[modules] Add description of autogenerated module class to readme
Bug: 925528
Change-Id: I6550ce1db71eda6152167eb59916b0b89f22dab9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1604114
Commit-Queue: Tibor Goldschwendt <[email protected]>
Reviewed-by: Ted Choc <[email protected]>
Cr-Commit-Position: refs/heads/master@{#658628}
diff --git a/docs/android_dynamic_feature_modules.md b/docs/android_dynamic_feature_modules.md
index 7401805b..70c8401f 100644
--- a/docs/android_dynamic_feature_modules.md
+++ b/docs/android_dynamic_feature_modules.md
@@ -245,13 +245,19 @@
To make Foo useful, let's add some Java code to it. This section will walk you
through the required steps.
-First, define a module interface in the new file
+First, define a module interface for Foo. This is accomplished by adding the
+`@ModuleInterface` annotation to the Foo interface. This annotation
+automatically creates a `FooModule` class that can be used later to install and
+access the module. To do this, add the following in the new file
`//chrome/android/features/foo/public/java/src/org/chromium/chrome/features/foo/Foo.java`:
```java
package org.chromium.chrome.features.foo;
+import org.chromium.components.module_installer.ModuleInterface;
+
/** Interface to call into Foo feature. */
+@ModuleInterface(module = "foo", impl = "org.chromium.chrome.features.FooImpl")
public interface Foo {
/** Magical function. */
void bar();
@@ -271,7 +277,9 @@
package org.chromium.chrome.features.foo;
import org.chromium.base.Log;
+import org.chromium.base.annotations.UsedByReflection;
+@UsedByReflection("FooModule")
public class FooImpl implements Foo {
@Override
public void bar() {
@@ -280,58 +288,25 @@
}
```
-In order to get the Foo implementation depending on whether the Foo DFM
-is present, we will add a module provider class handling that logic. For
-this, create the file
-`//chrome/android/features/foo/public/java/src/org/chromium/chrome/features/foo/FooModuleProvider.java`
-and add:
-
-```java
-package org.chromium.chrome.features.foo;
-
-/** Provides the Foo implementation. */
-public class FooModuleProvider {
- private static Foo sFoo;
-
- /**
- * Returns Foo implementation or null if Foo module is not installed.
- */
- public static Foo getFoo {
- if (sFoo == null) {
- try {
- sFoo = (Foo) Class
- .forName("org.chromium.chrome.features.foo.FooImpl")
- .newInstance();
- } catch (ClassNotFoundException | InstantiationException
- | IllegalAccessException | IllegalArgumentException e) {
- // Foo module is not installed. Leave sFoo as null.
- }
- }
- return sFoo;
- }
-}
-```
-
You can then use this provider to access the module if it is installed. To test
that, instantiate Foo and call `bar()` somewhere in Chrome:
```java
-if (FooModuleProvider.getFoo() != null) {
- FooModuleProvider.getFoo().bar();
+if (FooModule.isInstalled()) {
+ FooModule.getImpl().bar();
} else {
Log.i("FOO", "module not installed");
}
```
-The interface and module provider have to be available regardless of whether the
-Foo DFM is present. Therefore, put those classes into the base module. For this
-create a list of those Java files in
+The interface has to be available regardless of whether the Foo DFM is present.
+Therefore, put those classes into the base module. For this create a list of
+those Java files in
`//chrome/android/features/foo/public/foo_public_java_sources.gni`:
```gn
foo_public_java_sources = [
"//chrome/android/features/foo/public/java/src/org/chromium/chrome/features/foo/Foo.java",
- "//chrome/android/features/foo/public/java/src/org/chromium/chrome/features/foo/FooModuleProvider.java",
]
```
@@ -516,8 +491,10 @@
import org.chromium.base.ContextUtils;
import org.chromium.base.Log;
+import org.chromium.base.annotations.UsedByReflection;
import org.chromium.chrome.features.foo.R;
+@UsedByReflection("FooModule")
public class FooImpl implements Foo {
@Override
public void bar() {
@@ -551,41 +528,19 @@
module as soon as possible regardless of whether the user is on a metered
connection or whether they have turned updates off in the Play Store app.
-To request a module on-demand we can make use of the `ModuleInstaller` from
-`//components/module_installer/`. For this add, the following function to
-`FooModuleProvider` in
-`//chrome/android/features/foo/public/java/src/org/chromium/chrome/foo/FooModuleProvider.java`:
+You can use the autogenerated module class to on-demand install the module like
+so:
```java
-/**
- * On-demand install Foo module.
- * @param onFinishedListener listener to be called when install has finished.
- */
-public static installModule(
- OnModuleInstallFinishedListener onFinishedListener) {
- ModuleInstaller.install("foo", (success) -> {
- if (success) {
- assert getFoo() != null;
- }
- onFinishedListener.onFinished(success);
- });
-}
-```
-
-Then, use this new function to request the module and call `bar()` on install
-completion:
-
-```java
-// Need to call init before accessing any modules. Can be called multiple times.
-ModuleInstaller.init();
-FooModuleProvider.installModule((success) -> {
- FooModuleProvider.getFoo().bar();
+FooModule.install((success) -> {
+ if (success) {
+ FooModule.getImpl().bar();
+ }
});
```
**Optionally**, you can show UI telling the user about the install flow. For
-this, add the function below to `FooModuleProvider`. Then use
-`installModuleWithUi(...)` instead of `installModule(...)`. Note, it is possible
+this, add a function like the one below. Note, it is possible
to only show either one of the install, failure and success UI or any
combination of the three.
@@ -609,7 +564,7 @@
});
// At the time of writing, shows toast informing user about install start.
ui.showInstallStartUi();
- installModule(
+ FooModule.install(
(success) -> {
if (!success) {
// At the time of writing, shows infobar allowing user
@@ -657,7 +612,7 @@
To defer install Foo do the following:
```java
-ModuleInstaller.installDeferred("foo");
+FooModule.installDeferred();
```