Reimplement verify_uses_libraries.sh in manifest_check.py.

Previously there were two different scripts that did similar things:
1) build/soong/scripts/manifest_check.py
2) build/make/core/verify_uses_libraries.sh

Both scripts extracted <uses-library> tags and `targetSdkVersion` from
the manifests of Java modules, but 1) worked for XML manifests, and 2)
worked for APKs. This CL reimplements the functionality from 2) in 1),
so that one script can handle both XML manifests and APKs.

Bug: 132357300

Test: lunch cf_x86_64_phone-userdebug && m && launch_cvd \
      adb wait-for-device && adb root && adb logcat \
      | grep -E 'ClassLoaderContext [a-z ]+ mismatch'
      # empty grep output, no errors

Change-Id: Id1b66e4f3f30f307dba70cb111c7571762cb546a
diff --git a/java/app.go b/java/app.go
index eef627c..0c1c717 100755
--- a/java/app.go
+++ b/java/app.go
@@ -1281,10 +1281,13 @@
 	u.usesLibraryProperties.Enforce_uses_libs = &enforce
 }
 
-// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against the ones specified
-// in the uses_libs and optional_uses_libs properties.  It returns the path to a copy of the manifest.
-func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path) android.Path {
-	outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
+// verifyUsesLibraries checks the <uses-library> tags in the manifest against the ones specified
+// in the `uses_libs`/`optional_uses_libs` properties. The input can be either an XML manifest, or
+// an APK with the manifest embedded in it (manifest_check will know which one it is by the file
+// extension: APKs are supposed to end with '.apk').
+func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile android.Path,
+	outputFile android.WritablePath) {
+
 	statusFile := dexpreopt.UsesLibrariesStatusFile(ctx)
 
 	// Disable verify_uses_libraries check if dexpreopt is globally disabled. Without dexpreopt the
@@ -1292,15 +1295,19 @@
 	// non-linux build platforms where dexpreopt is generally disabled (the check may fail due to
 	// various unrelated reasons, such as a failure to get manifest from an APK).
 	if dexpreopt.GetGlobalConfig(ctx).DisablePreopt {
-		return manifest
+		return
 	}
 
 	rule := android.NewRuleBuilder(pctx, ctx)
 	cmd := rule.Command().BuiltTool("manifest_check").
 		Flag("--enforce-uses-libraries").
-		Input(manifest).
+		Input(inputFile).
 		FlagWithOutput("--enforce-uses-libraries-status ", statusFile).
-		FlagWithOutput("-o ", outputFile)
+		FlagWithInput("--aapt ", ctx.Config().HostToolPath(ctx, "aapt"))
+
+	if outputFile != nil {
+		cmd.FlagWithOutput("-o ", outputFile)
+	}
 
 	if dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck {
 		cmd.Flag("--enforce-uses-libraries-relax")
@@ -1315,35 +1322,20 @@
 	}
 
 	rule.Build("verify_uses_libraries", "verify <uses-library>")
+}
 
+// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against
+// the build system and returns the path to a copy of the manifest.
+func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path) android.Path {
+	outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
+	u.verifyUsesLibraries(ctx, manifest, outputFile)
 	return outputFile
 }
 
-// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the ones specified
-// in the uses_libs and optional_uses_libs properties.  It returns the path to a copy of the APK.
+// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the build
+// system and returns the path to a copy of the APK.
 func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path) android.Path {
+	u.verifyUsesLibraries(ctx, apk, nil) // for APKs manifest_check does not write output file
 	outputFile := android.PathForModuleOut(ctx, "verify_uses_libraries", apk.Base())
-	statusFile := dexpreopt.UsesLibrariesStatusFile(ctx)
-
-	// Disable verify_uses_libraries check if dexpreopt is globally disabled. Without dexpreopt the
-	// check is not necessary, and although it is good to have, it is difficult to maintain on
-	// non-linux build platforms where dexpreopt is generally disabled (the check may fail due to
-	// various unrelated reasons, such as a failure to get manifest from an APK).
-	if dexpreopt.GetGlobalConfig(ctx).DisablePreopt {
-		return apk
-	}
-
-	rule := android.NewRuleBuilder(pctx, ctx)
-	aapt := ctx.Config().HostToolPath(ctx, "aapt")
-	rule.Command().
-		Textf("aapt_binary=%s", aapt.String()).Implicit(aapt).
-		Textf(`uses_library_names="%s"`, strings.Join(u.usesLibraryProperties.Uses_libs, " ")).
-		Textf(`optional_uses_library_names="%s"`, strings.Join(u.usesLibraryProperties.Optional_uses_libs, " ")).
-		Textf(`relax_check="%t"`, dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck).
-		Tool(android.PathForSource(ctx, "build/make/core/verify_uses_libraries.sh")).Input(apk).Output(statusFile)
-	rule.Command().Text("cp -f").Input(apk).Output(outputFile)
-
-	rule.Build("verify_uses_libraries", "verify <uses-library>")
-
 	return outputFile
 }
diff --git a/java/app_test.go b/java/app_test.go
index 78e1a57..040ca19 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -2405,13 +2405,13 @@
 
 	// Test that all libraries are verified for an APK (library order matters).
 	verifyApkCmd := prebuilt.Rule("verify_uses_libraries").RuleParams.Command
-	verifyApkReqLibs := `uses_library_names="foo com.non.sdk.lib android.test.runner"`
-	verifyApkOptLibs := `optional_uses_library_names="bar baz"`
-	if !strings.Contains(verifyApkCmd, verifyApkReqLibs) {
-		t.Errorf("wanted %q in %q", verifyApkReqLibs, verifyApkCmd)
-	}
-	if !strings.Contains(verifyApkCmd, verifyApkOptLibs) {
-		t.Errorf("wanted %q in %q", verifyApkOptLibs, verifyApkCmd)
+	verifyApkArgs := `--uses-library foo ` +
+		`--uses-library com.non.sdk.lib ` +
+		`--uses-library android.test.runner ` +
+		`--optional-uses-library bar ` +
+		`--optional-uses-library baz `
+	if !strings.Contains(verifyApkCmd, verifyApkArgs) {
+		t.Errorf("wanted %q in %q", verifyApkArgs, verifyApkCmd)
 	}
 
 	// Test that all present libraries are preopted, including implicit SDK dependencies, possibly stubs