From df178fd936c019e0743444f9bb4eece89564c2d4 Mon Sep 17 00:00:00 2001 From: Matt Carroll Date: Mon, 19 Aug 2019 17:21:21 -0700 Subject: [PATCH] Remove dart entrypoint Intent parameter from FlutterActivity. (#38713) (#11239) --- .../embedding/android/FlutterActivity.java | 70 ++++++++----------- .../android/FlutterActivityTest.java | 2 - 2 files changed, 28 insertions(+), 44 deletions(-) diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java b/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java index d14c31780949b..aa7eb2dfe391e 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java @@ -39,20 +39,16 @@ *

* Dart entrypoint, initial route, and app bundle path *

- * The Dart entrypoint executed within this {@code Activity} is "main()" by default. The entrypoint - * may be specified explicitly by passing the name of the entrypoint method as a {@code String} in - * {@link #EXTRA_DART_ENTRYPOINT}, e.g., "myEntrypoint". + * The Dart entrypoint executed within this {@code Activity} is "main()" by default. To change the + * entrypoint that a {@code FlutterActivity} executes, subclass {@code FlutterActivity} and + * override {@link #getDartEntrypointFunctionName()}. *

* The Flutter route that is initially loaded within this {@code Activity} is "/". The initial * route may be specified explicitly by passing the name of the route as a {@code String} in * {@link #EXTRA_INITIAL_ROUTE}, e.g., "my/deep/link". *

- * The Dart entrypoint and initial route can each be controlled using a {@link NewEngineIntentBuilder} - * via the following methods: - *

+ * The initial route can each be controlled using a {@link NewEngineIntentBuilder} via + * {@link NewEngineIntentBuilder#initialRoute}. *

* The app bundle path, Dart entrypoint, and initial route can also be controlled in a subclass of * {@code FlutterActivity} by overriding their respective methods: @@ -62,12 +58,24 @@ *

  • {@link #getInitialRoute()}
  • * *

    + * The Dart entrypoint and app bundle path are not supported as {@code Intent} parameters due to + * security concerns. If such configurations were exposed via {@code Intent}, then a + * {@code FlutterActivity} that is {@code exported} from your Android app would allow other apps to + * invoke arbitrary Dart entrypoints in your app by specifying different Dart entrypoints for your + * {@code FlutterActivity}. Therefore, these configurations are not available via {@code Intent}. + *

    + * Using a cached FlutterEngine + *

    * {@code FlutterActivity} can be used with a cached {@link FlutterEngine} instead of creating a new * one. Use {@link #withCachedEngine(String)} to build a {@code FlutterActivity} {@code Intent} that - * is configured to use an existing, cached {@link FlutterEngine}. {@link FlutterEngineCache} is the - * cache that is used to obtain a given cached {@link FlutterEngine}. An - * {@code IllegalStateException} will be thrown if a cached engine is requested but does not exist - * in the cache. + * is configured to use an existing, cached {@link FlutterEngine}. + * {@link io.flutter.embedding.engine.FlutterEngineCache} is the cache that is used to obtain a + * given cached {@link FlutterEngine}. An {@code IllegalStateException} will be thrown if a cached + * engine is requested but does not exist in the cache. + *

    + * When using a cached {@link FlutterEngine}, that {@link FlutterEngine} should already be executing + * Dart code, which means that the Dart entrypoint and initial route have already been defined. + * Therefore, {@link CachedEngineIntentBuilder} does not offer configuration of these properties. *

    * It is generally recommended to use a cached {@link FlutterEngine} to avoid a momentary delay * when initializing a new {@link FlutterEngine}. The two exceptions to using a cached @@ -92,6 +100,8 @@ * FlutterEngineCache.getInstance().put("my_engine", flutterEngine); * } *

    + * Alternatives to FlutterActivity + *

    * If Flutter is needed in a location that cannot use an {@code Activity}, consider using * a {@link FlutterFragment}. Using a {@link FlutterFragment} requires forwarding some calls from * an {@code Activity} to the {@link FlutterFragment}. @@ -177,7 +187,6 @@ public class FlutterActivity extends Activity protected static final String NORMAL_THEME_META_DATA_KEY = "io.flutter.embedding.android.NormalTheme"; // Intent extra arguments. - protected static final String EXTRA_DART_ENTRYPOINT = "dart_entrypoint"; protected static final String EXTRA_INITIAL_ROUTE = "initial_route"; protected static final String EXTRA_BACKGROUND_MODE = "background_mode"; protected static final String EXTRA_CACHED_ENGINE_ID = "cached_engine_id"; @@ -213,7 +222,6 @@ public static NewEngineIntentBuilder withNewEngine() { */ public static class NewEngineIntentBuilder { private final Class activityClass; - private String dartEntrypoint = DEFAULT_DART_ENTRYPOINT; private String initialRoute = DEFAULT_INITIAL_ROUTE; private String backgroundMode = DEFAULT_BACKGROUND_MODE; @@ -234,15 +242,6 @@ protected NewEngineIntentBuilder(@NonNull Class activ this.activityClass = activityClass; } - /** - * The name of the initial Dart method to invoke, defaults to "main". - */ - @NonNull - public NewEngineIntentBuilder dartEntrypoint(@NonNull String dartEntrypoint) { - this.dartEntrypoint = dartEntrypoint; - return this; - } - /** * The initial route that a Flutter app will render in this {@link FlutterFragment}, * defaults to "/". @@ -282,7 +281,6 @@ public NewEngineIntentBuilder backgroundMode(@NonNull BackgroundMode backgroundM @NonNull public Intent build(@NonNull Context context) { return new Intent(context, activityClass) - .putExtra(EXTRA_DART_ENTRYPOINT, dartEntrypoint) .putExtra(EXTRA_INITIAL_ROUTE, initialRoute) .putExtra(EXTRA_BACKGROUND_MODE, backgroundMode) .putExtra(EXTRA_DESTROY_ENGINE_WITH_ACTIVITY, true); @@ -292,7 +290,7 @@ public Intent build(@NonNull Context context) { /** * Creates a {@link CachedEngineIntentBuilder}, which can be used to configure an {@link Intent} * to launch a {@code FlutterActivity} that internally uses an existing {@link FlutterEngine} that - * is cached in {@link FlutterEngineCache}. + * is cached in {@link io.flutter.embedding.engine.FlutterEngineCache}. */ public static CachedEngineIntentBuilder withCachedEngine(@NonNull String cachedEngineId) { return new CachedEngineIntentBuilder(FlutterActivity.class, cachedEngineId); @@ -300,7 +298,7 @@ public static CachedEngineIntentBuilder withCachedEngine(@NonNull String cachedE /** * Builder to create an {@code Intent} that launches a {@code FlutterActivity} with an existing - * {@link FlutterEngine} that is cached in {@link FlutterEngineCache}. + * {@link FlutterEngine} that is cached in {@link io.flutter.embedding.engine.FlutterEngineCache}. */ public static class CachedEngineIntentBuilder { private final Class activityClass; @@ -671,26 +669,14 @@ public boolean shouldDestroyEngineWithHost() { /** * The Dart entrypoint that will be executed as soon as the Dart snapshot is loaded. *

    - * This preference can be controlled with 2 methods: - *

      - *
    1. Pass a {@code String} as {@link #EXTRA_DART_ENTRYPOINT} with the launching {@code Intent}, or
    2. - *
    3. Set a {@code } called {@link #DART_ENTRYPOINT_META_DATA_KEY} for this - * {@code Activity} in the Android manifest.
    4. - *
    - * If both preferences are set, the {@code Intent} preference takes priority. - *

    - * The reason that a {@code } preference is supported is because this {@code Activity} - * might be the very first {@code Activity} launched, which means the developer won't have - * control over the incoming {@code Intent}. + * This preference can be controlled by setting a {@code } called + * {@link #DART_ENTRYPOINT_META_DATA_KEY} within the Android manifest definition for this + * {@code FlutterActivity}. *

    * Subclasses may override this method to directly control the Dart entrypoint. */ @NonNull public String getDartEntrypointFunctionName() { - if (getIntent().hasExtra(EXTRA_DART_ENTRYPOINT)) { - return getIntent().getStringExtra(EXTRA_DART_ENTRYPOINT); - } - try { ActivityInfo activityInfo = getPackageManager().getActivityInfo( getComponentName(), 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 694b349a8aa2f..9e6b2985199ed 100644 --- a/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityTest.java +++ b/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityTest.java @@ -39,14 +39,12 @@ public void itCreatesDefaultIntentWithExpectedDefaults() { @Test public void itCreatesNewEngineIntentWithRequestedSettings() { Intent intent = FlutterActivity.withNewEngine() - .dartEntrypoint("custom_entrypoint") .initialRoute("/custom/route") .backgroundMode(FlutterActivity.BackgroundMode.transparent) .build(RuntimeEnvironment.application); ActivityController activityController = Robolectric.buildActivity(FlutterActivity.class, intent); FlutterActivity flutterActivity = activityController.get(); - assertEquals("custom_entrypoint", flutterActivity.getDartEntrypointFunctionName()); assertEquals("/custom/route", flutterActivity.getInitialRoute()); assertArrayEquals(new String[]{}, flutterActivity.getFlutterShellArgs().toArray()); assertTrue(flutterActivity.shouldAttachEngineToActivity());