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

[WIP]add the feature that can create a new engine with FlutterEngineGroup … #29293

Closed
wants to merge 7 commits into from

Conversation

kylinchen
Copy link

@kylinchen kylinchen commented Oct 22, 2021

add the feature that can create a new engine with FlutterEngineGroup for FlutterActivity/FlutterFragment.

FlutterActivity/FlutterFragment adds support for multiple engines. The user sets the FlutterEngineGroup ID, calls the withNewEngineInGroup method, and creates a FlutterEngine in this FlutterEngineGroup.

fix issue:
flutter/flutter#72742

Pre-launch Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [Tree Hygiene] wiki page, which explains my responsibilities.
  • I read and followed the [Flutter Style Guide] and the [C++, Objective-C, Java style guides].
  • I listed at least one issue that this PR fixes in the description above.
  • I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test-exempt. See [testing the engine] for instructions on
    writing and running engine tests.
  • I updated/added relevant documentation (doc comments with ///).
  • I signed the [CLA].
  • All existing and new tests are passing.

@google-cla
Copy link

google-cla bot commented Oct 22, 2021

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here with @googlebot I signed it! and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

@google-cla google-cla bot added the cla: no label Oct 22, 2021
@kylinchen
Copy link
Author

@googlebot I signed it!

@google-cla google-cla bot added cla: yes and removed cla: no labels Oct 22, 2021
@google-cla
Copy link

google-cla bot commented Oct 22, 2021

All (the pull request submitter and all commit authors) CLAs are signed, but one or more commits were authored or co-authored by someone other than the pull request submitter.

We need to confirm that all authors are ok with their commits being contributed to this project. Please have them confirm that by leaving a comment that contains only @googlebot I consent. in this pull request.

Note to project maintainer: There may be cases where the author cannot leave a comment, or the comment is not properly detected as consent. In those cases, you can manually confirm consent of the commit author(s), and set the cla label to yes (if enabled on your project).

ℹ️ Googlers: Go here for more info.

@google-cla google-cla bot added cla: no and removed cla: yes labels Oct 22, 2021
@chinmaygarde
Copy link
Member

cc @blasten Do you have the cycles to review this soon?

* io.flutter.embedding.engine.FlutterEngineGroupCache}. and creates a new {@link
* io.flutter.embedding.engine.FlutterEngine} by FlutterEngineGroup#createAndRunEngine
*
* @param engineGroupId A cached engine group ID.
Copy link

Choose a reason for hiding this comment

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

can we add a code snippet that demonstrates a correct use of this method?

Copy link
Author

Choose a reason for hiding this comment

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

done

