From 6010053567b2aa9bef5ed6ba1a3cb66611fd4b5b Mon Sep 17 00:00:00 2001 From: Matt Carroll Date: Tue, 11 Feb 2020 16:52:09 -0800 Subject: [PATCH 1/8] Exposes FlutterView, FlutterSurfaceView, and FlutterTextureView to FlutterActivity and FlutterFragment. (#41984, #47557) --- shell/platform/android/BUILD.gn | 2 + .../embedding/android/FlutterActivity.java | 31 ++- .../FlutterActivityAndFragmentDelegate.java | 78 ++++++- .../embedding/android/FlutterFragment.java | 110 +++++----- .../android/FlutterFragmentActivity.java | 12 +- .../embedding/android/FlutterView.java | 195 ++++++++++++------ .../flutter/embedding/android/RenderMode.java | 21 ++ .../embedding/android/TransparencyMode.java | 36 ++++ ...lutterActivityAndFragmentDelegateTest.java | 4 +- .../android/FlutterActivityTest.java | 8 +- .../android/FlutterAndroidComponentTest.java | 17 +- .../android/FlutterFragmentTest.java | 12 +- .../flutter/external/FlutterLaunchTests.java | 6 +- 13 files changed, 372 insertions(+), 160 deletions(-) create mode 100644 shell/platform/android/io/flutter/embedding/android/RenderMode.java create mode 100644 shell/platform/android/io/flutter/embedding/android/TransparencyMode.java diff --git a/shell/platform/android/BUILD.gn b/shell/platform/android/BUILD.gn index 92130115f13e0..0564b4f0cdab3 100644 --- a/shell/platform/android/BUILD.gn +++ b/shell/platform/android/BUILD.gn @@ -138,8 +138,10 @@ android_java_sources = [ "io/flutter/embedding/android/FlutterSurfaceView.java", "io/flutter/embedding/android/FlutterTextureView.java", "io/flutter/embedding/android/FlutterView.java", + "io/flutter/embedding/android/RenderMode.java", "io/flutter/embedding/android/SplashScreen.java", "io/flutter/embedding/android/SplashScreenProvider.java", + "io/flutter/embedding/android/TransparencyMode.java", "io/flutter/embedding/engine/FlutterEngine.java", "io/flutter/embedding/engine/FlutterEngineCache.java", "io/flutter/embedding/engine/FlutterEnginePluginRegistry.java", diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java b/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java index 31105bea8139f..812ce4eac2c7c 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java @@ -782,28 +782,28 @@ private boolean isDebuggable() { /** * {@link FlutterActivityAndFragmentDelegate.Host} method that is used by {@link - * FlutterActivityAndFragmentDelegate} to obtain the desired {@link FlutterView.RenderMode} that + * FlutterActivityAndFragmentDelegate} to obtain the desired {@link RenderMode} that * should be used when instantiating a {@link FlutterView}. */ @NonNull @Override - public FlutterView.RenderMode getRenderMode() { + public RenderMode getRenderMode() { return getBackgroundMode() == BackgroundMode.opaque - ? FlutterView.RenderMode.surface - : FlutterView.RenderMode.texture; + ? RenderMode.surface + : RenderMode.texture; } /** * {@link FlutterActivityAndFragmentDelegate.Host} method that is used by {@link - * FlutterActivityAndFragmentDelegate} to obtain the desired {@link FlutterView.TransparencyMode} + * FlutterActivityAndFragmentDelegate} to obtain the desired {@link TransparencyMode} * that should be used when instantiating a {@link FlutterView}. */ @NonNull @Override - public FlutterView.TransparencyMode getTransparencyMode() { + public TransparencyMode getTransparencyMode() { return getBackgroundMode() == BackgroundMode.opaque - ? FlutterView.TransparencyMode.opaque - : FlutterView.TransparencyMode.transparent; + ? TransparencyMode.opaque + : TransparencyMode.transparent; } /** @@ -917,6 +917,21 @@ public boolean shouldAttachEngineToActivity() { return true; } + @Override + public void onFlutterSurfaceViewCreated(@NonNull FlutterSurfaceView flutterSurfaceView) { + // Hook for subclasses. + } + + @Override + public void onFlutterTextureViewCreated(@NonNull FlutterTextureView flutterTextureView) { + // Hook for subclasses. + } + + @Override + public void onFlutterViewCreated(@NonNull FlutterView flutterView) { + // Hook for subclasses. + } + @Override public void onFlutterUiDisplayed() { // Notifies Android that we're fully drawn so that performance metrics can be collected by diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterActivityAndFragmentDelegate.java b/shell/platform/android/io/flutter/embedding/android/FlutterActivityAndFragmentDelegate.java index 24689fc40ace1..67eb2dab3b1ba 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterActivityAndFragmentDelegate.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterActivityAndFragmentDelegate.java @@ -251,10 +251,33 @@ 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()); + + if (host.getRenderMode() == RenderMode.surface) { + FlutterSurfaceView flutterSurfaceView = new FlutterSurfaceView(host.getActivity(), host.getTransparencyMode() == TransparencyMode.transparent); + + // Allow our host to customize FlutterSurfaceView, if desired. + host.onFlutterSurfaceViewCreated(flutterSurfaceView); + + // Create the FlutterView that owns the FlutterSurfaceView. + flutterView = + new FlutterView(host.getActivity(), flutterSurfaceView); + } else { + FlutterTextureView flutterTextureView = new FlutterTextureView(host.getActivity()); + + // Allow our host to customize FlutterSurfaceView, if desired. + host.onFlutterTextureViewCreated(flutterTextureView); + + // Create the FlutterView that owns the FlutterTextureView. + flutterView = + new FlutterView(host.getActivity(), flutterTextureView); + } + + // Add listener to be notified when Flutter renders its first frame. flutterView.addOnFirstFrameRenderedListener(flutterUiDisplayListener); + // Allow our host to customize FlutterView, if desired. + host.onFlutterViewCreated(flutterView); + flutterSplashView = new FlutterSplashView(host.getContext()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { flutterSplashView.setId(View.generateViewId()); @@ -702,18 +725,18 @@ private void ensureAlive() { String getInitialRoute(); /** - * Returns the {@link FlutterView.RenderMode} used by the {@link FlutterView} that displays the + * Returns the {@link RenderMode} used by the {@link FlutterView} that displays the * {@link FlutterEngine}'s content. */ @NonNull - FlutterView.RenderMode getRenderMode(); + RenderMode getRenderMode(); /** - * Returns the {@link FlutterView.TransparencyMode} used by the {@link FlutterView} that + * Returns the {@link TransparencyMode} used by the {@link FlutterView} that * displays the {@link FlutterEngine}'s content. */ @NonNull - FlutterView.TransparencyMode getTransparencyMode(); + TransparencyMode getTransparencyMode(); @Nullable SplashScreen provideSplashScreen(); @@ -749,6 +772,49 @@ PlatformPlugin providePlatformPlugin( */ boolean shouldAttachEngineToActivity(); + /** + * Invoked by this delegate when the {@link FlutterSurfaceView} that renders the Flutter UI is + * initially instantiated. + * + *

This method is only invoked if the {@link + * io.flutter.embedding.android.FlutterView.RenderMode} is set to {@link + * io.flutter.embedding.android.FlutterView.RenderMode#surface}. Otherwise, {@link + * #onFlutterTextureViewCreated(FlutterTextureView)} is invoked. + * + *

This method is invoked before the given {@link FlutterSurfaceView} is attached to the + * {@code View} hierarchy. Implementers should not attempt to climb the {@code View} hierarchy + * or make assumptions about relationships with other {@code View}s. + */ + void onFlutterSurfaceViewCreated(@NonNull FlutterSurfaceView flutterSurfaceView); + + /** + * Invoked by this delegate when the {@link FlutterTextureView} that renders the Flutter UI is + * initially instantiated. + * + *

This method is only invoked if the {@link + * io.flutter.embedding.android.FlutterView.RenderMode} is set to {@link + * io.flutter.embedding.android.FlutterView.RenderMode#texture}. Otherwise, {@link + * #onFlutterSurfaceViewCreated(FlutterSurfaceView)} is invoked. + * + *

This method is invoked before the given {@link FlutterTextureView} is attached to the + * {@code View} hierarchy. Implementers should not attempt to climb the {@code View} hierarchy + * or make assumptions about relationships with other {@code View}s. + */ + void onFlutterTextureViewCreated(@NonNull FlutterTextureView flutterTextureView); + + /** + * Invoked by this delegate when the {@link FlutterView} that renders the Flutter UI is + * initially instantiated. + * + *

{@link FlutterView} internally owns the {@link FlutterSurfaceView} or {@link + * FlutterTextureView} that renders a Flutter UI. + * + *

This method is invoked before the given {@link FlutterView} is attached to the {@code + * View} hierarchy. Implementers should not attempt to climb the {@code View} hierarchy or make + * assumptions about relationships with other {@code View}s. + */ + void onFlutterViewCreated(@NonNull FlutterView flutterView); + /** Invoked by this delegate when its {@link FlutterView} starts painting pixels. */ void onFlutterUiDisplayed(); diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java b/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java index 70bf2b5b76a17..622dac8111081 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java @@ -91,14 +91,10 @@ public class FlutterFragment extends Fragment implements FlutterActivityAndFragm protected static final String ARG_APP_BUNDLE_PATH = "app_bundle_path"; /** Flutter shell arguments. */ protected static final String ARG_FLUTTER_INITIALIZATION_ARGS = "initialization_args"; - /** - * {@link FlutterView.RenderMode} to be used for the {@link FlutterView} in this {@code - * FlutterFragment} - */ + /** {@link RenderMode} to be used for the {@link FlutterView} in this {@code FlutterFragment} */ protected static final String ARG_FLUTTERVIEW_RENDER_MODE = "flutterview_render_mode"; /** - * {@link FlutterView.TransparencyMode} to be used for the {@link FlutterView} in this {@code - * FlutterFragment} + * {@link TransparencyMode} to be used for the {@link FlutterView} in this {@code FlutterFragment} */ protected static final String ARG_FLUTTERVIEW_TRANSPARENCY_MODE = "flutterview_transparency_mode"; /** See {@link #shouldAttachEngineToActivity()}. */ @@ -185,9 +181,8 @@ public static class NewEngineFragmentBuilder { private String initialRoute = "/"; private String appBundlePath = null; private FlutterShellArgs shellArgs = null; - private FlutterView.RenderMode renderMode = FlutterView.RenderMode.surface; - private FlutterView.TransparencyMode transparencyMode = - FlutterView.TransparencyMode.transparent; + private RenderMode renderMode = RenderMode.surface; + private TransparencyMode transparencyMode = TransparencyMode.transparent; private boolean shouldAttachEngineToActivity = true; /** @@ -241,27 +236,25 @@ public NewEngineFragmentBuilder flutterShellArgs(@NonNull FlutterShellArgs shell } /** - * Render Flutter either as a {@link FlutterView.RenderMode#surface} or a {@link - * FlutterView.RenderMode#texture}. You should use {@code surface} unless you have a specific - * reason to use {@code texture}. {@code texture} comes with a significant performance impact, - * but {@code texture} can be displayed beneath other Android {@code View}s and animated, - * whereas {@code surface} cannot. + * Render Flutter either as a {@link RenderMode#surface} or a {@link RenderMode#texture}. You + * should use {@code surface} unless you have a specific reason to use {@code texture}. {@code + * texture} comes with a significant performance impact, but {@code texture} can be displayed + * beneath other Android {@code View}s and animated, whereas {@code surface} cannot. */ @NonNull - public NewEngineFragmentBuilder renderMode(@NonNull FlutterView.RenderMode renderMode) { + public NewEngineFragmentBuilder renderMode(@NonNull RenderMode renderMode) { this.renderMode = renderMode; return this; } /** - * Support a {@link FlutterView.TransparencyMode#transparent} background within {@link - * FlutterView}, or force an {@link FlutterView.TransparencyMode#opaque} background. + * Support a {@link TransparencyMode#transparent} background within {@link FlutterView}, or + * force an {@link TransparencyMode#opaque} background. * - *

See {@link FlutterView.TransparencyMode} for implications of this selection. + *

See {@link TransparencyMode} for implications of this selection. */ @NonNull - public NewEngineFragmentBuilder transparencyMode( - @NonNull FlutterView.TransparencyMode transparencyMode) { + public NewEngineFragmentBuilder transparencyMode(@NonNull TransparencyMode transparencyMode) { this.transparencyMode = transparencyMode; return this; } @@ -326,12 +319,10 @@ protected Bundle createArgs() { } args.putString( ARG_FLUTTERVIEW_RENDER_MODE, - renderMode != null ? renderMode.name() : FlutterView.RenderMode.surface.name()); + renderMode != null ? renderMode.name() : RenderMode.surface.name()); args.putString( ARG_FLUTTERVIEW_TRANSPARENCY_MODE, - transparencyMode != null - ? transparencyMode.name() - : FlutterView.TransparencyMode.transparent.name()); + transparencyMode != null ? transparencyMode.name() : TransparencyMode.transparent.name()); args.putBoolean(ARG_SHOULD_ATTACH_ENGINE_TO_ACTIVITY, shouldAttachEngineToActivity); args.putBoolean(ARG_DESTROY_ENGINE_WITH_FRAGMENT, true); return args; @@ -412,9 +403,8 @@ public static class CachedEngineFragmentBuilder { private final Class fragmentClass; private final String engineId; private boolean destroyEngineWithFragment = false; - private FlutterView.RenderMode renderMode = FlutterView.RenderMode.surface; - private FlutterView.TransparencyMode transparencyMode = - FlutterView.TransparencyMode.transparent; + private RenderMode renderMode = RenderMode.surface; + private TransparencyMode transparencyMode = TransparencyMode.transparent; private boolean shouldAttachEngineToActivity = true; private CachedEngineFragmentBuilder(@NonNull String engineId) { @@ -440,27 +430,26 @@ public CachedEngineFragmentBuilder destroyEngineWithFragment( } /** - * Render Flutter either as a {@link FlutterView.RenderMode#surface} or a {@link - * FlutterView.RenderMode#texture}. You should use {@code surface} unless you have a specific - * reason to use {@code texture}. {@code texture} comes with a significant performance impact, - * but {@code texture} can be displayed beneath other Android {@code View}s and animated, - * whereas {@code surface} cannot. + * Render Flutter either as a {@link RenderMode#surface} or a {@link RenderMode#texture}. You + * should use {@code surface} unless you have a specific reason to use {@code texture}. {@code + * texture} comes with a significant performance impact, but {@code texture} can be displayed + * beneath other Android {@code View}s and animated, whereas {@code surface} cannot. */ @NonNull - public CachedEngineFragmentBuilder renderMode(@NonNull FlutterView.RenderMode renderMode) { + public CachedEngineFragmentBuilder renderMode(@NonNull RenderMode renderMode) { this.renderMode = renderMode; return this; } /** - * Support a {@link FlutterView.TransparencyMode#transparent} background within {@link - * FlutterView}, or force an {@link FlutterView.TransparencyMode#opaque} background. + * Support a {@link TransparencyMode#transparent} background within {@link FlutterView}, or + * force an {@link TransparencyMode#opaque} background. * - *

See {@link FlutterView.TransparencyMode} for implications of this selection. + *

See {@link TransparencyMode} for implications of this selection. */ @NonNull public CachedEngineFragmentBuilder transparencyMode( - @NonNull FlutterView.TransparencyMode transparencyMode) { + @NonNull TransparencyMode transparencyMode) { this.transparencyMode = transparencyMode; return this; } @@ -519,12 +508,10 @@ protected Bundle createArgs() { args.putBoolean(ARG_DESTROY_ENGINE_WITH_FRAGMENT, destroyEngineWithFragment); args.putString( ARG_FLUTTERVIEW_RENDER_MODE, - renderMode != null ? renderMode.name() : FlutterView.RenderMode.surface.name()); + renderMode != null ? renderMode.name() : RenderMode.surface.name()); args.putString( ARG_FLUTTERVIEW_TRANSPARENCY_MODE, - transparencyMode != null - ? transparencyMode.name() - : FlutterView.TransparencyMode.transparent.name()); + transparencyMode != null ? transparencyMode.name() : TransparencyMode.transparent.name()); args.putBoolean(ARG_SHOULD_ATTACH_ENGINE_TO_ACTIVITY, shouldAttachEngineToActivity); return args; } @@ -832,38 +819,36 @@ public String getInitialRoute() { } /** - * Returns the desired {@link FlutterView.RenderMode} for the {@link FlutterView} displayed in - * this {@code FlutterFragment}. + * Returns the desired {@link RenderMode} for the {@link FlutterView} displayed in this {@code + * FlutterFragment}. * - *

Defaults to {@link FlutterView.RenderMode#surface}. + *

Defaults to {@link RenderMode#surface}. * *

Used by this {@code FlutterFragment}'s {@link FlutterActivityAndFragmentDelegate.Host} */ @Override @NonNull - public FlutterView.RenderMode getRenderMode() { + public RenderMode getRenderMode() { String renderModeName = - getArguments() - .getString(ARG_FLUTTERVIEW_RENDER_MODE, FlutterView.RenderMode.surface.name()); - return FlutterView.RenderMode.valueOf(renderModeName); + getArguments().getString(ARG_FLUTTERVIEW_RENDER_MODE, RenderMode.surface.name()); + return RenderMode.valueOf(renderModeName); } /** - * Returns the desired {@link FlutterView.TransparencyMode} for the {@link FlutterView} displayed - * in this {@code FlutterFragment}. + * Returns the desired {@link TransparencyMode} for the {@link FlutterView} displayed in this + * {@code FlutterFragment}. * - *

Defaults to {@link FlutterView.TransparencyMode#transparent}. + *

Defaults to {@link TransparencyMode#transparent}. * *

Used by this {@code FlutterFragment}'s {@link FlutterActivityAndFragmentDelegate.Host} */ @Override @NonNull - public FlutterView.TransparencyMode getTransparencyMode() { + public TransparencyMode getTransparencyMode() { String transparencyModeName = getArguments() - .getString( - ARG_FLUTTERVIEW_TRANSPARENCY_MODE, FlutterView.TransparencyMode.transparent.name()); - return FlutterView.TransparencyMode.valueOf(transparencyModeName); + .getString(ARG_FLUTTERVIEW_TRANSPARENCY_MODE, TransparencyMode.transparent.name()); + return TransparencyMode.valueOf(transparencyModeName); } @Override @@ -983,6 +968,21 @@ public boolean shouldAttachEngineToActivity() { return getArguments().getBoolean(ARG_SHOULD_ATTACH_ENGINE_TO_ACTIVITY); } + @Override + public void onFlutterSurfaceViewCreated(@NonNull FlutterSurfaceView flutterSurfaceView) { + // Hook for subclasses. + } + + @Override + public void onFlutterTextureViewCreated(@NonNull FlutterTextureView flutterTextureView) { + // Hook for subclasses. + } + + @Override + public void onFlutterViewCreated(@NonNull FlutterView flutterView) { + // Hook for subclasses. + } + /** * Invoked after the {@link FlutterView} within this {@code FlutterFragment} starts rendering * pixels to the screen. diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterFragmentActivity.java b/shell/platform/android/io/flutter/embedding/android/FlutterFragmentActivity.java index f01f99891073b..dcdda40f04b53 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterFragmentActivity.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterFragmentActivity.java @@ -399,14 +399,14 @@ private void ensureFlutterFragmentCreated() { @NonNull protected FlutterFragment createFlutterFragment() { BackgroundMode backgroundMode = getBackgroundMode(); - FlutterView.RenderMode renderMode = + RenderMode renderMode = backgroundMode == BackgroundMode.opaque - ? FlutterView.RenderMode.surface - : FlutterView.RenderMode.texture; - FlutterView.TransparencyMode transparencyMode = + ? RenderMode.surface + : RenderMode.texture; + TransparencyMode transparencyMode = backgroundMode == BackgroundMode.opaque - ? FlutterView.TransparencyMode.opaque - : FlutterView.TransparencyMode.transparent; + ? TransparencyMode.opaque + : TransparencyMode.transparent; if (getCachedEngineId() != null) { Log.v( diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterView.java b/shell/platform/android/io/flutter/embedding/android/FlutterView.java index df382ce254b96..0e1ceb602c4e4 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterView.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterView.java @@ -47,21 +47,23 @@ * *

A {@code FlutterView}'s UI is painted by a corresponding {@link FlutterEngine}. * - *

A {@code FlutterView} can operate in 2 different {@link RenderMode}s: + *

A {@code FlutterView} can operate in 2 different {@link + * io.flutter.embedding.android.RenderMode}s: * *

    - *
  1. {@link RenderMode#surface}, which paints a Flutter UI to a {@link - * android.view.SurfaceView}. This mode has the best performance, but a {@code FlutterView} in - * this mode cannot be positioned between 2 other Android {@code View}s in the z-index, nor - * can it be animated/transformed. Unless the special capabilities of a {@link + *
  2. {@link io.flutter.embedding.android.RenderMode#surface}, which paints a Flutter UI to a + * {@link android.view.SurfaceView}. This mode has the best performance, but a {@code + * FlutterView} in this mode cannot be positioned between 2 other Android {@code View}s in the + * z-index, nor can it be animated/transformed. Unless the special capabilities of a {@link * android.graphics.SurfaceTexture} are required, developers should strongly prefer this * render mode. - *
  3. {@link RenderMode#texture}, which paints a Flutter UI to a {@link - * android.graphics.SurfaceTexture}. This mode is not as performant as {@link - * RenderMode#surface}, but a {@code FlutterView} in this mode can be animated and - * transformed, as well as positioned in the z-index between 2+ other Android {@code Views}. - * Unless the special capabilities of a {@link android.graphics.SurfaceTexture} are required, - * developers should strongly prefer the {@link RenderMode#surface} render mode. + *
  4. {@link io.flutter.embedding.android.RenderMode#texture}, which paints a Flutter UI to a + * {@link android.graphics.SurfaceTexture}. This mode is not as performant as {@link + * io.flutter.embedding.android.RenderMode#surface}, but a {@code FlutterView} in this mode + * can be animated and transformed, as well as positioned in the z-index between 2+ other + * Android {@code Views}. Unless the special capabilities of a {@link + * android.graphics.SurfaceTexture} are required, developers should strongly prefer the {@link + * io.flutter.embedding.android.RenderMode#surface} render mode. *
* * See https://source.android.com/devices/graphics/arch-tv#surface_or_texture for more @@ -70,11 +72,9 @@ public class FlutterView extends FrameLayout { private static final String TAG = "FlutterView"; - // Behavior configuration of this FlutterView. - @NonNull private RenderMode renderMode; - @Nullable private TransparencyMode transparencyMode; - // Internal view hierarchy references. + @Nullable private FlutterSurfaceView flutterSurfaceView; + @Nullable private FlutterTextureView flutterTextureView; @Nullable private RenderSurface renderSurface; private final Set flutterUiDisplayListeners = new HashSet<>(); private boolean isFlutterUiDisplayed; @@ -136,75 +136,135 @@ public void onFlutterUiNoLongerDisplayed() { *

* *

* * {@code FlutterView} requires an {@code Activity} instead of a generic {@code Context} to be * compatible with {@link PlatformViewsController}. */ public FlutterView(@NonNull Context context) { - this(context, null, null, null); + this(context, null, new FlutterSurfaceView(context)); + } + + /** + * Deprecated - use {@link #FlutterView(Context, FlutterSurfaceView)} or {@link + * #FlutterView(Context, FlutterTextureView)} instead. + */ + @Deprecated + public FlutterView(@NonNull Context context, @NonNull RenderMode renderMode) { + super(context, null); + + if (renderMode == RenderMode.surface) { + flutterSurfaceView = new FlutterSurfaceView(context); + renderSurface = flutterSurfaceView; + } else { + flutterTextureView = new FlutterTextureView(context); + renderSurface = flutterTextureView; + } + + init(); } /** - * Constructs a {@code FlutterView} programmatically, without any XML attributes, and allows - * selection of a {@link #renderMode}. + * Deprecated - use {@link #FlutterView(Context, FlutterSurfaceView)} or {@link + * #FlutterView(Context, FlutterTextureView)} instead, and configure the incoming {@code + * FlutterSurfaceView} or {@code FlutterTextureView} for transparency as desired. * - *

{@link #transparencyMode} defaults to {@link TransparencyMode#opaque}. + *

Constructs a {@code FlutterView} programmatically, without any XML attributes, uses a {@link + * FlutterSurfaceView} to render the Flutter UI, and allows selection of a {@code + * transparencyMode}. * *

{@code FlutterView} requires an {@code Activity} instead of a generic {@code Context} to be * compatible with {@link PlatformViewsController}. */ - public FlutterView(@NonNull Context context, @NonNull RenderMode renderMode) { - this(context, null, renderMode, null); + @Deprecated + public FlutterView(@NonNull Context context, @NonNull TransparencyMode transparencyMode) { + this( + context, + null, + new FlutterSurfaceView(context, transparencyMode == TransparencyMode.transparent)); } /** - * Constructs a {@code FlutterView} programmatically, without any XML attributes, assumes the use - * of {@link RenderMode#surface}, and allows selection of a {@link #transparencyMode}. + * Constructs a {@code FlutterView} programmatically, without any XML attributes, uses the given + * {@link FlutterSurfaceView} to render the Flutter UI, and allows selection of a {@code + * transparencyMode}. * *

{@code FlutterView} requires an {@code Activity} instead of a generic {@code Context} to be * compatible with {@link PlatformViewsController}. */ - public FlutterView(@NonNull Context context, @NonNull TransparencyMode transparencyMode) { - this(context, null, RenderMode.surface, transparencyMode); + public FlutterView(@NonNull Context context, @NonNull FlutterSurfaceView flutterSurfaceView) { + this(context, null, flutterSurfaceView); } /** - * Constructs a {@code FlutterView} programmatically, without any XML attributes, and allows a - * selection of {@link #renderMode} and {@link #transparencyMode}. + * Constructs a {@code FlutterView} programmatically, without any XML attributes, uses the given + * {@link FlutterTextureView} to render the Flutter UI, and allows selection of a {@code + * transparencyMode}. * *

{@code FlutterView} requires an {@code Activity} instead of a generic {@code Context} to be * compatible with {@link PlatformViewsController}. */ - public FlutterView( - @NonNull Context context, - @NonNull RenderMode renderMode, - @NonNull TransparencyMode transparencyMode) { - this(context, null, renderMode, transparencyMode); + public FlutterView(@NonNull Context context, @NonNull FlutterTextureView flutterTextureView) { + this(context, null, flutterTextureView); } /** - * Constructs a {@code FlutterSurfaceView} in an XML-inflation-compliant manner. + * Constructs a {@code FlutterView} in an XML-inflation-compliant manner. * *

{@code FlutterView} requires an {@code Activity} instead of a generic {@code Context} to be * compatible with {@link PlatformViewsController}. */ // TODO(mattcarroll): expose renderMode in XML when build system supports R.attr public FlutterView(@NonNull Context context, @Nullable AttributeSet attrs) { - this(context, attrs, null, null); + this(context, attrs, new FlutterSurfaceView(context)); + } + + /** + * Deprecated - use {@link #FlutterView(Context, FlutterSurfaceView)} or {@link + * #FlutterView(Context, FlutterTextureView)} instead, and configure the incoming {@code + * FlutterSurfaceView} or {@code FlutterTextureView} for transparency as desired. + */ + @Deprecated + public FlutterView( + @NonNull Context context, + @NonNull RenderMode renderMode, + @NonNull TransparencyMode transparencyMode) { + super(context, null); + + if (renderMode == RenderMode.surface) { + flutterSurfaceView = + new FlutterSurfaceView(context, transparencyMode == TransparencyMode.transparent); + renderSurface = flutterSurfaceView; + } else { + flutterTextureView = new FlutterTextureView(context); + renderSurface = flutterTextureView; + } + + init(); + } + + private FlutterView( + @NonNull Context context, + @Nullable AttributeSet attrs, + @NonNull FlutterSurfaceView flutterSurfaceView) { + super(context, attrs); + + this.flutterSurfaceView = flutterSurfaceView; + this.renderSurface = flutterSurfaceView; + + init(); } private FlutterView( @NonNull Context context, @Nullable AttributeSet attrs, - @Nullable RenderMode renderMode, - @Nullable TransparencyMode transparencyMode) { + @NonNull FlutterTextureView flutterTextureView) { super(context, attrs); - this.renderMode = renderMode == null ? RenderMode.surface : renderMode; - this.transparencyMode = transparencyMode != null ? transparencyMode : TransparencyMode.opaque; + this.flutterTextureView = flutterTextureView; + this.renderSurface = flutterSurfaceView; init(); } @@ -212,20 +272,12 @@ private FlutterView( private void init() { Log.v(TAG, "Initializing FlutterView"); - switch (renderMode) { - case surface: - Log.v(TAG, "Internally using a FlutterSurfaceView."); - FlutterSurfaceView flutterSurfaceView = - new FlutterSurfaceView(getContext(), transparencyMode == TransparencyMode.transparent); - renderSurface = flutterSurfaceView; - addView(flutterSurfaceView); - break; - case texture: - Log.v(TAG, "Internally using a FlutterTextureView."); - FlutterTextureView flutterTextureView = new FlutterTextureView(getContext()); - renderSurface = flutterTextureView; - addView(flutterTextureView); - break; + if (flutterSurfaceView != null) { + Log.v(TAG, "Internally using a FlutterSurfaceView."); + addView(flutterSurfaceView); + } else { + Log.v(TAG, "Internally using a FlutterTextureView."); + addView(flutterTextureView); } // FlutterView needs to be focusable so that the InputMethodManager can interact with it. @@ -846,7 +898,12 @@ private void sendViewportMetricsToFlutter() { flutterEngine.getRenderer().setViewportMetrics(viewportMetrics); } - /** Render modes for a {@link FlutterView}. */ + /** + * Render modes for a {@link FlutterView}. + * + *

Deprecated - please use {@link io.flutter.embedding.android.RenderMode} instead. + */ + @Deprecated() public enum RenderMode { /** * {@code RenderMode}, which paints a Flutter UI to a {@link android.view.SurfaceView}. This @@ -870,6 +927,8 @@ public enum RenderMode { /** * Transparency mode for a {@code FlutterView}. * + *

Deprecated - please use {@link io.flutter.embedding.android.TransparencyMode} instead. + * *

{@code TransparencyMode} impacts the visual behavior and performance of a {@link * FlutterSurfaceView}, which is displayed when a {@code FlutterView} uses {@link * RenderMode#surface}. @@ -878,27 +937,29 @@ public enum RenderMode { * a {@code FlutterView} uses {@link RenderMode#texture}, because a {@link FlutterTextureView} * automatically comes with transparency. */ + @Deprecated public enum TransparencyMode { /** * Renders a {@code FlutterView} without any transparency. This affects {@code FlutterView}s in - * {@link RenderMode#surface} by introducing a base color of black, and places the {@link - * FlutterSurfaceView}'s {@code Window} behind all other content. + * {@link io.flutter.embedding.android.RenderMode#surface} by introducing a base color of black, + * and places the {@link FlutterSurfaceView}'s {@code Window} behind all other content. * - *

In {@link RenderMode#surface}, this mode is the most performant and is a good choice for - * fullscreen Flutter UIs that will not undergo {@code Fragment} transactions. If this mode is - * used within a {@code Fragment}, and that {@code Fragment} is replaced by another one, a brief - * black flicker may be visible during the switch. + *

In {@link io.flutter.embedding.android.RenderMode#surface}, this mode is the most + * performant and is a good choice for fullscreen Flutter UIs that will not undergo {@code + * Fragment} transactions. If this mode is used within a {@code Fragment}, and that {@code + * Fragment} is replaced by another one, a brief black flicker may be visible during the switch. */ opaque, /** * Renders a {@code FlutterView} with transparency. This affects {@code FlutterView}s in {@link - * RenderMode#surface} by allowing background transparency, and places the {@link - * FlutterSurfaceView}'s {@code Window} on top of all other content. + * io.flutter.embedding.android.RenderMode#surface} by allowing background transparency, and + * places the {@link FlutterSurfaceView}'s {@code Window} on top of all other content. * - *

In {@link RenderMode#surface}, this mode is less performant than {@link #opaque}, but this - * mode avoids the black flicker problem that {@link #opaque} has when going through {@code - * Fragment} transactions. Consider using this {@code TransparencyMode} if you intend to switch - * {@code Fragment}s at runtime that contain a Flutter UI. + *

In {@link io.flutter.embedding.android.RenderMode#surface}, this mode is less performant + * than {@link #opaque}, but this mode avoids the black flicker problem that {@link #opaque} has + * when going through {@code Fragment} transactions. Consider using this {@code + * TransparencyMode} if you intend to switch {@code Fragment}s at runtime that contain a Flutter + * UI. */ transparent } diff --git a/shell/platform/android/io/flutter/embedding/android/RenderMode.java b/shell/platform/android/io/flutter/embedding/android/RenderMode.java new file mode 100644 index 0000000000000..fb464863230a3 --- /dev/null +++ b/shell/platform/android/io/flutter/embedding/android/RenderMode.java @@ -0,0 +1,21 @@ +package io.flutter.embedding.android; + +/** Render modes for a Flutter UI. */ +public enum RenderMode { + /** + * {@code RenderMode}, which paints a Flutter UI to a {@link android.view.SurfaceView}. This mode + * has the best performance, but a Flutter UI in this mode cannot be positioned between 2 other + * Android {@code View}s in the z-index, nor can it be animated/transformed. Unless the special + * capabilities of a {@link android.graphics.SurfaceTexture} are required, developers should + * strongly prefer this render mode. + */ + surface, + /** + * {@code RenderMode}, which paints a Flutter UI to a {@link android.graphics.SurfaceTexture}. + * This mode is not as performant as {@link #surface}, but a Flutter UI in this mode can be + * animated and transformed, as well as positioned in the z-index between 2+ other Android {@code + * Views}. Unless the special capabilities of a {@link android.graphics.SurfaceTexture} are + * required, developers should strongly prefer the {@link #surface} render mode. + */ + texture +} diff --git a/shell/platform/android/io/flutter/embedding/android/TransparencyMode.java b/shell/platform/android/io/flutter/embedding/android/TransparencyMode.java new file mode 100644 index 0000000000000..a38d1d2019283 --- /dev/null +++ b/shell/platform/android/io/flutter/embedding/android/TransparencyMode.java @@ -0,0 +1,36 @@ +package io.flutter.embedding.android; + +/** + * Transparency mode for a Flutter UI. + * + *

{@code TransparencyMode} impacts the visual behavior and performance of a {@link + * FlutterSurfaceView}, which is displayed when a Flutter UI uses {@link RenderMode#surface}. + * + *

{@code TransparencyMode} does not impact {@link FlutterTextureView}, which is displayed when a + * Flutter UI uses {@link RenderMode#texture}, because a {@link FlutterTextureView} automatically + * comes with transparency. + */ +public enum TransparencyMode { + /** + * Renders a Flutter UI without any transparency. This affects Flutter UI's with {@link + * RenderMode#surface} by introducing a base color of black, and places the {@link + * FlutterSurfaceView}'s {@code Window} behind all other content. + * + *

In {@link RenderMode#surface}, this mode is the most performant and is a good choice for + * fullscreen Flutter UIs that will not undergo {@code Fragment} transactions. If this mode is + * used within a {@code Fragment}, and that {@code Fragment} is replaced by another one, a brief + * black flicker may be visible during the switch. + */ + opaque, + /** + * Renders a Flutter UI with transparency. This affects Flutter UI's in {@link RenderMode#surface} + * by allowing background transparency, and places the {@link FlutterSurfaceView}'s {@code Window} + * on top of all other content. + * + *

In {@link RenderMode#surface}, this mode is less performant than {@link #opaque}, but this + * mode avoids the black flicker problem that {@link #opaque} has when going through {@code + * Fragment} transactions. Consider using this {@code TransparencyMode} if you intend to switch + * {@code Fragment}s at runtime that contain a Flutter UI. + */ + transparent +} diff --git a/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityAndFragmentDelegateTest.java b/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityAndFragmentDelegateTest.java index d75298f353148..83ab0c38c06a8 100644 --- a/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityAndFragmentDelegateTest.java +++ b/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityAndFragmentDelegateTest.java @@ -58,8 +58,8 @@ public void setup() { when(mockHost.getDartEntrypointFunctionName()).thenReturn("main"); when(mockHost.getAppBundlePath()).thenReturn("/fake/path"); when(mockHost.getInitialRoute()).thenReturn("/"); - when(mockHost.getRenderMode()).thenReturn(FlutterView.RenderMode.surface); - when(mockHost.getTransparencyMode()).thenReturn(FlutterView.TransparencyMode.transparent); + when(mockHost.getRenderMode()).thenReturn(RenderMode.surface); + when(mockHost.getTransparencyMode()).thenReturn(TransparencyMode.transparent); when(mockHost.provideFlutterEngine(any(Context.class))).thenReturn(mockFlutterEngine); when(mockHost.shouldAttachEngineToActivity()).thenReturn(true); when(mockHost.shouldDestroyEngineWithHost()).thenReturn(true); diff --git a/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityTest.java b/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityTest.java index e85ad1346fa95..3f476ebc8b72e 100644 --- a/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityTest.java +++ b/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityTest.java @@ -57,8 +57,8 @@ public void itCreatesDefaultIntentWithExpectedDefaults() { assertNull(flutterActivity.getCachedEngineId()); assertTrue(flutterActivity.shouldDestroyEngineWithHost()); assertEquals(BackgroundMode.opaque, flutterActivity.getBackgroundMode()); - assertEquals(FlutterView.RenderMode.surface, flutterActivity.getRenderMode()); - assertEquals(FlutterView.TransparencyMode.opaque, flutterActivity.getTransparencyMode()); + assertEquals(RenderMode.surface, flutterActivity.getRenderMode()); + assertEquals(TransparencyMode.opaque, flutterActivity.getTransparencyMode()); } @Test @@ -108,8 +108,8 @@ public void itCreatesNewEngineIntentWithRequestedSettings() { assertNull(flutterActivity.getCachedEngineId()); assertTrue(flutterActivity.shouldDestroyEngineWithHost()); assertEquals(BackgroundMode.transparent, flutterActivity.getBackgroundMode()); - assertEquals(FlutterView.RenderMode.texture, flutterActivity.getRenderMode()); - assertEquals(FlutterView.TransparencyMode.transparent, flutterActivity.getTransparencyMode()); + assertEquals(RenderMode.texture, flutterActivity.getRenderMode()); + assertEquals(TransparencyMode.transparent, flutterActivity.getTransparencyMode()); } @Test diff --git a/shell/platform/android/test/io/flutter/embedding/android/FlutterAndroidComponentTest.java b/shell/platform/android/test/io/flutter/embedding/android/FlutterAndroidComponentTest.java index 10f0739cb997c..d0130788f85c7 100644 --- a/shell/platform/android/test/io/flutter/embedding/android/FlutterAndroidComponentTest.java +++ b/shell/platform/android/test/io/flutter/embedding/android/FlutterAndroidComponentTest.java @@ -232,14 +232,14 @@ public String getInitialRoute() { @NonNull @Override - public FlutterView.RenderMode getRenderMode() { - return FlutterView.RenderMode.surface; + public RenderMode getRenderMode() { + return RenderMode.surface; } @NonNull @Override - public FlutterView.TransparencyMode getTransparencyMode() { - return FlutterView.TransparencyMode.transparent; + public TransparencyMode getTransparencyMode() { + return TransparencyMode.transparent; } @Nullable @@ -272,6 +272,15 @@ public boolean shouldAttachEngineToActivity() { return true; } + @Override + public void onFlutterSurfaceViewCreated(@NonNull FlutterSurfaceView flutterSurfaceView) {} + + @Override + public void onFlutterTextureViewCreated(@NonNull FlutterTextureView flutterTextureView) {} + + @Override + public void onFlutterViewCreated(@NonNull FlutterView flutterView) {} + @Override public void onFlutterUiDisplayed() {} diff --git a/shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentTest.java b/shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentTest.java index a2257f57ede5c..6dea8ec6b946d 100644 --- a/shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentTest.java +++ b/shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentTest.java @@ -25,8 +25,8 @@ public void itCreatesDefaultFragmentWithExpectedDefaults() { assertTrue(fragment.shouldAttachEngineToActivity()); assertNull(fragment.getCachedEngineId()); assertTrue(fragment.shouldDestroyEngineWithHost()); - assertEquals(FlutterView.RenderMode.surface, fragment.getRenderMode()); - assertEquals(FlutterView.TransparencyMode.transparent, fragment.getTransparencyMode()); + assertEquals(RenderMode.surface, fragment.getRenderMode()); + assertEquals(TransparencyMode.transparent, fragment.getTransparencyMode()); } @Test @@ -36,8 +36,8 @@ public void itCreatesNewEngineFragmentWithRequestedSettings() { .dartEntrypoint("custom_entrypoint") .initialRoute("/custom/route") .shouldAttachEngineToActivity(false) - .renderMode(FlutterView.RenderMode.texture) - .transparencyMode(FlutterView.TransparencyMode.opaque) + .renderMode(RenderMode.texture) + .transparencyMode(TransparencyMode.opaque) .build(); fragment.setDelegate(new FlutterActivityAndFragmentDelegate(fragment)); @@ -47,8 +47,8 @@ public void itCreatesNewEngineFragmentWithRequestedSettings() { assertFalse(fragment.shouldAttachEngineToActivity()); assertNull(fragment.getCachedEngineId()); assertTrue(fragment.shouldDestroyEngineWithHost()); - assertEquals(FlutterView.RenderMode.texture, fragment.getRenderMode()); - assertEquals(FlutterView.TransparencyMode.opaque, fragment.getTransparencyMode()); + assertEquals(RenderMode.texture, fragment.getRenderMode()); + assertEquals(TransparencyMode.opaque, fragment.getTransparencyMode()); } @Test diff --git a/shell/platform/android/test/io/flutter/external/FlutterLaunchTests.java b/shell/platform/android/test/io/flutter/external/FlutterLaunchTests.java index 391a1a8c5deff..0591375170148 100644 --- a/shell/platform/android/test/io/flutter/external/FlutterLaunchTests.java +++ b/shell/platform/android/test/io/flutter/external/FlutterLaunchTests.java @@ -9,7 +9,9 @@ import io.flutter.embedding.android.FlutterActivity; import io.flutter.embedding.android.FlutterActivityLaunchConfigs.BackgroundMode; import io.flutter.embedding.android.FlutterView; +import io.flutter.embedding.android.RenderMode; import io.flutter.embedding.android.RobolectricFlutterActivity; +import io.flutter.embedding.android.TransparencyMode; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; @@ -32,7 +34,7 @@ public void launchFlutterActivity_with_defaultIntent_expect_defaultConfiguration assertTrue(flutterActivity.shouldDestroyEngineWithHost()); assertEquals( BackgroundMode.opaque, RobolectricFlutterActivity.getBackgroundMode(flutterActivity)); - assertEquals(FlutterView.RenderMode.surface, flutterActivity.getRenderMode()); - assertEquals(FlutterView.TransparencyMode.opaque, flutterActivity.getTransparencyMode()); + assertEquals(RenderMode.surface, flutterActivity.getRenderMode()); + assertEquals(TransparencyMode.opaque, flutterActivity.getTransparencyMode()); } } From 40f68bbf7fc20672abfae4fb0044f78f90073196 Mon Sep 17 00:00:00 2001 From: Matt Carroll Date: Wed, 12 Feb 2020 13:35:32 -0800 Subject: [PATCH 2/8] Removed the onFlutterViewCreated() callback to limit changes to only what is needed right now. --- .../embedding/android/FlutterActivity.java | 5 ----- .../FlutterActivityAndFragmentDelegate.java | 16 ---------------- .../embedding/android/FlutterFragment.java | 5 ----- 3 files changed, 26 deletions(-) diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java b/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java index 812ce4eac2c7c..cb1a1c17c726a 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java @@ -927,11 +927,6 @@ public void onFlutterTextureViewCreated(@NonNull FlutterTextureView flutterTextu // Hook for subclasses. } - @Override - public void onFlutterViewCreated(@NonNull FlutterView flutterView) { - // Hook for subclasses. - } - @Override public void onFlutterUiDisplayed() { // Notifies Android that we're fully drawn so that performance metrics can be collected by diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterActivityAndFragmentDelegate.java b/shell/platform/android/io/flutter/embedding/android/FlutterActivityAndFragmentDelegate.java index 67eb2dab3b1ba..3b701c4989e0a 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterActivityAndFragmentDelegate.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterActivityAndFragmentDelegate.java @@ -275,9 +275,6 @@ View onCreateView( // Add listener to be notified when Flutter renders its first frame. flutterView.addOnFirstFrameRenderedListener(flutterUiDisplayListener); - // Allow our host to customize FlutterView, if desired. - host.onFlutterViewCreated(flutterView); - flutterSplashView = new FlutterSplashView(host.getContext()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { flutterSplashView.setId(View.generateViewId()); @@ -802,19 +799,6 @@ PlatformPlugin providePlatformPlugin( */ void onFlutterTextureViewCreated(@NonNull FlutterTextureView flutterTextureView); - /** - * Invoked by this delegate when the {@link FlutterView} that renders the Flutter UI is - * initially instantiated. - * - *

{@link FlutterView} internally owns the {@link FlutterSurfaceView} or {@link - * FlutterTextureView} that renders a Flutter UI. - * - *

This method is invoked before the given {@link FlutterView} is attached to the {@code - * View} hierarchy. Implementers should not attempt to climb the {@code View} hierarchy or make - * assumptions about relationships with other {@code View}s. - */ - void onFlutterViewCreated(@NonNull FlutterView flutterView); - /** Invoked by this delegate when its {@link FlutterView} starts painting pixels. */ void onFlutterUiDisplayed(); diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java b/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java index 622dac8111081..3e90990829309 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java @@ -978,11 +978,6 @@ public void onFlutterTextureViewCreated(@NonNull FlutterTextureView flutterTextu // Hook for subclasses. } - @Override - public void onFlutterViewCreated(@NonNull FlutterView flutterView) { - // Hook for subclasses. - } - /** * Invoked after the {@link FlutterView} within this {@code FlutterFragment} starts rendering * pixels to the screen. From 661074161920487e3eea8308280f486e216e9f85 Mon Sep 17 00:00:00 2001 From: Matt Carroll Date: Wed, 12 Feb 2020 13:47:05 -0800 Subject: [PATCH 3/8] Added tests. --- ...lutterActivityAndFragmentDelegateTest.java | 33 +++++++++++++++++++ .../android/FlutterAndroidComponentTest.java | 3 -- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityAndFragmentDelegateTest.java b/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityAndFragmentDelegateTest.java index 83ab0c38c06a8..b534e56c83b18 100644 --- a/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityAndFragmentDelegateTest.java +++ b/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityAndFragmentDelegateTest.java @@ -5,6 +5,7 @@ import static org.junit.Assert.assertNull; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; +import static org.mockito.Matchers.notNull; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -16,6 +17,7 @@ import android.content.Context; import android.content.Intent; import android.support.annotation.NonNull; +import io.flutter.embedding.android.FlutterActivityAndFragmentDelegate.Host; import io.flutter.embedding.engine.FlutterEngine; import io.flutter.embedding.engine.FlutterEngineCache; import io.flutter.embedding.engine.FlutterShellArgs; @@ -200,6 +202,37 @@ public void itGivesHostAnOpportunityToConfigureFlutterEngine() { verify(mockHost, times(1)).configureFlutterEngine(mockFlutterEngine); } + @Test + public void itGivesHostAnOpportunityToConfigureFlutterSurfaceView() { + // ---- Test setup ---- + // Create the real object that we're testing. + FlutterActivityAndFragmentDelegate delegate = new FlutterActivityAndFragmentDelegate(mockHost); + + // --- Execute the behavior under test --- + delegate.onAttach(RuntimeEnvironment.application); + delegate.onCreateView(null, null, null); + + // Verify that the host was asked to configure a FlutterSurfaceView. + verify(mockHost, times(1)).onFlutterSurfaceViewCreated(notNull(FlutterSurfaceView.class)); + } + + @Test + public void itGivesHostAnOpportunityToConfigureFlutterTextureView() { + // ---- Test setup ---- + Host customMockHost = mock(Host.class); + when(customMockHost.getRenderMode()).thenReturn(RenderMode.texture); + + // Create the real object that we're testing. + FlutterActivityAndFragmentDelegate delegate = new FlutterActivityAndFragmentDelegate(customMockHost); + + // --- Execute the behavior under test --- + delegate.onAttach(RuntimeEnvironment.application); + delegate.onCreateView(null, null, null); + + // Verify that the host was asked to configure a FlutterTextureView. + verify(customMockHost, times(1)).onFlutterTextureViewCreated(notNull(FlutterTextureView.class)); + } + @Test public void itGivesHostAnOpportunityToCleanUpFlutterEngine() { // ---- Test setup ---- diff --git a/shell/platform/android/test/io/flutter/embedding/android/FlutterAndroidComponentTest.java b/shell/platform/android/test/io/flutter/embedding/android/FlutterAndroidComponentTest.java index d0130788f85c7..05072e01c2f8a 100644 --- a/shell/platform/android/test/io/flutter/embedding/android/FlutterAndroidComponentTest.java +++ b/shell/platform/android/test/io/flutter/embedding/android/FlutterAndroidComponentTest.java @@ -278,9 +278,6 @@ public void onFlutterSurfaceViewCreated(@NonNull FlutterSurfaceView flutterSurfa @Override public void onFlutterTextureViewCreated(@NonNull FlutterTextureView flutterTextureView) {} - @Override - public void onFlutterViewCreated(@NonNull FlutterView flutterView) {} - @Override public void onFlutterUiDisplayed() {} From 3e8efdfb518dc1d0e1f14d0d728cf81031dd795e Mon Sep 17 00:00:00 2001 From: Matt Carroll Date: Wed, 12 Feb 2020 13:48:52 -0800 Subject: [PATCH 4/8] Formatting fixes. --- .../FlutterActivityAndFragmentDelegate.java | 18 +++++++++--------- .../android/FlutterFragmentActivity.java | 4 +--- .../flutter/external/FlutterLaunchTests.java | 1 - 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterActivityAndFragmentDelegate.java b/shell/platform/android/io/flutter/embedding/android/FlutterActivityAndFragmentDelegate.java index 3b701c4989e0a..0ca628ba37866 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterActivityAndFragmentDelegate.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterActivityAndFragmentDelegate.java @@ -253,14 +253,15 @@ View onCreateView( ensureAlive(); if (host.getRenderMode() == RenderMode.surface) { - FlutterSurfaceView flutterSurfaceView = new FlutterSurfaceView(host.getActivity(), host.getTransparencyMode() == TransparencyMode.transparent); + FlutterSurfaceView flutterSurfaceView = + new FlutterSurfaceView( + host.getActivity(), host.getTransparencyMode() == TransparencyMode.transparent); // Allow our host to customize FlutterSurfaceView, if desired. host.onFlutterSurfaceViewCreated(flutterSurfaceView); // Create the FlutterView that owns the FlutterSurfaceView. - flutterView = - new FlutterView(host.getActivity(), flutterSurfaceView); + flutterView = new FlutterView(host.getActivity(), flutterSurfaceView); } else { FlutterTextureView flutterTextureView = new FlutterTextureView(host.getActivity()); @@ -268,8 +269,7 @@ View onCreateView( host.onFlutterTextureViewCreated(flutterTextureView); // Create the FlutterView that owns the FlutterTextureView. - flutterView = - new FlutterView(host.getActivity(), flutterTextureView); + flutterView = new FlutterView(host.getActivity(), flutterTextureView); } // Add listener to be notified when Flutter renders its first frame. @@ -722,15 +722,15 @@ private void ensureAlive() { String getInitialRoute(); /** - * Returns the {@link RenderMode} used by the {@link FlutterView} that displays the - * {@link FlutterEngine}'s content. + * Returns the {@link RenderMode} used by the {@link FlutterView} that displays the {@link + * FlutterEngine}'s content. */ @NonNull RenderMode getRenderMode(); /** - * Returns the {@link TransparencyMode} used by the {@link FlutterView} that - * displays the {@link FlutterEngine}'s content. + * Returns the {@link TransparencyMode} used by the {@link FlutterView} that displays the {@link + * FlutterEngine}'s content. */ @NonNull TransparencyMode getTransparencyMode(); diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterFragmentActivity.java b/shell/platform/android/io/flutter/embedding/android/FlutterFragmentActivity.java index dcdda40f04b53..5860d6f8c986d 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterFragmentActivity.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterFragmentActivity.java @@ -400,9 +400,7 @@ private void ensureFlutterFragmentCreated() { protected FlutterFragment createFlutterFragment() { BackgroundMode backgroundMode = getBackgroundMode(); RenderMode renderMode = - backgroundMode == BackgroundMode.opaque - ? RenderMode.surface - : RenderMode.texture; + backgroundMode == BackgroundMode.opaque ? RenderMode.surface : RenderMode.texture; TransparencyMode transparencyMode = backgroundMode == BackgroundMode.opaque ? TransparencyMode.opaque diff --git a/shell/platform/android/test/io/flutter/external/FlutterLaunchTests.java b/shell/platform/android/test/io/flutter/external/FlutterLaunchTests.java index 0591375170148..3154483d814d6 100644 --- a/shell/platform/android/test/io/flutter/external/FlutterLaunchTests.java +++ b/shell/platform/android/test/io/flutter/external/FlutterLaunchTests.java @@ -8,7 +8,6 @@ import android.content.Intent; import io.flutter.embedding.android.FlutterActivity; import io.flutter.embedding.android.FlutterActivityLaunchConfigs.BackgroundMode; -import io.flutter.embedding.android.FlutterView; import io.flutter.embedding.android.RenderMode; import io.flutter.embedding.android.RobolectricFlutterActivity; import io.flutter.embedding.android.TransparencyMode; From 70e59c0e51955e75839862dc3930343994ab6dec Mon Sep 17 00:00:00 2001 From: Matt Carroll Date: Wed, 12 Feb 2020 15:12:20 -0800 Subject: [PATCH 5/8] Javadoc format fix. --- .../io/flutter/embedding/android/FlutterFragment.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java b/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java index 3e90990829309..ff18172ae131a 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java @@ -68,9 +68,11 @@ *

The following illustrates how to pre-warm and cache a {@link FlutterEngine}: * *

{@code
- * // Create and pre-warm a FlutterEngine. FlutterEngine flutterEngine = new
- * FlutterEngine(context);
- * flutterEngine.getDartExecutor().executeDartEntrypoint(DartEntrypoint.createDefault());
+ * // Create and pre-warm a FlutterEngine.
+ * FlutterEngine flutterEngine = new FlutterEngine(context);
+ * flutterEngine
+ *   .getDartExecutor()
+ *   .executeDartEntrypoint(DartEntrypoint.createDefault());
  *
  * // Cache the pre-warmed FlutterEngine in the FlutterEngineCache.
  * FlutterEngineCache.getInstance().put("my_engine", flutterEngine);

From ccd1a6f6785da0a7d5716f9d3e2d081c32bb6937 Mon Sep 17 00:00:00 2001
From: Matt Carroll 
Date: Wed, 12 Feb 2020 15:25:29 -0800
Subject: [PATCH 6/8] Format fixes.

---
 .../flutter/embedding/android/FlutterActivity.java   | 12 +++++-------
 .../FlutterActivityAndFragmentDelegateTest.java      |  3 ++-
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java b/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java
index cb1a1c17c726a..fa74bc53fd7d5 100644
--- a/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java
+++ b/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java
@@ -782,21 +782,19 @@ private boolean isDebuggable() {
 
   /**
    * {@link FlutterActivityAndFragmentDelegate.Host} method that is used by {@link
-   * FlutterActivityAndFragmentDelegate} to obtain the desired {@link RenderMode} that
-   * should be used when instantiating a {@link FlutterView}.
+   * FlutterActivityAndFragmentDelegate} to obtain the desired {@link RenderMode} that should be
+   * used when instantiating a {@link FlutterView}.
    */
   @NonNull
   @Override
   public RenderMode getRenderMode() {
-    return getBackgroundMode() == BackgroundMode.opaque
-        ? RenderMode.surface
-        : RenderMode.texture;
+    return getBackgroundMode() == BackgroundMode.opaque ? RenderMode.surface : RenderMode.texture;
   }
 
   /**
    * {@link FlutterActivityAndFragmentDelegate.Host} method that is used by {@link
-   * FlutterActivityAndFragmentDelegate} to obtain the desired {@link TransparencyMode}
-   * that should be used when instantiating a {@link FlutterView}.
+   * FlutterActivityAndFragmentDelegate} to obtain the desired {@link TransparencyMode} that should
+   * be used when instantiating a {@link FlutterView}.
    */
   @NonNull
   @Override
diff --git a/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityAndFragmentDelegateTest.java b/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityAndFragmentDelegateTest.java
index b534e56c83b18..422673439b551 100644
--- a/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityAndFragmentDelegateTest.java
+++ b/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityAndFragmentDelegateTest.java
@@ -223,7 +223,8 @@ public void itGivesHostAnOpportunityToConfigureFlutterTextureView() {
     when(customMockHost.getRenderMode()).thenReturn(RenderMode.texture);
 
     // Create the real object that we're testing.
-    FlutterActivityAndFragmentDelegate delegate = new FlutterActivityAndFragmentDelegate(customMockHost);
+    FlutterActivityAndFragmentDelegate delegate =
+        new FlutterActivityAndFragmentDelegate(customMockHost);
 
     // --- Execute the behavior under test ---
     delegate.onAttach(RuntimeEnvironment.application);

From ab58661b9f66bc7f6aace4dac8f2ad01f18329ac Mon Sep 17 00:00:00 2001
From: Matt Carroll 
Date: Wed, 12 Feb 2020 16:03:50 -0800
Subject: [PATCH 7/8] Updated licenses.

---
 ci/licenses_golden/licenses_flutter | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter
index c02d6ef79e5e3..f8cba6e7c66a6 100644
--- a/ci/licenses_golden/licenses_flutter
+++ b/ci/licenses_golden/licenses_flutter
@@ -655,8 +655,10 @@ FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/android/Flutt
 FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/android/FlutterSurfaceView.java
 FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/android/FlutterTextureView.java
 FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/android/FlutterView.java
+FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/android/RenderMode.java
 FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/android/SplashScreen.java
 FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/android/SplashScreenProvider.java
+FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/android/TransparencyMode.java
 FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java
 FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/FlutterEngineCache.java
 FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/FlutterEnginePluginRegistry.java

From 8c1ed0e6ab5df4ce1eb6575ed081a29445fe9b9b Mon Sep 17 00:00:00 2001
From: Matt Carroll 
Date: Wed, 12 Feb 2020 16:04:37 -0800
Subject: [PATCH 8/8] Added copyright to new files.

---
 .../android/io/flutter/embedding/android/RenderMode.java      | 4 ++++
 .../io/flutter/embedding/android/TransparencyMode.java        | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/shell/platform/android/io/flutter/embedding/android/RenderMode.java b/shell/platform/android/io/flutter/embedding/android/RenderMode.java
index fb464863230a3..3c0907bb850a3 100644
--- a/shell/platform/android/io/flutter/embedding/android/RenderMode.java
+++ b/shell/platform/android/io/flutter/embedding/android/RenderMode.java
@@ -1,3 +1,7 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
 package io.flutter.embedding.android;
 
 /** Render modes for a Flutter UI. */
diff --git a/shell/platform/android/io/flutter/embedding/android/TransparencyMode.java b/shell/platform/android/io/flutter/embedding/android/TransparencyMode.java
index a38d1d2019283..97736c7161653 100644
--- a/shell/platform/android/io/flutter/embedding/android/TransparencyMode.java
+++ b/shell/platform/android/io/flutter/embedding/android/TransparencyMode.java
@@ -1,3 +1,7 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
 package io.flutter.embedding.android;
 
 /**