Make sure desugaring already publicize private methods in interfaces.

Bug: 72109068
Change-Id: I131c054b948043f49ab06e35fd86b3edb4b134ed
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index 026c2b5..d234702 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -155,6 +155,9 @@
     return isVirtualMethod() && !accessFlags.isAbstract();
   }
 
+  public boolean isPublicMethod() {
+    return accessFlags.isPublic();
+  }
 
   public boolean isPrivateMethod() {
     return accessFlags.isPrivate();
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
index 73c5118..76a80d4 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
@@ -66,7 +66,7 @@
   // Public for testing.
   public static final String COMPANION_CLASS_NAME_SUFFIX = "$-CC";
   public static final String DEFAULT_METHOD_PREFIX = "$default$";
-  private static final String PRIVATE_METHOD_PREFIX = "$private$";
+  public static final String PRIVATE_METHOD_PREFIX = "$private$";
 
   private final IRConverter converter;
   private final InternalOptions options;
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
index 1e8d57a..f4a76e6 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
@@ -91,7 +91,7 @@
     remainingMethods.clear();
 
     // Process static and private methods, move them into companion class as well,
-    // make private instance methods static.
+    // make private instance methods public static.
     for (DexEncodedMethod direct : iface.directMethods()) {
       MethodAccessFlags originalFlags = direct.accessFlags;
       MethodAccessFlags newFlags = originalFlags.copy();
diff --git a/src/test/java/com/android/tools/r8/RunExamplesJava9Test.java b/src/test/java/com/android/tools/r8/RunExamplesJava9Test.java
index 9560c1f..60ebf39 100644
--- a/src/test/java/com/android/tools/r8/RunExamplesJava9Test.java
+++ b/src/test/java/com/android/tools/r8/RunExamplesJava9Test.java
@@ -4,28 +4,28 @@
 
 package com.android.tools.r8;
 
+import static com.android.tools.r8.utils.DexInspectorMatchers.isPresent;
 import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
 import static com.android.tools.r8.utils.FileUtils.ZIP_EXTENSION;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 
 import com.android.tools.r8.ToolHelper.DexVm;
-import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.ir.desugar.InterfaceMethodRewriter;
 import com.android.tools.r8.utils.AndroidApiLevel;
-import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.DexInspector;
+import com.android.tools.r8.utils.DexInspector.ClassSubject;
 import com.android.tools.r8.utils.DexInspector.FoundClassSubject;
 import com.android.tools.r8.utils.DexInspector.FoundMethodSubject;
 import com.android.tools.r8.utils.DexInspector.InstructionSubject;
+import com.android.tools.r8.utils.DexInspector.MethodSubject;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.OffOrAuto;
 import com.android.tools.r8.utils.TestDescriptionWatcher;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
-import com.google.common.io.ByteStreams;
 import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.ArrayList;
@@ -33,20 +33,17 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.ExecutionException;
 import java.util.function.Consumer;
 import java.util.function.Predicate;
 import java.util.function.UnaryOperator;
 import java.util.stream.Collectors;
-import java.util.zip.ZipException;
-import java.util.zip.ZipFile;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.junit.rules.TemporaryFolder;
 
 public abstract class RunExamplesJava9Test
-      <B extends BaseCommand.Builder<? extends BaseCommand, B>> {
+    <B extends BaseCommand.Builder<? extends BaseCommand, B>> {
   static final String EXAMPLE_DIR = ToolHelper.EXAMPLES_JAVA9_BUILD_DIR;
 
   abstract class TestRunner<C extends TestRunner<C>> {
@@ -99,10 +96,6 @@
       return self();
     }
 
-    C withMainDexClass(String... classes) {
-      return withBuilderTransformation(builder -> builder.addMainDexClasses(classes));
-    }
-
     C withInterfaceMethodDesugaring(OffOrAuto behavior) {
       return withOptionConsumer(o -> o.interfaceMethodDesugaring = behavior);
     }
@@ -111,15 +104,19 @@
       return withOptionConsumer(o -> o.tryWithResourcesDesugaring = behavior);
     }
 
+    void combinedOptionConsumer(InternalOptions options) {
+      for (Consumer<InternalOptions> consumer : optionConsumers) {
+        consumer.accept(options);
+      }
+    }
+
     C withBuilderTransformation(UnaryOperator<B> builderTransformation) {
       builderTransformations.add(builderTransformation);
       return self();
     }
 
-    void combinedOptionConsumer(InternalOptions options) {
-      for (Consumer<InternalOptions> consumer : optionConsumers) {
-        consumer.accept(options);
-      }
+    C withMainDexClass(String... classes) {
+      return withBuilderTransformation(builder -> builder.addMainDexClasses(classes));
     }
 
     Path build() throws Throwable {
@@ -179,19 +176,19 @@
     ImmutableMap.Builder<DexVm.Version, List<String>> builder = ImmutableMap.builder();
     builder
         .put(DexVm.Version.V4_0_4, ImmutableList.of(
-            "native-private-interface-methods",// Dex version not supported
+            "native-private-interface-methods", // Dex version not supported
             "varhandle"
         ))
         .put(DexVm.Version.V4_4_4, ImmutableList.of(
-            "native-private-interface-methods",// Dex version not supported
+            "native-private-interface-methods", // Dex version not supported
             "varhandle"
         ))
         .put(DexVm.Version.V5_1_1, ImmutableList.of(
-            "native-private-interface-methods",// Dex version not supported
+            "native-private-interface-methods", // Dex version not supported
             "varhandle"
         ))
-        .put(DexVm.Version.V6_0_1, ImmutableList.of("native-private-interface-methods",
-            // Dex version not supported
+        .put(DexVm.Version.V6_0_1, ImmutableList.of(
+            "native-private-interface-methods", // Dex version not supported
             "varhandle"
         ))
         .put(DexVm.Version.V7_0_0, ImmutableList.of(
@@ -208,12 +205,14 @@
   // Defines methods failing on JVM, specifies the output to be used for comparison.
   private static Map<String, String> expectedJvmResult =
       ImmutableMap.of(
-          "native-private-interface-methods", "0: s>i>a\n"
+          "native-private-interface-methods",
+          "0: s>i>a\n"
               + "1: d>i>s>i>a\n"
               + "2: l>i>s>i>a\n"
               + "3: x>s\n"
               + "4: c>d>i>s>i>a\n",
-          "desugared-private-interface-methods", "0: s>i>a\n"
+          "desugared-private-interface-methods",
+          "0: s>i>a\n"
               + "1: d>i>s>i>a\n"
               + "2: l>i>s>i>a\n"
               + "3: x>s\n"
@@ -245,21 +244,34 @@
 
   @Test
   public void nativePrivateInterfaceMethods() throws Throwable {
-    test("native-private-interface-methods", "privateinterfacemethods", "PrivateInterfaceMethods")
+    test("native-private-interface-methods",
+        "privateinterfacemethods", "PrivateInterfaceMethods")
         .withMinApiLevel(AndroidApiLevel.N.getLevel())
         .run();
   }
 
   @Test
   public void desugaredPrivateInterfaceMethods() throws Throwable {
-    test("desugared-private-interface-methods", "privateinterfacemethods",
-        "PrivateInterfaceMethods")
+    final String iName = "privateinterfacemethods.I";
+    test("desugared-private-interface-methods",
+        "privateinterfacemethods", "PrivateInterfaceMethods")
         .withMinApiLevel(AndroidApiLevel.M.getLevel())
+        .withDexCheck(dexInspector -> {
+          ClassSubject companion = dexInspector.clazz(
+              iName + InterfaceMethodRewriter.COMPANION_CLASS_NAME_SUFFIX);
+          assertThat(companion, isPresent());
+          MethodSubject iFoo = companion.method(
+              "java.lang.String",
+              InterfaceMethodRewriter.PRIVATE_METHOD_PREFIX + "iFoo",
+              ImmutableList.of(iName, "boolean"));
+          assertThat(iFoo, isPresent());
+          assertTrue(iFoo.getMethod().isPublicMethod());
+        })
         .run();
   }
 
   @Test
-  public void varHAndle() throws Throwable {
+  public void varHandle() throws Throwable {
     test("varhandle", "varhandle", "VarHandleTests")
         .withMinApiLevel(AndroidApiLevel.P.getLevel())
         .run();
@@ -285,7 +297,7 @@
       thrown.expect(Throwable.class);
     }
     String output = ToolHelper.runArtNoVerificationErrors(
-        Arrays.stream(dexes).map(path -> path.toString()).collect(Collectors.toList()),
+        Arrays.stream(dexes).map(Path::toString).collect(Collectors.toList()),
         qualifiedMainClass,
         null);
     String jvmResult = null;
@@ -308,17 +320,4 @@
     }
   }
 
-  protected DexInspector getMainDexInspector(Path zip)
-      throws ZipException, IOException, ExecutionException {
-    try (ZipFile zipFile = new ZipFile(zip.toFile(), StandardCharsets.UTF_8)) {
-      try (InputStream in =
-          zipFile.getInputStream(zipFile.getEntry(ToolHelper.DEFAULT_DEX_FILENAME))) {
-        return new DexInspector(
-            AndroidApp.builder()
-                .addDexProgramData(ByteStreams.toByteArray(in), Origin.unknown())
-                .build());
-      }
-    }
-  }
-
-}
+}
\ No newline at end of file