Pass config files to metalava

Adds a filegroup "metalava-config-files" whose contents are passed to
Metalava using the `--config-file` option.

Bug: 354699349
Test: m checkapi
Change-Id: I1e246517c2ef678e41214c975aecee97f9faca67
diff --git a/java/droidstubs.go b/java/droidstubs.go
index a8e0a22..d622903 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -197,6 +197,10 @@
 	// a list of aconfig_declarations module names that the stubs generated in this module
 	// depend on.
 	Aconfig_declarations []string
+
+	// List of hard coded filegroups containing Metalava config files that are passed to every
+	// Metalava invocation that this module performs. See addMetalavaConfigFilesToCmd.
+	ConfigFiles []string `android:"path" blueprint:"mutated"`
 }
 
 // Used by xsd_config
@@ -259,6 +263,7 @@
 
 	module.AddProperties(&module.properties,
 		&module.Javadoc.properties)
+	module.properties.ConfigFiles = getMetalavaConfigFilegroupReference()
 	module.initModuleAndImport(module)
 
 	InitDroiddocModule(module, android.HostAndDeviceSupported)
@@ -279,6 +284,7 @@
 	module.AddProperties(&module.properties,
 		&module.Javadoc.properties)
 
+	module.properties.ConfigFiles = getMetalavaConfigFilegroupReference()
 	InitDroiddocModule(module, android.HostSupported)
 	return module
 }
@@ -694,7 +700,7 @@
 }
 
 func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
-	srcJarList android.Path, homeDir android.WritablePath, params stubsCommandConfigParams) *android.RuleBuilderCommand {
+	srcJarList android.Path, homeDir android.WritablePath, params stubsCommandConfigParams, configFiles android.Paths) *android.RuleBuilderCommand {
 	rule.Command().Text("rm -rf").Flag(homeDir.String())
 	rule.Command().Text("mkdir -p").Flag(homeDir.String())
 
@@ -738,9 +744,26 @@
 
 	cmd.Flag(config.MetalavaFlags)
 
+	addMetalavaConfigFilesToCmd(cmd, configFiles)
+
 	return cmd
 }
 
+// MetalavaConfigFilegroup is the name of the filegroup in build/soong/java/metalava that lists
+// the configuration files to pass to Metalava.
+const MetalavaConfigFilegroup = "metalava-config-files"
+
+// Get a reference to the MetalavaConfigFilegroup suitable for use in a property.
+func getMetalavaConfigFilegroupReference() []string {
+	return []string{":" + MetalavaConfigFilegroup}
+}
+
+// addMetalavaConfigFilesToCmd adds --config-file options to use the config files list in the
+// MetalavaConfigFilegroup filegroup.
+func addMetalavaConfigFilesToCmd(cmd *android.RuleBuilderCommand, configFiles android.Paths) {
+	cmd.FlagForEachInput("--config-file ", configFiles)
+}
+
 // Pass flagged apis related flags to metalava. When aconfig_declarations property is not
 // defined for a module, simply revert all flagged apis annotations. If aconfig_declarations
 // property is defined, apply transformations and only revert the flagged apis that are not
@@ -812,7 +835,10 @@
 	srcJarList := zipSyncCmd(ctx, rule, params.srcJarDir, d.Javadoc.srcJars)
 
 	homeDir := android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "home")
-	cmd := metalavaCmd(ctx, rule, d.Javadoc.srcFiles, srcJarList, homeDir, params.stubConfig)
+
+	configFiles := android.PathsForModuleSrc(ctx, d.properties.ConfigFiles)
+
+	cmd := metalavaCmd(ctx, rule, d.Javadoc.srcFiles, srcJarList, homeDir, params.stubConfig, configFiles)
 	cmd.Implicits(d.Javadoc.implicits)
 
 	d.stubsFlags(ctx, cmd, params.stubsDir, params.stubConfig.stubsType, params.stubConfig.checkApi)
diff --git a/java/java.go b/java/java.go
index 3dae4e4..b320732 100644
--- a/java/java.go
+++ b/java/java.go
@@ -269,7 +269,7 @@
 	ImplementationAndResourcesJars android.Paths
 
 	// ImplementationJars is a list of jars that contain the implementations of classes in the