* Constructor that allows this {@code NewEngineInGroupIntentBuilder} to be used by subclasses
* of {@code FlutterActivity}.
*
* <p>Subclasses of {@code FlutterActivity} should provide their own static version of {@link
Copy link

Choose a reason for hiding this comment

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

same comment: an example would be helpful

Copy link
Author

Choose a reason for hiding this comment

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

done

*
* <p>A {@code FlutterActivity} that is configured with a background mode of {@link
* BackgroundMode#transparent} must have a theme applied to it that includes the following
* property: {@code <item name="android:windowIsTranslucent">true</item>}.
Copy link

Choose a reason for hiding this comment

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

in app/src/main/res/values/styles.xml right?

Copy link
Author

Choose a reason for hiding this comment

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

yes, in app/src/main/res/values/styles.xml, we can define custom theme for activity, and set the background of activity.

/**
* Returns a {@link NewEngineInGroupFragmentBuilder} to create a {@code FlutterFragment} with a
* cached {@link io.flutter.embedding.engine.FlutterEngineGroup} in {@link
* io.flutter.embedding.engine.FlutterEngineGroupCache}. creates a new {@link
Copy link

Choose a reason for hiding this comment

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

I think this sentence got cut off

Copy link
Author

Choose a reason for hiding this comment

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

done

private String initialRoute = "/";
private boolean handleDeeplinking = false;
private RenderMode renderMode = RenderMode.surface;
private TransparencyMode transparencyMode = TransparencyMode.transparent;
Copy link

Choose a reason for hiding this comment

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

nit: NonNull annotation for the required fields

Copy link
Author

Choose a reason for hiding this comment

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

done

@blasten
Copy link

blasten commented Nov 12, 2021

This is a great PR.

First pass review, I'd like to see maybe a bit more code snippets in the code about how to use these APIs.

* getInitialRoute} returns null.
*/
@NonNull
public NewEngineInGroupFragmentBuilder handleDeeplinking(@NonNull Boolean handleDeeplinking) {
Copy link

Choose a reason for hiding this comment

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

can this be boolean?

Copy link
Author

Choose a reason for hiding this comment

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

done

@CaseyHillers CaseyHillers changed the base branch from master to main November 15, 2021 18:13
@godofredoc godofredoc changed the base branch from master to main November 24, 2021 07:13
@chinmaygarde
Copy link
Member

Is progress being made on this issue? Looks like @blasten has a few open suggestions.

@gaaclarke
Copy link
Member

gaaclarke commented Dec 2, 2021

I closed out the iOS implementation saying that convenience functions can be implemented by users and incorporating them into the API doesn't scale.

edit: I said this after having read through the iOS PR. This Android one is a bit more involved so it might make sense having this if it's not just trivial convenience but removing boilerplate that will exist for most users. I haven't had a chance to read it closely to see if that's the case.

@ColdPaleLight
Copy link
Member

Is progress being made on this issue? Looks like @blasten has a few open suggestions.

Yes, it will update soon.

/**
* Creates a {@link NewEngineInGroupIntentBuilder}, which can be used to configure an {@link
* Intent} to launch a {@code FlutterActivity} that internally uses an existing {@link
* io.flutter.embedding.engine.FlutterEngineGroup} that is cached in {@link
Copy link
Member

Choose a reason for hiding this comment

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

that is cached in a FlutterEngineGroup

Copy link
Author

@kylinchen kylinchen Dec 6, 2021

Choose a reason for hiding this comment

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

yes, when we use this method. First, we should create a FlutterEngineGroup and cached in FlutterEngineGroupCache by flutterEngineGroupId. Then we can use FlutterActivity.withNewEngineInGroup(flutterEngineGroupId) to create intent and start FlutterActivity

* Creates a {@link NewEngineInGroupIntentBuilder}, which can be used to configure an {@link
* Intent} to launch a {@code FlutterActivity} that internally uses an existing {@link
* io.flutter.embedding.engine.FlutterEngineGroup} that is cached in {@link
* io.flutter.embedding.engine.FlutterEngineGroupCache}. and creates a new {@link
Copy link
Member

Choose a reason for hiding this comment

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

to launch a FlutterActivity by internally creating a FlutterEngine from an existing FlutterEngineGroup cached in a specified FlutterEngineGroupCache

}

/**
* The Dart entrypoint that will be executed as soon as the Dart snapshot is loaded, default to
Copy link
Member

Choose a reason for hiding this comment

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

The Dart entrypoint that will be executed in the newly created FlutterEngine as soon as the Dart snapshot is loaded

* @return The engine group intent builder.
*/
@NonNull
public NewEngineInGroupIntentBuilder backgroundMode(@NonNull BackgroundMode backgroundMode) {
Copy link
Member

Choose a reason for hiding this comment

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

rather than copying all this stuff again, can't we have them both be in the same builder class? Just have 2 constructors. One with an engine id and one with a engine group id.

Copy link
Author

Choose a reason for hiding this comment

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

yes , we can have them both be in the same builder class. But this break Single Responsibility Principle.

@@ -214,6 +216,10 @@ void onAttach(@NonNull Context context) {
* <p>Second, the {@code host} is given an opportunity to provide a {@link
* io.flutter.embedding.engine.FlutterEngine} via {@link Host#provideFlutterEngine(Context)}.
*
* <p>Third, the {@code host} is given an FluttenEngineGroup Id, then used a cached {@link
Copy link
Member

Choose a reason for hiding this comment

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

this statement doesn't match the code below? The host is asked whether it would like to provide a cached FlutterEngineGroup id rather than being given one

Copy link
Author

Choose a reason for hiding this comment

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

yes, you are right. I will update

+ "'");
}

String appBundlePathOverride = host.getAppBundlePath();
Copy link
Member

Choose a reason for hiding this comment

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

this block seems unrelated to the proposed change and is a scope creep right?

Copy link
Author

Choose a reason for hiding this comment

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

because the Constructor of DartEntrypoint need 2 params. One is AppBundlePath, this block provide it from Host or FlutterLoader

* <p>The ID of a given {@link io.flutter.embedding.engine.FlutterEngineGroup} can be whatever
* {@code String} is desired.
*
* <p>{@code FlutterEngineGroupCache} is useful for storing pre-warmed {@link
Copy link
Member

Choose a reason for hiding this comment

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

this sentence makes sense for FlutterEngine, less for FlutterEngineGroups. e.g. a FlutterEngineGroup can't exactly be "pre-warmed"

Copy link
Author

Choose a reason for hiding this comment

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

yes, you are right. I will update

…terEngineGroup

add a code snippet for the feature that create a new engine with FlutterEngineGroup
@kylinchen kylinchen force-pushed the activity_with_engine_group branch from b9b3ace to eb2d4d8 Compare December 6, 2021 12:44
@kylinchen kylinchen requested review from xster and blasten December 8, 2021 05:54
@ColdPaleLight
Copy link
Member

Friendly ping @blasten @xster

Copy link
Member

@xster xster left a comment

Choose a reason for hiding this comment

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

sorry for the wait. I was away last month. Almost there.

* Intent} to launch a {@code FlutterActivity} by internally creating a FlutterEngine from an
* existing {@link io.flutter.embedding.engine.FlutterEngineGroup} cached in a specified {@link
* io.flutter.embedding.engine.FlutterEngineGroupCache}, and creates a new {@link
* io.flutter.embedding.engine.FlutterEngine} by FlutterEngineGroup#createAndRunEngine
Copy link
Member

Choose a reason for hiding this comment

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

we can remove the last sentence

* io.flutter.embedding.engine.FlutterEngine} by FlutterEngineGroup#createAndRunEngine
*
* <pre>{@code
* // Create a FlutterEngineGroup, usually we could create it in onCreate method of Application.
Copy link
Member

Choose a reason for hiding this comment

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

Create a FlutterEngineGroup, such as in the onCreate method of the Application

* FlutterEngineGroup engineGroup = new FlutterEngineGroup(this);
* FlutterEngineGroupCache.getInstance().put("my_cached_engine_group_id", engineGroup);
*
* // use the intent that build by withNewEngineInGroup to start FlutterActivity
Copy link
Member

Choose a reason for hiding this comment

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

Start a FlutterActivity with the FlutterEngineGroup by creating an intent with withNewEngineInGroup


/**
* Builder to create an {@code Intent} that launches a {@code FlutterActivity} with a new {@link
* FlutterEngine} by FlutterEngineGroup#createAndRunEngine.
Copy link
Member

Choose a reason for hiding this comment

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

with a new {@link FlutterEngine} created by FlutterEngineGroup#createAndRunEngine.

* cacheedEngineGroupId); }
*
* <pre>{@code
* // Create a FlutterEngineGroup, usually we could create it in onCreate method of Application.
Copy link
Member

Choose a reason for hiding this comment

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

Create a FlutterEngineGroup, such as in the onCreate method of the Application

* FlutterEngineGroup engineGroup = new FlutterEngineGroup(this);
* FlutterEngineGroupCache.getInstance().put("my_cached_engine_group_id", engineGroup);
*
* // create NewEngineInGroupIntentBuilder, and start my custom FlutterActivity with the intent
Copy link
Member

Choose a reason for hiding this comment

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

Create a NewEngineInGroupIntentBuilder that would build an intent to start my custom FlutterActivity subclass.

@@ -213,6 +215,10 @@ void onAttach(@NonNull Context context) {
* <p>Second, the {@code host} is given an opportunity to provide a {@link
* io.flutter.embedding.engine.FlutterEngine} via {@link Host#provideFlutterEngine(Context)}.
*
* <p>Third, the {@code host} is given an FluttenEngineGroup Id, then used a cached {@link
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* <p>Third, the {@code host} is given an FluttenEngineGroup Id, then used a cached {@link
* <p>Third, the {@code host} is asked if it would like to use a cached
* {@link io.flutter.embedding.engine.FlutterEngineGroup}. If so, the cached
* {@link io.flutter.embedding.engine.FlutterEngineGroup} is used to create a new
* {@link io.flutter.embedding.engine.FlutterEngine}.

@@ -241,6 +247,34 @@ void onAttach(@NonNull Context context) {
return;
}

// Third, check if the host wants to use a cached FlutterEngineGroup
// and create new FlutterEngine by FlutterEngineGroup#createAndRunEngine
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// and create new FlutterEngine by FlutterEngineGroup#createAndRunEngine
// and create new FlutterEngine using FlutterEngineGroup#createAndRunEngine

@@ -702,6 +705,263 @@ protected Bundle createArgs() {
}
}

/**
Copy link
Member

Choose a reason for hiding this comment

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

same comments on the doc for from FlutterActivity on the next 2 classes

@@ -178,7 +178,7 @@ public void onEngineWillDestroy() {
}

@VisibleForTesting
/* package */ FlutterEngine createEngine(Context context) {
public FlutterEngine createEngine(Context context) {
Copy link
Member

Choose a reason for hiding this comment

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

you don't need to do this right?

@chinmaygarde
Copy link
Member

@kylinchen Any updates after @xster s last review?

@chinmaygarde
Copy link
Member

Closing as this seems stale. Please re-open once progress can be made. Thanks.

@ColdPaleLight ColdPaleLight added the Work in progress (WIP) Not ready (yet) for review! label May 16, 2022
@ColdPaleLight ColdPaleLight changed the title add the feature that can create a new engine with FlutterEngineGroup … [WIP]add the feature that can create a new engine with FlutterEngineGroup … May 16, 2022
@ColdPaleLight ColdPaleLight reopened this May 16, 2022
@ColdPaleLight
Copy link
Member

Talked to @kylinchen offline and he will restart work on this PR recently. So I reopened the PR and marked it as "WIP"

@chinmaygarde
Copy link
Member

Are any updates on this likely?

@ColdPaleLight
Copy link
Member

I'll take over this PR and close it for now. I will reopen it in the future.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants