Add option to specify use of isolated splits

Bug: b/300247439
Change-Id: I521870cc749500f4c144284f837c823cf1b4d723
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index 9fd20d8..07b3ef5 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -131,7 +131,8 @@
     private GraphConsumer keptGraphConsumer = null;
     private GraphConsumer mainDexKeptGraphConsumer = null;
     private InputDependencyGraphConsumer inputDependencyGraphConsumer = null;
-    private final List<FeatureSplit> featureSplits = new ArrayList<>();
+    private final FeatureSplitConfiguration.Builder featureSplitConfigurationBuilder =
+        FeatureSplitConfiguration.builder();
     private String synthesizedClassPrefix = "";
     private boolean enableMissingLibraryApiModeling = false;
     private boolean enableExperimentalKeepAnnotations =
@@ -446,7 +447,7 @@
     public Builder addFeatureSplit(
         Function<FeatureSplit.Builder, FeatureSplit> featureSplitGenerator) {
       FeatureSplit featureSplit = featureSplitGenerator.apply(FeatureSplit.builder(getReporter()));
-      featureSplits.add(featureSplit);
+      featureSplitConfigurationBuilder.addFeatureSplit(featureSplit);
       for (ProgramResourceProvider programResourceProvider : featureSplit
           .getProgramResourceProviders()) {
         // Data resources are handled separately and passed directly to the feature split consumer.
@@ -467,6 +468,18 @@
     }
 
     /**
+     * Used to specify if the application is using isolated splits, i.e., if split APKs installed
+     * for this application are loaded into their own Context objects.
+     *
+     * <p>See also <a href="https://developer.android.com/reference/android/R.attr#isolatedSplits">
+     * R.attr#isolatedSplits</a>.
+     */
+    public Builder setEnableExperimentalIsolatedSplits(boolean enableIsolatedSplits) {
+      featureSplitConfigurationBuilder.setEnableIsolatedSplits(enableIsolatedSplits);
+      return this;
+    }
+
+    /**
      * Enable experimental/pre-release support for modeling missing library APIs.
      *
      * <p>This allows enabling the feature while it is still default disabled by the compiler. Once
@@ -580,7 +593,7 @@
                   + " and above");
         }
       }
-      for (FeatureSplit featureSplit : featureSplits) {
+      for (FeatureSplit featureSplit : featureSplitConfigurationBuilder.getFeatureSplits()) {
         verifyResourceSplitOrProgramSplit(featureSplit);
         if (getProgramConsumer() != null && !(getProgramConsumer() instanceof DexIndexedConsumer)) {
           reporter.error("R8 does not support class file output when using feature splits");
@@ -667,9 +680,6 @@
               ? DesugarState.OFF
               : getDesugaringState();
 
-      FeatureSplitConfiguration featureSplitConfiguration =
-          !featureSplits.isEmpty() ? new FeatureSplitConfiguration(featureSplits) : null;
-
       R8Command command =
           new R8Command(
               getAppBuilder().build(),
@@ -698,7 +708,7 @@
               getDexClassChecksumFilter(),
               desugaredLibraryKeepRuleConsumer,
               desugaredLibrarySpecification,
-              featureSplitConfiguration,
+              featureSplitConfigurationBuilder.build(),
               getAssertionsConfiguration(),
               getOutputInspections(),
               synthesizedClassPrefix,
diff --git a/src/main/java/com/android/tools/r8/features/FeatureSplitConfiguration.java b/src/main/java/com/android/tools/r8/features/FeatureSplitConfiguration.java
index c357177..af85bd2 100644
--- a/src/main/java/com/android/tools/r8/features/FeatureSplitConfiguration.java
+++ b/src/main/java/com/android/tools/r8/features/FeatureSplitConfiguration.java
@@ -16,9 +16,15 @@
 public class FeatureSplitConfiguration {
 
   private final List<FeatureSplit> featureSplits;
+  private final boolean isolatedSplits;
 
-  public FeatureSplitConfiguration(List<FeatureSplit> featureSplits) {
+  public FeatureSplitConfiguration(List<FeatureSplit> featureSplits, boolean isolatedSplits) {
     this.featureSplits = featureSplits;
+    this.isolatedSplits = isolatedSplits;
+  }
+
+  public static Builder builder() {
+    return new Builder();
   }
 
   public static class DataResourceProvidersAndConsumer {
@@ -67,4 +73,34 @@
   public List<FeatureSplit> getFeatureSplits() {
     return featureSplits;
   }
+
+  public boolean isIsolatedSplitsEnabled() {
+    return isolatedSplits;
+  }
+
+  public static class Builder {
+
+    private List<FeatureSplit> featureSplits = new ArrayList<>();
+    private boolean isolatedSplits;
+
+    public Builder addFeatureSplit(FeatureSplit featureSplit) {
+      featureSplits.add(featureSplit);
+      return this;
+    }
+
+    public List<FeatureSplit> getFeatureSplits() {
+      return featureSplits;
+    }
+
+    public Builder setEnableIsolatedSplits(boolean isolatedSplits) {
+      this.isolatedSplits = isolatedSplits;
+      return this;
+    }
+
+    public FeatureSplitConfiguration build() {
+      return featureSplits.isEmpty()
+          ? null
+          : new FeatureSplitConfiguration(featureSplits, isolatedSplits);
+    }
+  }
 }