Skip to content

Conversation

@GaryQian
Copy link
Contributor

@GaryQian GaryQian commented Dec 23, 2020

Adds a utility class DeferredComponent which contains wrappers around system channel methods that handle manual installation/uninstallation/state of deferred components.

The current API exposes only installation and querying by module name, which restricts the API to asset-only components. Dart code should be loaded via calling loadLibrary() on the deferred import. Exposing a parameter for loadingUnitId would require additional dart work and is not necessary for the initial release of Deferred components.

@GaryQian GaryQian added c: new feature Nothing broken; request for a new capability engine flutter/engine related. See also e: labels. customer: money (g3) labels Dec 23, 2020
@flutter-dashboard flutter-dashboard bot added the framework flutter/packages/flutter repository. See also f: labels. label Dec 23, 2020
@google-cla google-cla bot added the cla: yes label Dec 23, 2020
@GaryQian GaryQian marked this pull request as ready for review December 28, 2020 17:52
@GaryQian GaryQian changed the title [WIP] DynamicFeatures utility class for manual handling of DynamicFeatures DynamicFeature utility class for manual handling of DynamicFeatures Dec 28, 2020
@GaryQian GaryQian requested a review from xster December 28, 2020 17:52
@xster
Copy link
Member

xster commented Jan 7, 2021

The general concept seems sound to me. Though we should get some feedback from the framework team too for adding a new top level API class to services package.

@GaryQian GaryQian changed the title DynamicFeature utility class for manual handling of DynamicFeatures DeferredComponent utility class for manual handling of Deferred Components Jan 8, 2021
///
/// Returned by [DeferredComponent.getDeferredComponentInstallState].
///
/// These states may differ in custom deferred component implementations.
Copy link
Member

Choose a reason for hiding this comment

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

What makes a component "custom"? Where could the reader learn more about custom components?

Copy link
Member

Choose a reason for hiding this comment

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

What would DeferredComponent.getDeferredComponentInstallState return for custom components that have different state?

Copy link
Contributor Author

@GaryQian GaryQian Jan 8, 2021

Choose a reason for hiding this comment

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

I'll be writing a guide on creating custom deferred components. Custom components are very open ended, and thus, this API has been left open ended. Since this state getting API is informational/quality-of-life, this open-ended-ness should not impact functionality, so I planned on leaving it as a channel to pass whatever information custom implementers wish. Also, custom implementations can be considered a very advanced feature, as it requires not only the custom impl and servers to host the files, but also a custom build setup to build the custom components. Thus, I'm erring on the less restrictive side here.

}

/// Manages the installation and loading of deferred component modules.
///
Copy link
Member

Choose a reason for hiding this comment

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

The docs above mention "Google Play Store". Is this an Android-only feature (for now)? May be worthwhile to mention that here as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The initial version of this is Android only, but I do plan on extending this in some form to other platforms in the future.

Copy link
Member

Choose a reason for hiding this comment

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

That's fine but for now, at least say somewhere that it does something on Android only. Describe what happens when used in other platforms.

Copy link
Member

Choose a reason for hiding this comment

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

+1 We can update the docs when this does more on other platforms.

/// avoiding installing unnessecary code/assets on end user devices. Common
/// use cases include deferring installation of advanced or infrequently
/// used features and limiting locale specific features to users of matching
/// locales.
Copy link
Member

Choose a reason for hiding this comment

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

Are there docs we can link to from here in case a developer wants to learn more about how to add a DeferredComponent to his project?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll be writing up a full set of guides, examples, and whatnot for the release of this feature. I'll add links to the full docs once those exist.

/// may only be used after the Future completes succesfully, regardless of what
/// the installation state is in.
static Future<String?> getDeferredComponentInstallState({@required String? moduleName}) async {
await SystemChannels.deferredComponent.invokeMethod<void>(
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't this method return something?

Copy link
Member

Choose a reason for hiding this comment

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

Maybe worthwhile to add a test...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops, yes!


/// Requests that a deferred component identified by the [moduleName] be
/// uninstalled.
///
Copy link
Member

Choose a reason for hiding this comment

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

Is this always safe to be called? What if the dart code from the component or the asset is still "in use"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Once loaded in and in use, uninstallation should not effect the dart code in the app's current session, though assets may become inaccessible. I'll make note of this.

}

/// Manages the installation and loading of deferred component modules.
///
Copy link
Member

Choose a reason for hiding this comment

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

That's fine but for now, at least say somewhere that it does something on Android only. Describe what happens when used in other platforms.


/// Manages the installation and loading of deferred component modules.
///
/// Deferred components allow Flutter applications to download precompiled AOT
Copy link
Member

Choose a reason for hiding this comment

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

Need to be a bit clearer on the fact that this is only for parts that are part of the same app you built and uploaded to the store. You can't add new things.

/// This method will not load associated dart libraries contained in the dynamic
/// feature module, though it will download the files necessary and subsequent
/// calls to `loadLibrary()` to load will complete faster.
///
Copy link
Member

Choose a reason for hiding this comment

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

Brief reference or description on how to subsequently consume said asset after loading.

/// the dart method to trigger the installation of the corresponding deferred component that
/// contains the dart library.
/// * [installDeferredComponent], a method to install asset-only components.
static Future<String?> getDeferredComponentInstallState({required String moduleName}) {
Copy link
Member

Choose a reason for hiding this comment

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

Can this ever return null? or should the ? be removed?

Copy link
Member

Choose a reason for hiding this comment

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

Also, as said above, it is confusing that this returns a String, but the doc above talks about it returning an enum value of DeferredComponentInstallState.

Copy link
Contributor Author

@GaryQian GaryQian Jan 12, 2021

Choose a reason for hiding this comment

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

I'm going to just remove this feature from the initial release of deferred components to avoid releasing a strange/limiting API as per discussion earlier today. We can add this method back in at a later date once how this feature works across other platforms is fleshed out further.

The nullable String is because invokeMethod always completes with a nullable value. The value can be null when the method does not exist.

@GaryQian GaryQian requested a review from goderbauer January 13, 2021 02:22
Copy link
Member

@goderbauer goderbauer left a comment

Choose a reason for hiding this comment

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

LGTM

/// app that was built and installed on the device. It cannot load new code
/// written after the app is distributed.
///
/// Deferred components are currently and Android-only feature. The methods in
Copy link
Member

Choose a reason for hiding this comment

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

typo: and -> an

///
/// Since uninstallation typically requires significant disk i/o, this method only
/// signals the intent to uninstall. Completion of the returned future indicates
/// that the request to uninstall has been registered. Actual uninstallation (eg,
Copy link
Member

Choose a reason for hiding this comment

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

nit: eg -> e.g.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c: new feature Nothing broken; request for a new capability customer: money (g3) engine flutter/engine related. See also e: labels. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants