Merge "Fix build_prop module to use partition() instead of PartitionTag()" into main
diff --git a/android/androidmk.go b/android/androidmk.go
index e9df752..f88a226 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -861,6 +861,7 @@
 	}
 
 	data := provider.AndroidMk()
+
 	if data.Include == "" {
 		data.Include = "$(BUILD_PREBUILT)"
 	}
@@ -907,6 +908,7 @@
 		case "*phony.PhonyRule": // writes phony deps and acts like `.PHONY`
 		case "*selinux.selinuxContextsModule": // license properties written
 		case "*sysprop.syspropLibrary": // license properties written
+		case "*vintf.vintfCompatibilityMatrixRule": // use case like phony
 		default:
 			if !ctx.Config().IsEnvFalse("ANDROID_REQUIRE_LICENSES") {
 				return fmt.Errorf("custom make rules not allowed for %q (%q) module %q", ctx.ModuleType(mod), reflect.TypeOf(mod), ctx.ModuleName(mod))
diff --git a/android/compliance_metadata.go b/android/compliance_metadata.go
index 0080b9a..5cdd302 100644
--- a/android/compliance_metadata.go
+++ b/android/compliance_metadata.go
@@ -160,7 +160,7 @@
 // buildComplianceMetadataProvider starts with the ModuleContext.ComplianceMetadataInfo() and fills in more common metadata
 // for different module types without accessing their private fields but through android.Module interface
 // and public/private fields of package android. The final metadata is stored to a module's ComplianceMetadataProvider.
-func buildComplianceMetadataProvider(ctx ModuleContext, m *ModuleBase) {
+func buildComplianceMetadataProvider(ctx *moduleContext, m *ModuleBase) {
 	complianceMetadataInfo := ctx.ComplianceMetadataInfo()
 	complianceMetadataInfo.SetStringValue(ComplianceMetadataProp.NAME, m.Name())
 	complianceMetadataInfo.SetStringValue(ComplianceMetadataProp.PACKAGE, ctx.ModuleDir())
@@ -186,7 +186,7 @@
 		}
 
 		var installed InstallPaths
-		installed = append(installed, m.module.FilesToInstall()...)
+		installed = append(installed, ctx.installFiles...)
 		installed = append(installed, m.katiInstalls.InstallPaths()...)
 		installed = append(installed, m.katiSymlinks.InstallPaths()...)
 		installed = append(installed, m.katiInitRcInstalls.InstallPaths()...)
diff --git a/android/config.go b/android/config.go
index d13e5ab..d6d76a4 100644
--- a/android/config.go
+++ b/android/config.go
@@ -2053,3 +2053,19 @@
 func (c *config) EnableUffdGc() string {
 	return String(c.productVariables.EnableUffdGc)
 }
+
+func (c *config) DeviceFrameworkCompatibilityMatrixFile() []string {
+	return c.productVariables.DeviceFrameworkCompatibilityMatrixFile
+}
+
+func (c *config) DeviceProductCompatibilityMatrixFile() []string {
+	return c.productVariables.DeviceProductCompatibilityMatrixFile
+}
+
+func (c *config) BoardAvbEnable() bool {
+	return Bool(c.productVariables.BoardAvbEnable)
+}
+
+func (c *config) BoardAvbSystemAddHashtreeFooterArgs() []string {
+	return c.productVariables.BoardAvbSystemAddHashtreeFooterArgs
+}
diff --git a/android/deapexer.go b/android/deapexer.go
index 61ae64e..dcae3e4 100644
--- a/android/deapexer.go
+++ b/android/deapexer.go
@@ -181,7 +181,11 @@
 			// An err has been found. Do not visit further.
 			return
 		}
-		c, _ := OtherModuleProvider(ctx, m, DeapexerProvider)
+		c, ok := OtherModuleProvider(ctx, m, DeapexerProvider)
+		if !ok {
+			ctx.ModuleErrorf("Expected all deps with DeapexerTag to have a DeapexerProvider, but module %q did not", m.Name())
+			return
+		}
 		p := &c
 		if di != nil {
 			// If two DeapexerInfo providers have been found then check if they are
diff --git a/android/license_metadata.go b/android/license_metadata.go
index 8056189..c12a01c 100644
--- a/android/license_metadata.go
+++ b/android/license_metadata.go
@@ -33,7 +33,7 @@
 	}, "args")
 )
 
-func buildLicenseMetadata(ctx ModuleContext, licenseMetadataFile WritablePath) {
+func buildLicenseMetadata(ctx *moduleContext, licenseMetadataFile WritablePath) {
 	base := ctx.Module().base()
 
 	if !base.Enabled(ctx) {
@@ -52,8 +52,8 @@
 	// Only pass the last installed file to isContainerFromFileExtensions so a *.zip file in test data
 	// doesn't mark the whole module as a container.
 	var installFiles InstallPaths
-	if len(base.installFiles) > 0 {
-		installFiles = InstallPaths{base.installFiles[len(base.installFiles)-1]}
+	if len(ctx.installFiles) > 0 {
+		installFiles = InstallPaths{ctx.installFiles[len(ctx.installFiles)-1]}
 	}
 
 	isContainer := isContainerFromFileExtensions(installFiles, outputFiles)
@@ -92,7 +92,7 @@
 
 			allDepMetadataArgs = append(allDepMetadataArgs, info.LicenseMetadataPath.String()+depAnnotations)
 
-			if depInstallFiles := dep.base().installFiles; len(depInstallFiles) > 0 {
+			if depInstallFiles := ModuleFilesToInstall(ctx, dep); len(depInstallFiles) > 0 {
 				allDepOutputFiles = append(allDepOutputFiles, depInstallFiles.Paths()...)
 			} else if depOutputFiles, err := outputFilesForModule(ctx, dep, ""); err == nil {
 				depOutputFiles = PathsIfNonNil(depOutputFiles...)
@@ -162,7 +162,7 @@
 
 	// Installed files
 	args = append(args,
-		JoinWithPrefix(proptools.NinjaAndShellEscapeListIncludingSpaces(base.installFiles.Strings()), "-i "))
+		JoinWithPrefix(proptools.NinjaAndShellEscapeListIncludingSpaces(ctx.installFiles.Strings()), "-i "))
 
 	if isContainer {
 		args = append(args, "--is_container")
diff --git a/android/module.go b/android/module.go
index 63df6f7..d548b83 100644
--- a/android/module.go
+++ b/android/module.go
@@ -112,7 +112,6 @@
 	HostRequiredModuleNames() []string
 	TargetRequiredModuleNames() []string
 
-	FilesToInstall() InstallPaths
 	PackagingSpecs() []PackagingSpec
 
 	// TransitivePackagingSpecs returns the PackagingSpecs for this module and any transitive
@@ -760,6 +759,14 @@
 	m.base().commonProperties.CreateCommonOSVariant = true
 }
 
+func ModuleFilesToInstall(ctx OtherModuleProviderContext, m blueprint.Module) InstallPaths {
+	var filesToInstall InstallPaths
+	if info, ok := OtherModuleProvider(ctx, m, InstallFilesProvider); ok {
+		filesToInstall = info.InstallFiles
+	}
+	return filesToInstall
+}
+
 // A ModuleBase object contains the properties that are common to all Android
 // modules.  It should be included as an anonymous field in every module
 // struct definition.  InitAndroidModule should then be called from the module's
@@ -832,7 +839,6 @@
 	primaryLicensesProperty applicableLicensesProperty
 
 	noAddressSanitizer   bool
-	installFiles         InstallPaths
 	installFilesDepSet   *DepSet[InstallPath]
 	checkbuildFiles      Paths
 	packagingSpecs       []PackagingSpec
@@ -1476,10 +1482,6 @@
 	return IsInstallDepNeededTag(tag)
 }
 
-func (m *ModuleBase) FilesToInstall() InstallPaths {
-	return m.installFiles
-}
-
 func (m *ModuleBase) PackagingSpecs() []PackagingSpec {
 	return m.packagingSpecs
 }
@@ -1615,12 +1617,16 @@
 	m.licenseInstallMap = append(m.licenseInstallMap, installMap...)
 }
 
-func (m *ModuleBase) generateModuleTarget(ctx ModuleContext) {
+func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) {
 	var allInstalledFiles InstallPaths
 	var allCheckbuildFiles Paths
 	ctx.VisitAllModuleVariants(func(module Module) {
 		a := module.base()
-		allInstalledFiles = append(allInstalledFiles, a.installFiles...)
+		if a == m {
+			allInstalledFiles = append(allInstalledFiles, ctx.installFiles...)
+		} else {
+			allInstalledFiles = append(allInstalledFiles, ModuleFilesToInstall(ctx, module)...)
+		}
 		// A module's -checkbuild phony targets should
 		// not be created if the module is not exported to make.
 		// Those could depend on the build target and fail to compile
@@ -1763,6 +1769,12 @@
 
 }
 
+type InstallFilesInfo struct {
+	InstallFiles InstallPaths
+}
+
+var InstallFilesProvider = blueprint.NewProvider[InstallFilesInfo]()
+
 func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
 	ctx := &moduleContext{
 		module:            m.module,
@@ -1944,12 +1956,15 @@
 			return
 		}
 
-		m.installFiles = append(m.installFiles, ctx.installFiles...)
 		m.checkbuildFiles = append(m.checkbuildFiles, ctx.checkbuildFiles...)
 		m.packagingSpecs = append(m.packagingSpecs, ctx.packagingSpecs...)
 		m.katiInstalls = append(m.katiInstalls, ctx.katiInstalls...)
 		m.katiSymlinks = append(m.katiSymlinks, ctx.katiSymlinks...)
 		m.testData = append(m.testData, ctx.testData...)
+
+		SetProvider(ctx, InstallFilesProvider, InstallFilesInfo{
+			InstallFiles: ctx.installFiles,
+		})
 	} else if ctx.Config().AllowMissingDependencies() {
 		// If the module is not enabled it will not create any build rules, nothing will call
 		// ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled
@@ -1965,7 +1980,7 @@
 		}
 	}
 
-	m.installFilesDepSet = NewDepSet[InstallPath](TOPOLOGICAL, m.installFiles, dependencyInstallFiles)
+	m.installFilesDepSet = NewDepSet[InstallPath](TOPOLOGICAL, ctx.installFiles, dependencyInstallFiles)
 	m.packagingSpecsDepSet = NewDepSet[PackagingSpec](TOPOLOGICAL, m.packagingSpecs, dependencyPackagingSpecs)
 
 	buildLicenseMetadata(ctx, m.licenseMetadataFile)
diff --git a/android/test_suites.go b/android/test_suites.go
index ff75f26..c0dc17e 100644
--- a/android/test_suites.go
+++ b/android/test_suites.go
@@ -47,7 +47,7 @@
 					files[testSuite] = make(map[string]InstallPaths)
 				}
 				name := ctx.ModuleName(m)
-				files[testSuite][name] = append(files[testSuite][name], tsm.FilesToInstall()...)
+				files[testSuite][name] = append(files[testSuite][name], ModuleFilesToInstall(ctx, tsm)...)
 			}
 		}
 	})
diff --git a/android/variable.go b/android/variable.go
index 4025607..c141437 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -513,6 +513,11 @@
 	ProductPropFiles   []string `json:",omitempty"`
 
 	EnableUffdGc *string `json:",omitempty"`
+
+	BoardAvbEnable                         *bool    `json:",omitempty"`
+	BoardAvbSystemAddHashtreeFooterArgs    []string `json:",omitempty"`
+	DeviceFrameworkCompatibilityMatrixFile []string `json:",omitempty"`
+	DeviceProductCompatibilityMatrixFile   []string `json:",omitempty"`
 }
 
 type PartitionQualifiedVariablesType struct {
diff --git a/android_sdk/sdk_repo_host.go b/android_sdk/sdk_repo_host.go
index 373e883..a2486fd 100644
--- a/android_sdk/sdk_repo_host.go
+++ b/android_sdk/sdk_repo_host.go
@@ -46,6 +46,9 @@
 
 	outputBaseName string
 	outputFile     android.OptionalPath
+
+	// TODO(b/357908583): Temp field, remove this once we support Android Mk providers
+	installFile android.InstallPath
 }
 
 type remapProperties struct {
@@ -234,14 +237,18 @@
 
 	s.outputBaseName = name
 	s.outputFile = android.OptionalPathForPath(outputZipFile)
-	ctx.InstallFile(android.PathForModuleInstall(ctx, "sdk-repo"), name+".zip", outputZipFile)
+	installPath := android.PathForModuleInstall(ctx, "sdk-repo")
+	name = name + ".zip"
+	ctx.InstallFile(installPath, name, outputZipFile)
+	// TODO(b/357908583): Temp field, remove this once we support Android Mk providers
+	s.installFile = installPath.Join(ctx, name)
 }
 
 func (s *sdkRepoHost) AndroidMk() android.AndroidMkData {
 	return android.AndroidMkData{
 		Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
 			fmt.Fprintln(w, ".PHONY:", name, "sdk_repo", "sdk-repo-"+name)
-			fmt.Fprintln(w, "sdk_repo", "sdk-repo-"+name+":", strings.Join(s.FilesToInstall().Strings(), " "))
+			fmt.Fprintln(w, "sdk_repo", "sdk-repo-"+name+":", s.installFile.String())
 
 			fmt.Fprintf(w, "$(call dist-for-goals,sdk_repo sdk-repo-%s,%s:%s-FILE_NAME_TAG_PLACEHOLDER.zip)\n\n", s.BaseModuleName(), s.outputFile.String(), s.outputBaseName)
 		},
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index 20a13c3..65278c9 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -516,7 +516,7 @@
 	// This cannot be marked as `android:"arch_variant"` because the `prebuilt_apex` is only mutated
 	// for android_common. That is so that it will have the same arch variant as, and so be compatible
 	// with, the source `apex` module type that it replaces.
-	Src  *string `android:"path"`
+	Src  proptools.Configurable[string] `android:"path,replace_instead_of_append"`
 	Arch struct {
 		Arm struct {
 			Src *string `android:"path"`
@@ -566,7 +566,7 @@
 		src = String(p.Arch.X86_64.Src)
 	}
 	if src == "" {
-		src = String(p.Src)
+		src = p.Src.GetOrDefault(ctx, "")
 	}
 
 	if src == "" {
diff --git a/cc/cmake_snapshot.go b/cc/cmake_snapshot.go
index 8f3ad96..9159156 100644
--- a/cc/cmake_snapshot.go
+++ b/cc/cmake_snapshot.go
@@ -476,7 +476,7 @@
 		var prebuiltsList android.Paths
 
 		ctx.VisitDirectDepsWithTag(cmakeSnapshotPrebuiltTag, func(dep android.Module) {
-			for _, file := range dep.FilesToInstall() {
+			for _, file := range android.ModuleFilesToInstall(ctx, dep) {
 				prebuiltsList = append(prebuiltsList, file)
 			}
 		})
diff --git a/java/app.go b/java/app.go
index 19dc8d5..a8eaaa4 100644
--- a/java/app.go
+++ b/java/app.go
@@ -1109,7 +1109,7 @@
 						coverageFile:   dep.CoverageOutputFile(),
 						unstrippedFile: dep.UnstrippedOutputFile(),
 						partition:      dep.Partition(),
-						installPaths:   dep.FilesToInstall(),
+						installPaths:   android.ModuleFilesToInstall(ctx, dep),
 					})
 				} else if ctx.Config().AllowMissingDependencies() {
 					ctx.AddMissingDependencies([]string{otherName})
diff --git a/java/ravenwood.go b/java/ravenwood.go
index a52f405..d65be52 100644
--- a/java/ravenwood.go
+++ b/java/ravenwood.go
@@ -152,7 +152,7 @@
 	var runtimeJniModuleNames map[string]bool
 
 	if utils := ctx.GetDirectDepsWithTag(ravenwoodUtilsTag)[0]; utils != nil {
-		for _, installFile := range utils.FilesToInstall() {
+		for _, installFile := range android.ModuleFilesToInstall(ctx, utils) {
 			installDeps = append(installDeps, installFile)
 		}
 		jniDeps, ok := android.OtherModuleProvider(ctx, utils, ravenwoodLibgroupJniDepProvider)
@@ -162,7 +162,7 @@
 	}
 
 	if runtime := ctx.GetDirectDepsWithTag(ravenwoodRuntimeTag)[0]; runtime != nil {
-		for _, installFile := range runtime.FilesToInstall() {
+		for _, installFile := range android.ModuleFilesToInstall(ctx, runtime) {
 			installDeps = append(installDeps, installFile)
 		}
 		jniDeps, ok := android.OtherModuleProvider(ctx, runtime, ravenwoodLibgroupJniDepProvider)
@@ -191,7 +191,7 @@
 
 	resApkInstallPath := installPath.Join(ctx, "ravenwood-res-apks")
 	if resApk := ctx.GetDirectDepsWithTag(ravenwoodTestResourceApkTag); len(resApk) > 0 {
-		for _, installFile := range resApk[0].FilesToInstall() {
+		for _, installFile := range android.ModuleFilesToInstall(ctx, resApk[0]) {
 			installResApk := ctx.InstallFile(resApkInstallPath, "ravenwood-res.apk", installFile)
 			installDeps = append(installDeps, installResApk)
 		}