-	//module.
+	// module.
 	ImplementationJars android.Paths
 
 	// ResourceJars is a list of jars that contain the resources included in the module.
@@ -2039,12 +2039,17 @@
 	// List of aconfig_declarations module names that the stubs generated in this module
 	// depend on.
 	Aconfig_declarations []string
+
+	// List of hard coded filegroups containing Metalava config files that are passed to every
+	// Metalava invocation that this module performs. See addMetalavaConfigFilesToCmd.
+	ConfigFiles []string `android:"path" blueprint:"mutated"`
 }
 
 func ApiLibraryFactory() android.Module {
 	module := &ApiLibrary{}
-	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
 	module.AddProperties(&module.properties)
+	module.properties.ConfigFiles = getMetalavaConfigFilegroupReference()
+	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
 	module.initModuleAndImport(module)
 	android.InitDefaultableModule(module)
 	return module
@@ -2060,7 +2065,7 @@
 
 func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
 	srcs android.Paths, homeDir android.WritablePath,
-	classpath android.Paths) *android.RuleBuilderCommand {
+	classpath android.Paths, configFiles android.Paths) *android.RuleBuilderCommand {
 	rule.Command().Text("rm -rf").Flag(homeDir.String())
 	rule.Command().Text("mkdir -p").Flag(homeDir.String())
 
@@ -2099,6 +2104,8 @@
 		FlagWithArg("--hide ", "InvalidNullabilityOverride").
 		FlagWithArg("--hide ", "ChangedDefault")
 
+	addMetalavaConfigFilesToCmd(cmd, configFiles)
+
 	if len(classpath) == 0 {
 		// The main purpose of the `--api-class-resolution api` option is to force metalava to ignore
 		// classes on the classpath when an API file contains missing classes. However, as this command
@@ -2310,7 +2317,9 @@
 		ctx.ModuleErrorf("Error: %s has an empty api file.", ctx.ModuleName())
 	}
 
-	cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir, systemModulesPaths)
+	configFiles := android.PathsForModuleSrc(ctx, al.properties.ConfigFiles)
+
+	cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir, systemModulesPaths, configFiles)
 
 	al.stubsFlags(ctx, cmd, stubsDir)
 
diff --git a/java/metalava/Android.bp b/java/metalava/Android.bp
new file mode 100644
index 0000000..ccbd191
--- /dev/null
+++ b/java/metalava/Android.bp
@@ -0,0 +1,18 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+filegroup {
+    name: "metalava-config-files",
+    srcs: ["*-config.xml"],
+}
diff --git a/java/metalava/OWNERS b/java/metalava/OWNERS
new file mode 100644
index 0000000..e8c438e
--- /dev/null
+++ b/java/metalava/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 463936
+
+file:platform/tools/metalava:/OWNERS
diff --git a/java/metalava/main-config.xml b/java/metalava/main-config.xml
new file mode 100644
index 0000000..c61196f
--- /dev/null
+++ b/java/metalava/main-config.xml
@@ -0,0 +1,19 @@
+<!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<config xmlns="http://www.google.com/tools/metalava/config"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://www.google.com/tools/metalava/config ../../../../tools/metalava/metalava/src/main/resources/schemas/config.xsd"/>
diff --git a/java/metalava/source-model-selection-config.xml b/java/metalava/source-model-selection-config.xml
new file mode 100644
index 0000000..c61196f
--- /dev/null
+++ b/java/metalava/source-model-selection-config.xml
@@ -0,0 +1,19 @@
+<!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<config xmlns="http://www.google.com/tools/metalava/config"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://www.google.com/tools/metalava/config ../../../../tools/metalava/metalava/src/main/resources/schemas/config.xsd"/>
diff --git a/java/testing.go b/java/testing.go
index 5ae326d..7a42e4c 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -52,6 +52,8 @@
 	android.MockFS{
 		// Needed for linter used by java_library.
 		"build/soong/java/lint_defaults.txt": nil,
+		// Needed for java components that invoke Metalava.
+		"build/soong/java/metalava/Android.bp": []byte(`filegroup {name: "metalava-config-files"}`),
 		// Needed for apps that do not provide their own.
 		"build/make/target/product/security": nil,
 		// Required to generate Java used-by API coverage