Account for non-public library methods in class merger

Bug: 203446070
Change-Id: Ifabf27e4ef78f727a9635c8421bf04019f58f4c4
diff --git a/src/main/java/com/android/tools/r8/graph/ImmediateProgramSubtypingInfo.java b/src/main/java/com/android/tools/r8/graph/ImmediateProgramSubtypingInfo.java
index 12044f5..7895b61 100644
--- a/src/main/java/com/android/tools/r8/graph/ImmediateProgramSubtypingInfo.java
+++ b/src/main/java/com/android/tools/r8/graph/ImmediateProgramSubtypingInfo.java
@@ -45,6 +45,13 @@
     return new ImmediateProgramSubtypingInfo(appView, immediateSubtypes);
   }
 
+  public void forEachImmediateSuperClass(DexClass clazz, Consumer<? super DexClass> consumer) {
+    forEachImmediateSuperClassMatching(
+        clazz,
+        (supertype, superclass) -> superclass != null,
+        (supertype, superclass) -> consumer.accept(superclass));
+  }
+
   public void forEachImmediateSuperClass(
       DexProgramClass clazz, BiConsumer<? super DexType, ? super DexClass> consumer) {
     forEachImmediateSuperClassMatching(clazz, (supertype, superclass) -> true, consumer);
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoWeakerAccessPrivileges.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoWeakerAccessPrivileges.java
index 399e807..600b5a8 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoWeakerAccessPrivileges.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoWeakerAccessPrivileges.java
@@ -31,6 +31,8 @@
       new IdentityHashMap<>();
   private final Map<Set<DexProgramClass>, DexMethodSignatureSet>
       nonPublicVirtualMethodSignaturesCache = new IdentityHashMap<>();
+  private final Map<DexClass, DexMethodSignatureSet> nonPublicVirtualLibraryMethodSignaturesCache =
+      new IdentityHashMap<>();
   private final Map<DexProgramClass, Set<DexProgramClass>> stronglyConnectedComponentsCache =
       new IdentityHashMap<>();
 
@@ -152,12 +154,37 @@
       clazz.forEachProgramVirtualMethodMatching(
           method -> method.getAccessFlags().isPackagePrivateOrProtected(),
           nonPublicVirtualMethodSignatures::add);
+      immediateSubtypingInfo.forEachImmediateSuperClassMatching(
+          clazz,
+          superclass -> !superclass.isProgramClass(),
+          superclass ->
+              nonPublicVirtualMethodSignatures.addAll(
+                  getOrComputeNonPublicVirtualLibraryMethodSignatures(superclass)));
     }
     nonPublicVirtualMethodSignaturesCache.put(
         stronglyConnectedComponent, nonPublicVirtualMethodSignatures);
     return nonPublicVirtualMethodSignatures;
   }
 
+  private DexMethodSignatureSet getOrComputeNonPublicVirtualLibraryMethodSignatures(
+      DexClass clazz) {
+    if (nonPublicVirtualLibraryMethodSignaturesCache.containsKey(clazz)) {
+      return nonPublicVirtualLibraryMethodSignaturesCache.get(clazz);
+    }
+    DexMethodSignatureSet nonPublicVirtualLibraryMethodSignatures = DexMethodSignatureSet.create();
+    clazz.forEachClassMethodMatching(
+        method -> method.getAccessFlags().isPackagePrivateOrProtected(),
+        nonPublicVirtualLibraryMethodSignatures::add);
+    immediateSubtypingInfo.forEachImmediateSuperClass(
+        clazz,
+        superclass ->
+            nonPublicVirtualLibraryMethodSignatures.addAll(
+                getOrComputeNonPublicVirtualLibraryMethodSignatures(superclass)));
+    nonPublicVirtualLibraryMethodSignaturesCache.put(
+        clazz, nonPublicVirtualLibraryMethodSignatures);
+    return nonPublicVirtualLibraryMethodSignatures;
+  }
+
   @Override
   public void clear() {
     inheritedInterfaceMethodsCache.clear();