Add public API for adding ART profiles for rewriting

Bug: b/237043695
Change-Id: I9ff06771807471bf8a20f848f8c681f21d86fd27
diff --git a/src/main/java/com/android/tools/r8/BaseCompilerCommand.java b/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
index 0900897..a233e49 100644
--- a/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
+++ b/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
@@ -12,7 +12,9 @@
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecificationParser;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecification;
 import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.profile.art.ArtProfileInput;
+import com.android.tools.r8.profile.art.ArtProfileConsumer;
+import com.android.tools.r8.profile.art.ArtProfileForRewriting;
+import com.android.tools.r8.profile.art.ArtProfileProvider;
 import com.android.tools.r8.startup.StartupProfileProvider;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
@@ -58,7 +60,7 @@
   private final MapIdProvider mapIdProvider;
   private final SourceFileProvider sourceFileProvider;
   private final boolean isAndroidPlatformBuild;
-  private final List<ArtProfileInput> artProfileInputs;
+  private final List<ArtProfileForRewriting> artProfilesForRewriting;
   private final List<StartupProfileProvider> startupProfileProviders;
   private final ClassConflictResolver classConflictResolver;
 
@@ -80,7 +82,7 @@
     mapIdProvider = null;
     sourceFileProvider = null;
     isAndroidPlatformBuild = false;
-    artProfileInputs = null;
+    artProfilesForRewriting = null;
     startupProfileProviders = null;
     classConflictResolver = null;
   }
@@ -103,7 +105,7 @@
       MapIdProvider mapIdProvider,
       SourceFileProvider sourceFileProvider,
       boolean isAndroidPlatformBuild,
-      List<ArtProfileInput> artProfileInputs,
+      List<ArtProfileForRewriting> artProfilesForRewriting,
       List<StartupProfileProvider> startupProfileProviders,
       ClassConflictResolver classConflictResolver) {
     super(app);
@@ -125,7 +127,7 @@
     this.mapIdProvider = mapIdProvider;
     this.sourceFileProvider = sourceFileProvider;
     this.isAndroidPlatformBuild = isAndroidPlatformBuild;
-    this.artProfileInputs = artProfileInputs;
+    this.artProfilesForRewriting = artProfilesForRewriting;
     this.startupProfileProviders = startupProfileProviders;
     this.classConflictResolver = classConflictResolver;
   }
@@ -224,8 +226,8 @@
     return isAndroidPlatformBuild;
   }
 
-  List<ArtProfileInput> getArtProfileInputs() {
-    return artProfileInputs;
+  List<ArtProfileForRewriting> getArtProfilesForRewriting() {
+    return artProfilesForRewriting;
   }
 
   List<StartupProfileProvider> getStartupProfileProviders() {
@@ -267,7 +269,6 @@
     protected DesugarState desugarState = DesugarState.ON;
     private List<StringResource> desugaredLibrarySpecificationResources = new ArrayList<>();
     private boolean includeClassesChecksum = false;
-    private boolean lookupLibraryBeforeProgram = true;
     private boolean optimizeMultidexForLinearAlloc = false;
     private BiPredicate<String, Long> dexClassChecksumFilter = (name, checksum) -> true;
     private List<AssertionsConfiguration> assertionsConfiguration = new ArrayList<>();
@@ -277,7 +278,7 @@
     private MapIdProvider mapIdProvider = null;
     private SourceFileProvider sourceFileProvider = null;
     private boolean isAndroidPlatformBuild = false;
-    private List<ArtProfileInput> artProfileInputs = new ArrayList<>();
+    private List<ArtProfileForRewriting> artProfilesForRewriting = new ArrayList<>();
     private List<StartupProfileProvider> startupProfileProviders = new ArrayList<>();
     private ClassConflictResolver classConflictResolver = null;
 
@@ -695,17 +696,21 @@
       return isAndroidPlatformBuild;
     }
 
-    B addArtProfileInputs(ArtProfileInput... artProfileInputs) {
-      return addArtProfileInputs(Arrays.asList(artProfileInputs));
-    }
-
-    B addArtProfileInputs(Collection<ArtProfileInput> artProfileInputs) {
-      this.artProfileInputs.addAll(artProfileInputs);
+    /**
+     * Add an ART profiles that should be rewritten to match the residual application. The ART
+     * profile is given to the compiler by the {@link ArtProfileProvider} and passed back to the
+     * {@link ArtProfileConsumer} at the end of compilation when the ART profile has been fully
+     * rewritten to match the residual application.
+     */
+    public B addArtProfileForRewriting(
+        ArtProfileProvider artProfileProvider, ArtProfileConsumer residualArtProfileProvider) {
+      artProfilesForRewriting.add(
+          new ArtProfileForRewriting(artProfileProvider, residualArtProfileProvider));
       return self();
     }
 
-    List<ArtProfileInput> getArtProfileInputs() {
-      return artProfileInputs;
+    List<ArtProfileForRewriting> getArtProfilesForRewriting() {
+      return artProfilesForRewriting;
     }
 
     B addStartupProfileProviders(StartupProfileProvider... startupProfileProviders) {
diff --git a/src/main/java/com/android/tools/r8/D8Command.java b/src/main/java/com/android/tools/r8/D8Command.java
index 687da32..43bcdee 100644
--- a/src/main/java/com/android/tools/r8/D8Command.java
+++ b/src/main/java/com/android/tools/r8/D8Command.java
@@ -13,7 +13,7 @@
 import com.android.tools.r8.inspector.internal.InspectorImpl;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecification;
 import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.profile.art.ArtProfileInput;
+import com.android.tools.r8.profile.art.ArtProfileForRewriting;
 import com.android.tools.r8.shaking.ProguardConfigurationParser;
 import com.android.tools.r8.shaking.ProguardConfigurationRule;
 import com.android.tools.r8.shaking.ProguardConfigurationSource;
@@ -458,7 +458,7 @@
           proguardMapConsumer,
           enableMissingLibraryApiModeling,
           getAndroidPlatformBuild(),
-          getArtProfileInputs(),
+          getArtProfilesForRewriting(),
           getStartupProfileProviders(),
           getClassConflictResolver(),
           factory);
@@ -551,7 +551,7 @@
       StringConsumer proguardMapConsumer,
       boolean enableMissingLibraryApiModeling,
       boolean isAndroidPlatformBuild,
-      List<ArtProfileInput> artProfileInputs,
+      List<ArtProfileForRewriting> artProfilesForRewriting,
       List<StartupProfileProvider> startupProfileProviders,
       ClassConflictResolver classConflictResolver,
       DexItemFactory factory) {
@@ -573,7 +573,7 @@
         mapIdProvider,
         null,
         isAndroidPlatformBuild,
-        artProfileInputs,
+        artProfilesForRewriting,
         startupProfileProviders,
         classConflictResolver);
     this.intermediate = intermediate;
@@ -698,7 +698,10 @@
 
     internal.configureAndroidPlatformBuild(getAndroidPlatformBuild());
 
-    internal.getArtProfileOptions().setArtProfileInputs(getArtProfileInputs()).setPassthrough(true);
+    internal
+        .getArtProfileOptions()
+        .setArtProfilesForRewriting(getArtProfilesForRewriting())
+        .setPassthrough(true);
     internal.getStartupOptions().setStartupProfileProviders(getStartupProfileProviders());
 
     internal.programClassConflictResolver =
diff --git a/src/main/java/com/android/tools/r8/L8Command.java b/src/main/java/com/android/tools/r8/L8Command.java
index 123c7d3..783bab0 100644
--- a/src/main/java/com/android/tools/r8/L8Command.java
+++ b/src/main/java/com/android/tools/r8/L8Command.java
@@ -14,6 +14,7 @@
 import com.android.tools.r8.inspector.Inspector;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecification;
 import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.profile.art.ArtProfileForRewriting;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.AssertionConfigurationWithDefault;
@@ -372,8 +373,12 @@
                 .setMode(getMode())
                 .setIncludeClassesChecksum(getIncludeClassesChecksum())
                 .setDexClassChecksumFilter(getDexClassChecksumFilter())
-                .setProgramConsumer(getProgramConsumer())
-                .addArtProfileInputs(getArtProfileInputs());
+                .setProgramConsumer(getProgramConsumer());
+        for (ArtProfileForRewriting artProfileForRewriting : getArtProfilesForRewriting()) {
+          r8Builder.addArtProfileForRewriting(
+              artProfileForRewriting.getArtProfileProvider(),
+              artProfileForRewriting.getResidualArtProfileConsumer());
+        }
         for (ClassFileResourceProvider libraryResourceProvider :
             inputs.getLibraryResourceProviders()) {
           r8Builder.addLibraryResourceProvider(libraryResourceProvider);
@@ -404,8 +409,12 @@
                 .setMode(getMode())
                 .setIncludeClassesChecksum(getIncludeClassesChecksum())
                 .setDexClassChecksumFilter(getDexClassChecksumFilter())
-                .setProgramConsumer(getProgramConsumer())
-                .addArtProfileInputs(getArtProfileInputs());
+                .setProgramConsumer(getProgramConsumer());
+        for (ArtProfileForRewriting artProfileForRewriting : getArtProfilesForRewriting()) {
+          d8Builder.addArtProfileForRewriting(
+              artProfileForRewriting.getArtProfileProvider(),
+              artProfileForRewriting.getResidualArtProfileConsumer());
+        }
         for (ClassFileResourceProvider libraryResourceProvider :
             inputs.getLibraryResourceProviders()) {
           d8Builder.addLibraryResourceProvider(libraryResourceProvider);
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index 55963a2..8e5a0ec 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -18,7 +18,7 @@
 import com.android.tools.r8.naming.SourceFileRewriter;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.origin.PathOrigin;
-import com.android.tools.r8.profile.art.ArtProfileInput;
+import com.android.tools.r8.profile.art.ArtProfileForRewriting;
 import com.android.tools.r8.shaking.ProguardConfiguration;
 import com.android.tools.r8.shaking.ProguardConfigurationParser;
 import com.android.tools.r8.shaking.ProguardConfigurationParserOptions;
@@ -663,7 +663,7 @@
               getSourceFileProvider(),
               enableMissingLibraryApiModeling,
               getAndroidPlatformBuild(),
-              getArtProfileInputs(),
+              getArtProfilesForRewriting(),
               getStartupProfileProviders(),
               getClassConflictResolver());
 
@@ -852,7 +852,7 @@
       SourceFileProvider sourceFileProvider,
       boolean enableMissingLibraryApiModeling,
       boolean isAndroidPlatformBuild,
-      List<ArtProfileInput> artProfileInputs,
+      List<ArtProfileForRewriting> artProfilesForRewriting,
       List<StartupProfileProvider> startupProfileProviders,
       ClassConflictResolver classConflictResolver) {
     super(
@@ -873,7 +873,7 @@
         mapIdProvider,
         sourceFileProvider,
         isAndroidPlatformBuild,
-        artProfileInputs,
+        artProfilesForRewriting,
         startupProfileProviders,
         classConflictResolver);
     assert proguardConfiguration != null;
@@ -1075,7 +1075,7 @@
 
     internal.configureAndroidPlatformBuild(getAndroidPlatformBuild());
 
-    internal.getArtProfileOptions().setArtProfileInputs(getArtProfileInputs());
+    internal.getArtProfileOptions().setArtProfilesForRewriting(getArtProfilesForRewriting());
     internal.getStartupOptions().setStartupProfileProviders(getStartupProfileProviders());
 
     internal.programClassConflictResolver =
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfile.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfile.java
index 37b9011..f4418ba 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfile.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfile.java
@@ -42,7 +42,7 @@
         (methodRule, builderFactory) ->
             builderFactory
                 .apply(lens.getRenamedMethodSignature(methodRule.getMethod()))
-                .internalSetMethodRuleInfo(
+                .acceptMethodRuleInfoBuilder(
                     methodRuleInfoBuilder ->
                         methodRuleInfoBuilder.merge(methodRule.getMethodRuleInfo())));
   }
@@ -55,7 +55,7 @@
         (methodRule, builderFactory) ->
             builderFactory
                 .apply(lens.lookupMethod(methodRule.getMethod(), dexItemFactory))
-                .internalSetMethodRuleInfo(
+                .acceptMethodRuleInfoBuilder(
                     methodRuleInfoBuilder ->
                         methodRuleInfoBuilder.merge(methodRule.getMethodRuleInfo())));
   }
@@ -71,7 +71,7 @@
           if (!prunedItems.isRemoved(methodRule.getMethod())) {
             builderFactory
                 .apply(methodRule.getMethod())
-                .internalSetMethodRuleInfo(
+                .acceptMethodRuleInfoBuilder(
                     methodRuleInfoBuilder ->
                         methodRuleInfoBuilder.merge(methodRule.getMethodRuleInfo()));
           }
@@ -116,9 +116,9 @@
     return new ArtProfile(newRules.build());
   }
 
-  public void supplyConsumer(ResidualArtProfileConsumer consumer, Reporter reporter) {
+  public void supplyConsumer(ArtProfileConsumer consumer, Reporter reporter) {
     if (consumer != null) {
-      ResidualArtProfileRuleConsumer ruleConsumer = consumer.getRuleConsumer();
+      ArtProfileRuleConsumer ruleConsumer = consumer.getRuleConsumer();
       if (ruleConsumer != null) {
         for (ArtProfileRule rule : rules) {
           rule.accept(
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileBuilder.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileBuilder.java
index 930aade..d5af9c8 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileBuilder.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileBuilder.java
@@ -4,10 +4,11 @@
 
 package com.android.tools.r8.profile.art;
 
+import com.android.tools.r8.Keep;
 import java.util.function.Consumer;
 
 /** API for building an ART profile. */
-// TODO(b/237043695): @Keep this when adding a public API for passing ART profiles to the compiler.
+@Keep
 public interface ArtProfileBuilder {
 
   ArtProfileBuilder addClassRule(Consumer<ArtProfileClassRuleBuilder> classRuleBuilderConsumer);
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileClassRuleBuilder.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileClassRuleBuilder.java
index 6f02da7..eaeab93 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileClassRuleBuilder.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileClassRuleBuilder.java
@@ -4,10 +4,11 @@
 
 package com.android.tools.r8.profile.art;
 
+import com.android.tools.r8.Keep;
 import com.android.tools.r8.references.ClassReference;
 
 /** API for defining a class rule for an ART profile. */
-// TODO(b/237043695): @Keep this when adding a public API for passing ART profiles to the compiler.
+@Keep
 public interface ArtProfileClassRuleBuilder {
 
   ArtProfileClassRuleBuilder setClassReference(ClassReference classReference);
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileCollection.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileCollection.java
index 1d7c009..16b2d44 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileCollection.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileCollection.java
@@ -18,17 +18,19 @@
 
   public static ArtProfileCollection createInitialArtProfileCollection(InternalOptions options) {
     ArtProfileOptions artProfileOptions = options.getArtProfileOptions();
-    Collection<ArtProfileInput> artProfileInputs = artProfileOptions.getArtProfileInputs();
-    if (artProfileInputs.isEmpty()) {
+    Collection<ArtProfileForRewriting> artProfilesForRewriting =
+        artProfileOptions.getArtProfilesForRewriting();
+    if (artProfilesForRewriting.isEmpty()) {
       return empty();
     }
     if (artProfileOptions.isPassthrough()) {
       return passthrough();
     }
-    List<ArtProfile> artProfiles = new ArrayList<>(artProfileInputs.size());
-    for (ArtProfileInput input : options.getArtProfileOptions().getArtProfileInputs()) {
+    List<ArtProfile> artProfiles = new ArrayList<>(artProfilesForRewriting.size());
+    for (ArtProfileForRewriting input :
+        options.getArtProfileOptions().getArtProfilesForRewriting()) {
       ArtProfile.Builder artProfileBuilder = ArtProfile.builder(options.dexItemFactory());
-      input.getArtProfile(artProfileBuilder);
+      input.getArtProfileProvider().getArtProfile(artProfileBuilder);
       artProfiles.add(artProfileBuilder.build());
     }
     return new NonEmptyArtProfileCollection(artProfiles);
diff --git a/src/main/java/com/android/tools/r8/profile/art/ResidualArtProfileConsumer.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileConsumer.java
similarity index 65%
rename from src/main/java/com/android/tools/r8/profile/art/ResidualArtProfileConsumer.java
rename to src/main/java/com/android/tools/r8/profile/art/ArtProfileConsumer.java
index fc8183e..6cc123d 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ResidualArtProfileConsumer.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileConsumer.java
@@ -5,19 +5,20 @@
 package com.android.tools.r8.profile.art;
 
 import com.android.tools.r8.DiagnosticsHandler;
+import com.android.tools.r8.Keep;
 
 /**
  * API for consuming an ART profile provided by the compiler, which has been rewritten to match the
  * residual, optimized app.
  */
-// TODO(b/237043695): @Keep this when adding a public API for passing ART profiles to the compiler.
-public interface ResidualArtProfileConsumer {
+@Keep
+public interface ArtProfileConsumer {
 
   /**
-   * Returns an {@link ResidualArtProfileRuleConsumer} that will receive the rules of the residual
-   * ART profile. If this returns <code>null</code> no rules will be emitted.
+   * Returns an {@link ArtProfileRuleConsumer} that will receive the rules of the residual ART
+   * profile. If this returns <code>null</code> no rules will be emitted.
    */
-  default ResidualArtProfileRuleConsumer getRuleConsumer() {
+  default ArtProfileRuleConsumer getRuleConsumer() {
     return null;
   }
 
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileForRewriting.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileForRewriting.java
new file mode 100644
index 0000000..7065f86
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileForRewriting.java
@@ -0,0 +1,31 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.profile.art;
+
+/** Internal pair of an {@link ArtProfileProvider} and {@link ArtProfileConsumer}. */
+public class ArtProfileForRewriting {
+
+  private final ArtProfileProvider artProfileProvider;
+  private final ArtProfileConsumer residualArtProfileConsumer;
+
+  public ArtProfileForRewriting(
+      ArtProfileProvider artProfileProvider, ArtProfileConsumer residualArtProfileConsumer) {
+    this.artProfileProvider = artProfileProvider;
+    this.residualArtProfileConsumer = residualArtProfileConsumer;
+  }
+
+  /** Specifies a provider that performs callbacks to a given {@link ArtProfileBuilder}. */
+  public ArtProfileProvider getArtProfileProvider() {
+    return artProfileProvider;
+  }
+
+  /**
+   * Specifies a consumer that should receive the ART profile after it has been rewritten to match
+   * the residual, optimized application.
+   */
+  public ArtProfileConsumer getResidualArtProfileConsumer() {
+    return residualArtProfileConsumer;
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileInput.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileInput.java
deleted file mode 100644
index 74d0685..0000000
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileInput.java
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.profile.art;
-
-/**
- * Top-level API for supplying an ART profile to the compiler and retrieving the ART profile after
- * the profile has been rewritten to match the residual, optimized application.
- */
-// TODO(b/237043695): @Keep this when adding a public API for passing ART profiles to the compiler.
-public interface ArtProfileInput {
-
-  /**
-   * Specifies a consumer that should receive the ART profile after it has been rewritten to match
-   * the residual, optimized application.
-   */
-  // TODO(b/237043695): If this ends up in the public API, maybe rename this method to
-  //  getResidualArtProfileConsumer() and ResidualArtProfileConsumer to ArtProfileConsumer.
-  ResidualArtProfileConsumer getArtProfileConsumer();
-
-  /** Provides the ART profile by performing callbacks to the given {@param profileBuilder}. */
-  void getArtProfile(ArtProfileBuilder profileBuilder);
-}
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRule.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRule.java
index 2a1f840..57e0639 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRule.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRule.java
@@ -122,11 +122,11 @@
     @Override
     public Builder setMethodRuleInfo(
         Consumer<ArtProfileMethodRuleInfoBuilder> methodRuleInfoBuilderConsumer) {
-      internalSetMethodRuleInfo(methodRuleInfoBuilderConsumer);
-      return this;
+      methodRuleInfoBuilder.clear();
+      return acceptMethodRuleInfoBuilder(methodRuleInfoBuilderConsumer);
     }
 
-    public Builder internalSetMethodRuleInfo(
+    public Builder acceptMethodRuleInfoBuilder(
         Consumer<? super ArtProfileMethodRuleInfoImpl.Builder> methodRuleInfoBuilderConsumer) {
       methodRuleInfoBuilderConsumer.accept(methodRuleInfoBuilder);
       return this;
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleBuilder.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleBuilder.java
index 99c7888..4bae3b3 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleBuilder.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleBuilder.java
@@ -4,11 +4,12 @@
 
 package com.android.tools.r8.profile.art;
 
+import com.android.tools.r8.Keep;
 import com.android.tools.r8.references.MethodReference;
 import java.util.function.Consumer;
 
 /** API for defining a method rule for an ART profile. */
-// TODO(b/237043695): @Keep this when adding a public API for passing ART profiles to the compiler.
+@Keep
 public interface ArtProfileMethodRuleBuilder {
 
   ArtProfileMethodRuleBuilder setMethodReference(MethodReference methodReference);
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleInfoBuilder.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleInfoBuilder.java
index a3a4041..11f8b42 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleInfoBuilder.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleInfoBuilder.java
@@ -4,8 +4,10 @@
 
 package com.android.tools.r8.profile.art;
 
+import com.android.tools.r8.Keep;
+
 /** API for providing metadata related to a method rule for an ART profile. */
-// TODO(b/237043695): @Keep this when adding a public API for passing ART profiles to the compiler.
+@Keep
 public interface ArtProfileMethodRuleInfoBuilder {
 
   ArtProfileMethodRuleInfoBuilder setIsHot(boolean isHot);
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleInfoImpl.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleInfoImpl.java
index 7bf5d15..046a20e 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleInfoImpl.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRuleInfoImpl.java
@@ -77,6 +77,11 @@
 
     private int flags;
 
+    Builder clear() {
+      flags = 0;
+      return this;
+    }
+
     public Builder merge(ArtProfileMethodRuleInfo methodRuleInfo) {
       if (methodRuleInfo.isHot()) {
         setIsHot();
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileOptions.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileOptions.java
index accab43..231a2d6 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileOptions.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileOptions.java
@@ -9,17 +9,17 @@
 
 public class ArtProfileOptions {
 
-  private Collection<ArtProfileInput> inputs = Collections.emptyList();
+  private Collection<ArtProfileForRewriting> artProfilesForRewriting = Collections.emptyList();
   private boolean passthrough;
 
   public ArtProfileOptions() {}
 
-  public Collection<ArtProfileInput> getArtProfileInputs() {
-    return inputs;
+  public Collection<ArtProfileForRewriting> getArtProfilesForRewriting() {
+    return artProfilesForRewriting;
   }
 
-  public ArtProfileOptions setArtProfileInputs(Collection<ArtProfileInput> inputs) {
-    this.inputs = inputs;
+  public ArtProfileOptions setArtProfilesForRewriting(Collection<ArtProfileForRewriting> inputs) {
+    this.artProfilesForRewriting = inputs;
     return this;
   }
 
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileProvider.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileProvider.java
new file mode 100644
index 0000000..87450e5
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileProvider.java
@@ -0,0 +1,15 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.profile.art;
+
+import com.android.tools.r8.Keep;
+import com.android.tools.r8.Resource;
+
+/** API for providing an ART profile to the compiler. */
+@Keep
+public interface ArtProfileProvider extends Resource {
+
+  void getArtProfile(ArtProfileBuilder profileBuilder);
+}
diff --git a/src/main/java/com/android/tools/r8/profile/art/ResidualArtProfileRuleConsumer.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileRuleConsumer.java
similarity index 86%
rename from src/main/java/com/android/tools/r8/profile/art/ResidualArtProfileRuleConsumer.java
rename to src/main/java/com/android/tools/r8/profile/art/ArtProfileRuleConsumer.java
index ae1e950..beab144 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ResidualArtProfileRuleConsumer.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileRuleConsumer.java
@@ -4,6 +4,7 @@
 
 package com.android.tools.r8.profile.art;
 
+import com.android.tools.r8.Keep;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.MethodReference;
 
@@ -12,8 +13,8 @@
  * #acceptClassRule} and {@link #acceptMethodRule} for each class and method rule (respectively) in
  * the profile.
  */
-// TODO(b/237043695): @Keep this when adding a public API for passing ART profiles to the compiler.
-public interface ResidualArtProfileRuleConsumer {
+@Keep
+public interface ArtProfileRuleConsumer {
 
   /** Provides information about a specific class rule to the consumer. */
   void acceptClassRule(ClassReference classReference, ArtProfileClassRuleInfo classRuleInfo);
diff --git a/src/main/java/com/android/tools/r8/profile/art/EmptyArtProfileCollection.java b/src/main/java/com/android/tools/r8/profile/art/EmptyArtProfileCollection.java
index c3b420c..f0313ef 100644
--- a/src/main/java/com/android/tools/r8/profile/art/EmptyArtProfileCollection.java
+++ b/src/main/java/com/android/tools/r8/profile/art/EmptyArtProfileCollection.java
@@ -32,7 +32,7 @@
 
   @Override
   public void supplyConsumers(AppView<?> appView) {
-    assert appView.options().getArtProfileOptions().getArtProfileInputs().isEmpty();
+    assert appView.options().getArtProfileOptions().getArtProfilesForRewriting().isEmpty();
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/profile/art/NonEmptyArtProfileCollection.java b/src/main/java/com/android/tools/r8/profile/art/NonEmptyArtProfileCollection.java
index 56c9683..e3cbaf7 100644
--- a/src/main/java/com/android/tools/r8/profile/art/NonEmptyArtProfileCollection.java
+++ b/src/main/java/com/android/tools/r8/profile/art/NonEmptyArtProfileCollection.java
@@ -42,13 +42,14 @@
             ? this
             : rewrittenWithLens(appView.getNamingLens(), appView.dexItemFactory());
     InternalOptions options = appView.options();
-    Collection<ArtProfileInput> inputs = options.getArtProfileOptions().getArtProfileInputs();
+    Collection<ArtProfileForRewriting> inputs =
+        options.getArtProfileOptions().getArtProfilesForRewriting();
     assert !inputs.isEmpty();
     assert collection.artProfiles.size() == inputs.size();
-    Iterator<ArtProfileInput> inputIterator = inputs.iterator();
+    Iterator<ArtProfileForRewriting> inputIterator = inputs.iterator();
     for (ArtProfile artProfile : collection.artProfiles) {
-      ArtProfileInput input = inputIterator.next();
-      artProfile.supplyConsumer(input.getArtProfileConsumer(), options.reporter);
+      ArtProfileForRewriting input = inputIterator.next();
+      artProfile.supplyConsumer(input.getResidualArtProfileConsumer(), options.reporter);
     }
   }
 
diff --git a/src/main/java/com/android/tools/r8/profile/art/PassthroughArtProfileCollection.java b/src/main/java/com/android/tools/r8/profile/art/PassthroughArtProfileCollection.java
index 0ca22c0..0b7e0ac 100644
--- a/src/main/java/com/android/tools/r8/profile/art/PassthroughArtProfileCollection.java
+++ b/src/main/java/com/android/tools/r8/profile/art/PassthroughArtProfileCollection.java
@@ -36,16 +36,18 @@
 
   @Override
   public void supplyConsumers(AppView<?> appView) {
-    for (ArtProfileInput artProfileInput :
-        appView.options().getArtProfileOptions().getArtProfileInputs()) {
-      ResidualArtProfileConsumer artProfileConsumer = artProfileInput.getArtProfileConsumer();
+    for (ArtProfileForRewriting artProfileForRewriting :
+        appView.options().getArtProfileOptions().getArtProfilesForRewriting()) {
+      ArtProfileConsumer artProfileConsumer =
+          artProfileForRewriting.getResidualArtProfileConsumer();
       if (artProfileConsumer == null) {
         continue;
       }
 
-      ResidualArtProfileRuleConsumer ruleConsumer = artProfileConsumer.getRuleConsumer();
+      ArtProfileRuleConsumer ruleConsumer = artProfileConsumer.getRuleConsumer();
       if (ruleConsumer != null) {
-        artProfileInput.getArtProfile(
+        ArtProfileProvider artProfileProvider = artProfileForRewriting.getArtProfileProvider();
+        artProfileProvider.getArtProfile(
             new ArtProfileBuilder() {
 
               @Override
diff --git a/src/test/java/com/android/tools/r8/D8TestBuilder.java b/src/test/java/com/android/tools/r8/D8TestBuilder.java
index 5c492f7..ad5ba5e 100644
--- a/src/test/java/com/android/tools/r8/D8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/D8TestBuilder.java
@@ -7,7 +7,8 @@
 import com.android.tools.r8.TestBase.Backend;
 import com.android.tools.r8.benchmarks.BenchmarkResults;
 import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.profile.art.ArtProfileInput;
+import com.android.tools.r8.profile.art.ArtProfileConsumer;
+import com.android.tools.r8.profile.art.ArtProfileProvider;
 import com.android.tools.r8.startup.StartupProfileProvider;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.InternalOptions;
@@ -131,13 +132,9 @@
     return self();
   }
 
-  public D8TestBuilder addArtProfileInputs(ArtProfileInput... artProfileInputs) {
-    builder.addArtProfileInputs(artProfileInputs);
-    return self();
-  }
-
-  public D8TestBuilder addArtProfileInputs(Collection<ArtProfileInput> artProfileInputs) {
-    builder.addArtProfileInputs(artProfileInputs);
+  public D8TestBuilder addArtProfileForRewriting(
+      ArtProfileProvider artProfileProvider, ArtProfileConsumer residualArtProfileConsumer) {
+    builder.addArtProfileForRewriting(artProfileProvider, residualArtProfileConsumer);
     return self();
   }
 
diff --git a/src/test/java/com/android/tools/r8/L8TestBuilder.java b/src/test/java/com/android/tools/r8/L8TestBuilder.java
index e5cb212..4a22769 100644
--- a/src/test/java/com/android/tools/r8/L8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/L8TestBuilder.java
@@ -11,7 +11,8 @@
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecification;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecificationParser;
 import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.profile.art.ArtProfileInput;
+import com.android.tools.r8.profile.art.ArtProfileConsumer;
+import com.android.tools.r8.profile.art.ArtProfileProvider;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidAppConsumers;
 import com.android.tools.r8.utils.ConsumerUtils;
@@ -267,13 +268,9 @@
     return libraryFiles;
   }
 
-  public L8TestBuilder addArtProfileInputs(ArtProfileInput... artProfileInputs) {
-    l8Builder.addArtProfileInputs(artProfileInputs);
-    return this;
-  }
-
-  public L8TestBuilder addArtProfileInputs(Collection<ArtProfileInput> artProfileInputs) {
-    l8Builder.addArtProfileInputs(artProfileInputs);
+  public L8TestBuilder addArtProfileForRewriting(
+      ArtProfileProvider artProfileProvider, ArtProfileConsumer residualArtProfileConsumer) {
+    l8Builder.addArtProfileForRewriting(artProfileProvider, residualArtProfileConsumer);
     return this;
   }
 }
diff --git a/src/test/java/com/android/tools/r8/R8TestBuilder.java b/src/test/java/com/android/tools/r8/R8TestBuilder.java
index 1cecce2..eb06bee 100644
--- a/src/test/java/com/android/tools/r8/R8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/R8TestBuilder.java
@@ -15,7 +15,8 @@
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.experimental.graphinfo.GraphConsumer;
 import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.profile.art.ArtProfileInput;
+import com.android.tools.r8.profile.art.ArtProfileConsumer;
+import com.android.tools.r8.profile.art.ArtProfileProvider;
 import com.android.tools.r8.shaking.CheckEnumUnboxedRule;
 import com.android.tools.r8.shaking.CollectingGraphConsumer;
 import com.android.tools.r8.shaking.KeepUnusedReturnValueRule;
@@ -779,13 +780,9 @@
     return self();
   }
 
-  public T addArtProfileInputs(ArtProfileInput... artProfileInputs) {
-    builder.addArtProfileInputs(artProfileInputs);
-    return self();
-  }
-
-  public T addArtProfileInputs(Collection<ArtProfileInput> artProfileInputs) {
-    builder.addArtProfileInputs(artProfileInputs);
+  public T addArtProfileForRewriting(
+      ArtProfileProvider artProfileProvider, ArtProfileConsumer residualArtProfileConsumer) {
+    builder.addArtProfileForRewriting(artProfileProvider, residualArtProfileConsumer);
     return self();
   }
 
diff --git a/src/test/java/com/android/tools/r8/compilerapi/CompilerApiTestCollection.java b/src/test/java/com/android/tools/r8/compilerapi/CompilerApiTestCollection.java
index 092d2ad..73dbba2 100644
--- a/src/test/java/com/android/tools/r8/compilerapi/CompilerApiTestCollection.java
+++ b/src/test/java/com/android/tools/r8/compilerapi/CompilerApiTestCollection.java
@@ -9,6 +9,7 @@
 
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.compilerapi.androidplatformbuild.AndroidPlatformBuildApiTest;
+import com.android.tools.r8.compilerapi.artprofiles.ArtProfilesForRewritingApiTest;
 import com.android.tools.r8.compilerapi.assertionconfiguration.AssertionConfigurationTest;
 import com.android.tools.r8.compilerapi.classconflictresolver.ClassConflictResolverTest;
 import com.android.tools.r8.compilerapi.desugardependencies.DesugarDependenciesTest;
@@ -53,7 +54,9 @@
 
   private static final List<Class<? extends CompilerApiTest>> CLASSES_PENDING_BINARY_COMPATIBILITY =
       ImmutableList.of(
-          StartupProfileApiTest.ApiTest.class, ClassConflictResolverTest.ApiTest.class);
+          ArtProfilesForRewritingApiTest.ApiTest.class,
+          StartupProfileApiTest.ApiTest.class,
+          ClassConflictResolverTest.ApiTest.class);
 
   private final TemporaryFolder temp;
 
diff --git a/src/test/java/com/android/tools/r8/compilerapi/artprofiles/ArtProfilesForRewritingApiTest.java b/src/test/java/com/android/tools/r8/compilerapi/artprofiles/ArtProfilesForRewritingApiTest.java
new file mode 100644
index 0000000..dbdddf7
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/compilerapi/artprofiles/ArtProfilesForRewritingApiTest.java
@@ -0,0 +1,213 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.compilerapi.artprofiles;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.r8.D8;
+import com.android.tools.r8.D8Command;
+import com.android.tools.r8.DexIndexedConsumer;
+import com.android.tools.r8.DiagnosticsHandler;
+import com.android.tools.r8.R8;
+import com.android.tools.r8.R8Command;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.compilerapi.CompilerApiTest;
+import com.android.tools.r8.compilerapi.CompilerApiTestRunner;
+import com.android.tools.r8.compilerapi.artprofiles.ArtProfilesForRewritingApiTest.ApiTest.ArtProfileConsumerForTesting;
+import com.android.tools.r8.compilerapi.mockdata.MockClass;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.profile.art.ArtProfileBuilder;
+import com.android.tools.r8.profile.art.ArtProfileClassRuleInfo;
+import com.android.tools.r8.profile.art.ArtProfileConsumer;
+import com.android.tools.r8.profile.art.ArtProfileMethodRuleInfo;
+import com.android.tools.r8.profile.art.ArtProfileProvider;
+import com.android.tools.r8.profile.art.ArtProfileRuleConsumer;
+import com.android.tools.r8.references.ClassReference;
+import com.android.tools.r8.references.MethodReference;
+import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.utils.ThrowingConsumer;
+import com.google.common.collect.Lists;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.junit.Test;
+
+public class ArtProfilesForRewritingApiTest extends CompilerApiTestRunner {
+
+  private static final int SOME_API_LEVEL = 24;
+
+  public ArtProfilesForRewritingApiTest(TestParameters parameters) {
+    super(parameters);
+  }
+
+  @Override
+  public Class<? extends CompilerApiTest> binaryTestClass() {
+    return ApiTest.class;
+  }
+
+  @Test
+  public void testD8() throws Exception {
+    ApiTest test = new ApiTest(ApiTest.PARAMETERS);
+    runTest(test::runD8);
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    ApiTest test = new ApiTest(ApiTest.PARAMETERS);
+    runTest(test::runR8);
+  }
+
+  private void runTest(ThrowingConsumer<ArtProfileConsumerForTesting, Exception> testRunner)
+      throws Exception {
+    ArtProfileConsumerForTesting artProfileConsumer = new ArtProfileConsumerForTesting();
+    testRunner.accept(artProfileConsumer);
+    assertTrue(artProfileConsumer.isFinished());
+    assertEquals(
+        Lists.newArrayList(
+            "Lcom/android/tools/r8/compilerapi/mockdata/MockClass;",
+            "PLcom/android/tools/r8/compilerapi/mockdata/MockClass;-><init>()V",
+            "HSPLcom/android/tools/r8/compilerapi/mockdata/MockClass;->main([Ljava/lang/String;)V"),
+        artProfileConsumer.getResidualArtProfileRules());
+  }
+
+  public static class ApiTest extends CompilerApiTest {
+
+    private static ClassReference mockClassReference = Reference.classFromClass(MockClass.class);
+    private static MethodReference mockInitMethodReference =
+        Reference.method(mockClassReference, "<init>", Collections.emptyList(), null);
+    private static MethodReference mockMainMethodReference =
+        Reference.method(
+            mockClassReference,
+            "main",
+            Collections.singletonList(Reference.classFromClass(String[].class)),
+            null);
+
+    public ApiTest(Object parameters) {
+      super(parameters);
+    }
+
+    public void runD8(ArtProfileConsumerForTesting artProfileConsumer) throws Exception {
+      ArtProfileProviderForTesting artProfileProvider = new ArtProfileProviderForTesting();
+      D8Command.Builder commandBuilder =
+          D8Command.builder()
+              .addClassProgramData(getBytesForClass(getMockClass()), Origin.unknown())
+              .addLibraryFiles(getJava8RuntimeJar())
+              .setMinApiLevel(SOME_API_LEVEL)
+              .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+              .addArtProfileForRewriting(artProfileProvider, artProfileConsumer);
+      D8.run(commandBuilder.build());
+    }
+
+    public void runR8(ArtProfileConsumerForTesting artProfileConsumer) throws Exception {
+      ArtProfileProviderForTesting artProfileProvider = new ArtProfileProviderForTesting();
+      R8Command.Builder commandBuilder =
+          R8Command.builder()
+              .addClassProgramData(getBytesForClass(getMockClass()), Origin.unknown())
+              .addProguardConfiguration(
+                  Collections.singletonList("-keep class * { *; }"), Origin.unknown())
+              .addLibraryFiles(getJava8RuntimeJar())
+              .setMinApiLevel(SOME_API_LEVEL)
+              .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+              .addArtProfileForRewriting(artProfileProvider, artProfileConsumer);
+      R8.run(commandBuilder.build());
+    }
+
+    @Test
+    public void testD8() throws Exception {
+      runD8(null);
+    }
+
+    @Test
+    public void testR8() throws Exception {
+      runR8(null);
+    }
+
+    static class ArtProfileProviderForTesting implements ArtProfileProvider {
+
+      @Override
+      public void getArtProfile(ArtProfileBuilder profileBuilder) {
+        profileBuilder
+            .addClassRule(
+                classRuleBuilder -> classRuleBuilder.setClassReference(mockClassReference))
+            .addMethodRule(
+                methodRuleBuilder ->
+                    methodRuleBuilder
+                        .setMethodReference(mockInitMethodReference)
+                        .setMethodRuleInfo(
+                            methodRuleInfoBuilder -> methodRuleInfoBuilder.setIsHot(true))
+                        .setMethodRuleInfo(
+                            methodRuleInfoBuilder -> methodRuleInfoBuilder.setIsPostStartup(true)))
+            .addMethodRule(
+                methodRuleBuilder ->
+                    methodRuleBuilder
+                        .setMethodReference(mockMainMethodReference)
+                        .setMethodRuleInfo(
+                            methodRuleInfoBuilder ->
+                                methodRuleInfoBuilder
+                                    .setIsHot(true)
+                                    .setIsStartup(true)
+                                    .setIsPostStartup(true)));
+      }
+
+      @Override
+      public Origin getOrigin() {
+        return Origin.unknown();
+      }
+    }
+
+    static class ArtProfileConsumerForTesting implements ArtProfileConsumer {
+
+      private boolean finished;
+      private final List<String> residualArtProfileRules = new ArrayList<>();
+
+      @Override
+      public ArtProfileRuleConsumer getRuleConsumer() {
+        return new ArtProfileRuleConsumer() {
+
+          @Override
+          public void acceptClassRule(
+              ClassReference classReference, ArtProfileClassRuleInfo classRuleInfo) {
+            residualArtProfileRules.add(classReference.getDescriptor());
+          }
+
+          @Override
+          public void acceptMethodRule(
+              MethodReference methodReference, ArtProfileMethodRuleInfo methodRuleInfo) {
+            StringBuilder builder = new StringBuilder();
+            if (methodRuleInfo.isHot()) {
+              builder.append('H');
+            }
+            if (methodRuleInfo.isStartup()) {
+              builder.append('S');
+            }
+            if (methodRuleInfo.isPostStartup()) {
+              builder.append('P');
+            }
+            residualArtProfileRules.add(
+                builder
+                    .append(methodReference.getHolderClass().getDescriptor())
+                    .append("->")
+                    .append(methodReference.getMethodName())
+                    .append(methodReference.getMethodDescriptor())
+                    .toString());
+          }
+        };
+      }
+
+      @Override
+      public void finished(DiagnosticsHandler handler) {
+        finished = true;
+      }
+
+      List<String> getResidualArtProfileRules() {
+        return residualArtProfileRules;
+      }
+
+      boolean isFinished() {
+        return finished;
+      }
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestBuilder.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestBuilder.java
index 77e3488..e68c8bc 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestBuilder.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestBuilder.java
@@ -24,7 +24,9 @@
 import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase;
 import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase.KeepRuleConsumer;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecificationParser;
-import com.android.tools.r8.profile.art.ArtProfileInput;
+import com.android.tools.r8.profile.art.ArtProfileConsumer;
+import com.android.tools.r8.profile.art.ArtProfileForRewriting;
+import com.android.tools.r8.profile.art.ArtProfileProvider;
 import com.android.tools.r8.tracereferences.TraceReferences;
 import com.android.tools.r8.utils.ConsumerUtils;
 import com.android.tools.r8.utils.FileUtils;
@@ -35,7 +37,6 @@
 import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 import java.util.function.Consumer;
 import java.util.function.Function;
@@ -48,7 +49,7 @@
   private final LibraryDesugaringSpecification libraryDesugaringSpecification;
   private final CompilationSpecification compilationSpecification;
   private final TestCompilerBuilder<?, ?, ?, ? extends SingleTestRunResult<?>, ?> builder;
-  private List<ArtProfileInput> l8ArtProfileInputs = new ArrayList<>();
+  private List<ArtProfileForRewriting> l8ArtProfilesForRewriting = new ArrayList<>();
   private String l8ExtraKeepRules = "";
   private Consumer<InternalOptions> l8OptionModifier = ConsumerUtils.emptyConsumer();
   private boolean l8FinalPrefixVerification = true;
@@ -420,8 +421,12 @@
         .applyIf(
             compilationSpecification.isL8Shrink() && !backend.isCf() && !l8ExtraKeepRules.isEmpty(),
             b -> b.addKeepRules(l8ExtraKeepRules))
-        .addOptionsModifier(l8OptionModifier)
-        .addArtProfileInputs(l8ArtProfileInputs);
+        .addOptionsModifier(l8OptionModifier);
+    for (ArtProfileForRewriting artProfileForRewriting : l8ArtProfilesForRewriting) {
+      l8Builder.addArtProfileForRewriting(
+          artProfileForRewriting.getArtProfileProvider(),
+          artProfileForRewriting.getResidualArtProfileConsumer());
+    }
   }
 
   public String collectKeepRulesWithTraceReferences(
@@ -488,15 +493,10 @@
     return this;
   }
 
-  public DesugaredLibraryTestBuilder<?> addL8ArtProfileInputs(
-      ArtProfileInput... l8ArtProfileInputs) {
-    Collections.addAll(this.l8ArtProfileInputs, l8ArtProfileInputs);
-    return this;
-  }
-
-  public DesugaredLibraryTestBuilder<?> addL8ArtProfileInputs(
-      Collection<ArtProfileInput> l8ArtProfileInputs) {
-    this.l8ArtProfileInputs.addAll(l8ArtProfileInputs);
+  public DesugaredLibraryTestBuilder<?> addL8ArtProfileForRewriting(
+      ArtProfileProvider artProfileProvider, ArtProfileConsumer residualArtProfileConsumer) {
+    l8ArtProfilesForRewriting.add(
+        new ArtProfileForRewriting(artProfileProvider, residualArtProfileConsumer));
     return this;
   }
 }
diff --git a/src/test/java/com/android/tools/r8/profile/art/ArtProfileCollisionAfterClassMergingRewritingTest.java b/src/test/java/com/android/tools/r8/profile/art/ArtProfileCollisionAfterClassMergingRewritingTest.java
index f37483a..15ed09c 100644
--- a/src/test/java/com/android/tools/r8/profile/art/ArtProfileCollisionAfterClassMergingRewritingTest.java
+++ b/src/test/java/com/android/tools/r8/profile/art/ArtProfileCollisionAfterClassMergingRewritingTest.java
@@ -13,6 +13,7 @@
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.MethodReference;
 import com.android.tools.r8.references.Reference;
@@ -53,13 +54,12 @@
 
   @Test
   public void test() throws Exception {
-    ResidualArtProfileConsumerForTesting residualArtProfileConsumer =
-        new ResidualArtProfileConsumerForTesting();
-    MyArtProfileInput artProfileInput = new MyArtProfileInput(residualArtProfileConsumer);
+    MyArtProfileProvider artProfileProvider = new MyArtProfileProvider();
+    ArtProfileConsumerForTesting residualArtProfileConsumer = new ArtProfileConsumerForTesting();
     testForR8(Backend.DEX)
         .addInnerClasses(getClass())
         .addKeepMainRule(Main.class)
-        .addArtProfileInputs(artProfileInput)
+        .addArtProfileForRewriting(artProfileProvider, residualArtProfileConsumer)
         .addHorizontallyMergedClassesInspector(
             inspector ->
                 inspector.assertMergedInto(Foo.class, Bar.class).assertNoOtherClassesMerged())
@@ -70,7 +70,7 @@
   }
 
   private void inspect(
-      CodeInspector inspector, ResidualArtProfileConsumerForTesting residualArtProfileConsumer) {
+      CodeInspector inspector, ArtProfileConsumerForTesting residualArtProfileConsumer) {
     ClassSubject barClassSubject = inspector.clazz(Bar.class);
     assertThat(barClassSubject, isPresentAndRenamed());
 
@@ -99,18 +99,7 @@
         residualArtProfileConsumer.infos);
   }
 
-  static class MyArtProfileInput implements ArtProfileInput {
-
-    private final ResidualArtProfileConsumerForTesting residualArtProfileConsumer;
-
-    MyArtProfileInput(ResidualArtProfileConsumerForTesting residualArtProfileConsumer) {
-      this.residualArtProfileConsumer = residualArtProfileConsumer;
-    }
-
-    @Override
-    public ResidualArtProfileConsumer getArtProfileConsumer() {
-      return residualArtProfileConsumer;
-    }
+  static class MyArtProfileProvider implements ArtProfileProvider {
 
     @Override
     public void getArtProfile(ArtProfileBuilder profileBuilder) {
@@ -125,6 +114,11 @@
           .addMethodRule(
               methodRuleBuilder -> methodRuleBuilder.setMethodReference(worldMethodReference));
     }
+
+    @Override
+    public Origin getOrigin() {
+      return Origin.unknown();
+    }
   }
 
   static class Main {
diff --git a/src/test/java/com/android/tools/r8/profile/art/ResidualArtProfileConsumerForTesting.java b/src/test/java/com/android/tools/r8/profile/art/ArtProfileConsumerForTesting.java
similarity index 85%
rename from src/test/java/com/android/tools/r8/profile/art/ResidualArtProfileConsumerForTesting.java
rename to src/test/java/com/android/tools/r8/profile/art/ArtProfileConsumerForTesting.java
index 9afc6da..2a0a041 100644
--- a/src/test/java/com/android/tools/r8/profile/art/ResidualArtProfileConsumerForTesting.java
+++ b/src/test/java/com/android/tools/r8/profile/art/ArtProfileConsumerForTesting.java
@@ -10,15 +10,15 @@
 import java.util.ArrayList;
 import java.util.List;
 
-public class ResidualArtProfileConsumerForTesting implements ResidualArtProfileConsumer {
+public class ArtProfileConsumerForTesting implements ArtProfileConsumer {
 
   boolean finished;
   List<Object> references = new ArrayList<>();
   List<Object> infos = new ArrayList<>();
 
   @Override
-  public ResidualArtProfileRuleConsumer getRuleConsumer() {
-    return new ResidualArtProfileRuleConsumer() {
+  public ArtProfileRuleConsumer getRuleConsumer() {
+    return new ArtProfileRuleConsumer() {
 
       @Override
       public void acceptClassRule(
diff --git a/src/test/java/com/android/tools/r8/profile/art/ArtProfilePassthroughTest.java b/src/test/java/com/android/tools/r8/profile/art/ArtProfilePassthroughTest.java
index 6fb97bd..b45ba38 100644
--- a/src/test/java/com/android/tools/r8/profile/art/ArtProfilePassthroughTest.java
+++ b/src/test/java/com/android/tools/r8/profile/art/ArtProfilePassthroughTest.java
@@ -11,7 +11,7 @@
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.profile.art.ArtProfileCollisionAfterClassMergingRewritingTest.Main;
+import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.MethodReference;
 import com.android.tools.r8.references.Reference;
@@ -49,68 +49,29 @@
 
   @Test
   public void testD8() throws Exception {
-    ArtProfileInputForTesting artProfileInput = new ArtProfileInputForTesting();
+    ArtProfileProviderForTesting artProfileProvider = new ArtProfileProviderForTesting();
+    ArtProfileConsumerForTesting residualArtProfileConsumer =
+        new ArtProfileConsumerForTesting(artProfileProvider);
     testForD8(Backend.DEX)
         .addProgramClasses(Main.class)
         // Add a profile provider and consumer that verifies that the profile is being provided at
         // the same time it is being consumed.
-        .addArtProfileInputs(artProfileInput)
+        .addArtProfileForRewriting(artProfileProvider, residualArtProfileConsumer)
         .release()
         .setMinApi(AndroidApiLevel.LATEST)
         .compile();
 
     // Verify that the profile input was processed.
-    assertEquals(ProviderStatus.DONE, artProfileInput.providerStatus);
-    assertTrue(artProfileInput.finished);
+    assertEquals(ProviderStatus.DONE, artProfileProvider.providerStatus);
+    assertTrue(residualArtProfileConsumer.finished);
     assertEquals(
-        Lists.newArrayList(mainClassReference, mainMethodReference), artProfileInput.references);
+        Lists.newArrayList(mainClassReference, mainMethodReference),
+        residualArtProfileConsumer.references);
   }
 
-  static class ArtProfileInputForTesting implements ArtProfileInput {
+  static class ArtProfileProviderForTesting implements ArtProfileProvider {
 
     ProviderStatus providerStatus = ProviderStatus.PENDING;
-    boolean finished;
-
-    List<Object> references = new ArrayList<>();
-
-    @Override
-    public ResidualArtProfileConsumer getArtProfileConsumer() {
-      return new ResidualArtProfileConsumer() {
-
-        @Override
-        public ResidualArtProfileRuleConsumer getRuleConsumer() {
-          // The compiler should not request to get the profile from the provider before getting the
-          // consumer.
-          assertTrue(providerStatus == ProviderStatus.PENDING);
-          return new ResidualArtProfileRuleConsumer() {
-            @Override
-            public void acceptClassRule(
-                ClassReference classReference, ArtProfileClassRuleInfo classRuleInfo) {
-              // The consumer should only be receiving callbacks while the profile is being
-              // provided.
-              assertTrue(providerStatus == ProviderStatus.ACTIVE);
-              references.add(classReference);
-            }
-
-            @Override
-            public void acceptMethodRule(
-                MethodReference methodReference, ArtProfileMethodRuleInfo methodRuleInfo) {
-              // The consumer should only be receiving callbacks while the profile is being
-              // provided.
-              assertTrue(providerStatus == ProviderStatus.ACTIVE);
-              references.add(methodReference);
-            }
-          };
-        }
-
-        @Override
-        public void finished(DiagnosticsHandler handler) {
-          // The profile should be fully provided when all data is given to the consumer.
-          assertTrue(providerStatus == ProviderStatus.DONE);
-          finished = true;
-        }
-      };
-    }
 
     @Override
     public void getArtProfile(ArtProfileBuilder profileBuilder) {
@@ -121,6 +82,56 @@
               methodRuleBuilder -> methodRuleBuilder.setMethodReference(mainMethodReference));
       providerStatus = ProviderStatus.DONE;
     }
+
+    @Override
+    public Origin getOrigin() {
+      return Origin.unknown();
+    }
+  }
+
+  static class ArtProfileConsumerForTesting implements ArtProfileConsumer {
+
+    private final ArtProfileProviderForTesting artProfileProvider;
+
+    List<Object> references = new ArrayList<>();
+    boolean finished;
+
+    ArtProfileConsumerForTesting(ArtProfileProviderForTesting artProfileProvider) {
+      this.artProfileProvider = artProfileProvider;
+    }
+
+    @Override
+    public ArtProfileRuleConsumer getRuleConsumer() {
+      // The compiler should not request to get the profile from the provider before getting the
+      // consumer.
+      assertTrue(artProfileProvider.providerStatus == ProviderStatus.PENDING);
+      return new ArtProfileRuleConsumer() {
+        @Override
+        public void acceptClassRule(
+            ClassReference classReference, ArtProfileClassRuleInfo classRuleInfo) {
+          // The consumer should only be receiving callbacks while the profile is being
+          // provided.
+          assertTrue(artProfileProvider.providerStatus == ProviderStatus.ACTIVE);
+          references.add(classReference);
+        }
+
+        @Override
+        public void acceptMethodRule(
+            MethodReference methodReference, ArtProfileMethodRuleInfo methodRuleInfo) {
+          // The consumer should only be receiving callbacks while the profile is being
+          // provided.
+          assertTrue(artProfileProvider.providerStatus == ProviderStatus.ACTIVE);
+          references.add(methodReference);
+        }
+      };
+    }
+
+    @Override
+    public void finished(DiagnosticsHandler handler) {
+      // The profile should be fully provided when all data is given to the consumer.
+      assertTrue(artProfileProvider.providerStatus == ProviderStatus.DONE);
+      finished = true;
+    }
   }
 
   static class Main {
diff --git a/src/test/java/com/android/tools/r8/profile/art/ArtProfileRewritingTest.java b/src/test/java/com/android/tools/r8/profile/art/ArtProfileRewritingTest.java
index 677308b..80bb288 100644
--- a/src/test/java/com/android/tools/r8/profile/art/ArtProfileRewritingTest.java
+++ b/src/test/java/com/android/tools/r8/profile/art/ArtProfileRewritingTest.java
@@ -13,6 +13,7 @@
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.MethodReference;
 import com.android.tools.r8.references.Reference;
@@ -50,13 +51,12 @@
 
   @Test
   public void test() throws Exception {
-    ResidualArtProfileConsumerForTesting residualArtProfileConsumer =
-        new ResidualArtProfileConsumerForTesting();
-    MyArtProfileInput artProfileInput = new MyArtProfileInput(residualArtProfileConsumer);
+    ArtProfileProviderForTesting artProfileProvider = new ArtProfileProviderForTesting();
+    ArtProfileConsumerForTesting residualArtProfileConsumer = new ArtProfileConsumerForTesting();
     testForR8(Backend.DEX)
         .addInnerClasses(getClass())
         .addKeepMainRule(Main.class)
-        .addArtProfileInputs(artProfileInput)
+        .addArtProfileForRewriting(artProfileProvider, residualArtProfileConsumer)
         .enableInliningAnnotations()
         .setMinApi(AndroidApiLevel.LATEST)
         .compile()
@@ -64,7 +64,7 @@
   }
 
   private void inspect(
-      CodeInspector inspector, ResidualArtProfileConsumerForTesting residualArtProfileConsumer) {
+      CodeInspector inspector, ArtProfileConsumerForTesting residualArtProfileConsumer) {
     ClassSubject greeterClassSubject = inspector.clazz(Greeter.class);
     assertThat(greeterClassSubject, isPresentAndRenamed());
 
@@ -88,18 +88,7 @@
         residualArtProfileConsumer.infos);
   }
 
-  static class MyArtProfileInput implements ArtProfileInput {
-
-    private final ResidualArtProfileConsumerForTesting residualArtProfileConsumer;
-
-    MyArtProfileInput(ResidualArtProfileConsumerForTesting residualArtProfileConsumer) {
-      this.residualArtProfileConsumer = residualArtProfileConsumer;
-    }
-
-    @Override
-    public ResidualArtProfileConsumer getArtProfileConsumer() {
-      return residualArtProfileConsumer;
-    }
+  static class ArtProfileProviderForTesting implements ArtProfileProvider {
 
     @Override
     public void getArtProfile(ArtProfileBuilder profileBuilder) {
@@ -121,6 +110,11 @@
                           methodRuleInfoBuilder ->
                               methodRuleInfoBuilder.setIsHot(true).setIsPostStartup(true)));
     }
+
+    @Override
+    public Origin getOrigin() {
+      return Origin.unknown();
+    }
   }
 
   static class Main {
diff --git a/src/test/java/com/android/tools/r8/profile/art/DesugaredLibraryArtProfileRewritingTest.java b/src/test/java/com/android/tools/r8/profile/art/DesugaredLibraryArtProfileRewritingTest.java
index 7846ba8..da88bc6 100644
--- a/src/test/java/com/android/tools/r8/profile/art/DesugaredLibraryArtProfileRewritingTest.java
+++ b/src/test/java/com/android/tools/r8/profile/art/DesugaredLibraryArtProfileRewritingTest.java
@@ -16,6 +16,7 @@
 import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase;
 import com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification;
 import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
+import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.references.MethodReference;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
@@ -55,14 +56,12 @@
   @Test
   public void test() throws Throwable {
     Assume.assumeTrue(libraryDesugaringSpecification.hasEmulatedInterfaceDesugaring(parameters));
-    ResidualArtProfileConsumerForTesting residualArtProfileConsumer =
-        new ResidualArtProfileConsumerForTesting();
-    ArtProfileInputForTesting artProfileInput =
-        new ArtProfileInputForTesting(residualArtProfileConsumer);
+    ArtProfileProviderForTesting artProfileProvider = new ArtProfileProviderForTesting();
+    ArtProfileConsumerForTesting residualArtProfileConsumer = new ArtProfileConsumerForTesting();
     testForDesugaredLibrary(parameters, libraryDesugaringSpecification, compilationSpecification)
         .addInnerClasses(getClass())
         .addKeepMainRule(Main.class)
-        .addL8ArtProfileInputs(artProfileInput)
+        .addL8ArtProfileForRewriting(artProfileProvider, residualArtProfileConsumer)
         .compile()
         .inspectL8(
             inspector -> {
@@ -94,18 +93,7 @@
         .assertSuccessWithOutputLines("0");
   }
 
-  class ArtProfileInputForTesting implements ArtProfileInput {
-
-    private final ResidualArtProfileConsumerForTesting residualArtProfileConsumer;
-
-    ArtProfileInputForTesting(ResidualArtProfileConsumerForTesting residualArtProfileConsumer) {
-      this.residualArtProfileConsumer = residualArtProfileConsumer;
-    }
-
-    @Override
-    public ResidualArtProfileConsumer getArtProfileConsumer() {
-      return residualArtProfileConsumer;
-    }
+  class ArtProfileProviderForTesting implements ArtProfileProvider {
 
     @Override
     public void getArtProfile(ArtProfileBuilder profileBuilder) {
@@ -121,6 +109,11 @@
       profileBuilder.addMethodRule(
           methodRuleBuilder -> methodRuleBuilder.setMethodReference(forEachMethodReference));
     }
+
+    @Override
+    public Origin getOrigin() {
+      return Origin.unknown();
+    }
   }
 
   static class Main {