Merge "Always install to out/target instead of out/soong/target" into main
diff --git a/aconfig/codegen/cc_aconfig_library.go b/aconfig/codegen/cc_aconfig_library.go
index 8c4bfe6..f9c7b8c 100644
--- a/aconfig/codegen/cc_aconfig_library.go
+++ b/aconfig/codegen/cc_aconfig_library.go
@@ -104,7 +104,7 @@
 	result := cc.GeneratedSource{}
 
 	// Get the values that came from the global RELEASE_ACONFIG_VALUE_SETS flag
-	declarationsModules := ctx.GetDirectDepsWithTag(ccDeclarationsTag)
+	declarationsModules := ctx.GetDirectDepsProxyWithTag(ccDeclarationsTag)
 	if len(declarationsModules) != 1 {
 		panic(fmt.Errorf("Exactly one aconfig_declarations property required"))
 	}
@@ -134,7 +134,7 @@
 
 func (this *CcAconfigLibraryCallbacks) GeneratorBuildActions(ctx cc.ModuleContext, flags cc.Flags, deps cc.PathDeps) {
 	// Get the values that came from the global RELEASE_ACONFIG_VALUE_SETS flag
-	declarationsModules := ctx.GetDirectDepsWithTag(ccDeclarationsTag)
+	declarationsModules := ctx.GetDirectDepsProxyWithTag(ccDeclarationsTag)
 	if len(declarationsModules) != 1 {
 		panic(fmt.Errorf("Exactly one aconfig_declarations property required"))
 	}
diff --git a/aconfig/init.go b/aconfig/init.go
index 621d619..21903e2 100644
--- a/aconfig/init.go
+++ b/aconfig/init.go
@@ -73,11 +73,11 @@
 
 	CreateStorageRule = pctx.AndroidStaticRule("aconfig_create_storage",
 		blueprint.RuleParams{
-			Command: `${aconfig} create-storage --container ${container} --file ${file_type} --out ${out} ${cache_files}`,
+			Command: `${aconfig} create-storage --container ${container} --file ${file_type} --out ${out} ${cache_files} --version ${version}`,
 			CommandDeps: []string{
 				"${aconfig}",
 			},
-		}, "container", "file_type", "cache_files")
+		}, "container", "file_type", "cache_files", "version")
 
 	// For exported_java_aconfig_library: Generate a JAR from all
 	// java_aconfig_libraries to be consumed by apps built outside the
diff --git a/android/aconfig_providers.go b/android/aconfig_providers.go
index 210a656..b698d24 100644
--- a/android/aconfig_providers.go
+++ b/android/aconfig_providers.go
@@ -92,11 +92,11 @@
 				if asError {
 					ctx.ModuleErrorf(msg)
 				} else {
-					fmt.Printf("WARNING: " + msg)
+					fmt.Print("WARNING: " + msg)
 				}
 			} else {
 				if !asError {
-					fmt.Printf("PASSED: " + msg)
+					fmt.Print("PASSED: " + msg)
 				}
 			}
 		}
diff --git a/android/base_module_context.go b/android/base_module_context.go
index 06819d6..d8558d0 100644
--- a/android/base_module_context.go
+++ b/android/base_module_context.go
@@ -110,15 +110,14 @@
 
 	GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module
 
+	GetDirectDepsProxyWithTag(tag blueprint.DependencyTag) []ModuleProxy
+
 	// GetDirectDepWithTag returns the Module the direct dependency with the specified name, or nil if
 	// none exists.  It panics if the dependency does not have the specified tag.  It skips any
 	// dependencies that are not an android.Module.
 	GetDirectDepWithTag(name string, tag blueprint.DependencyTag) Module
 
-	// GetDirectDep returns the Module and DependencyTag for the direct dependency with the specified
-	// name, or nil if none exists.  If there are multiple dependencies on the same module it returns
-	// the first DependencyTag.
-	GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
+	GetDirectDepProxyWithTag(name string, tag blueprint.DependencyTag) *ModuleProxy
 
 	// VisitDirectDeps calls visit for each direct dependency.  If there are multiple
 	// direct dependencies on the same module visit will be called multiple times on that module
@@ -314,6 +313,13 @@
 	return nil
 }
 
+func (b *baseModuleContext) GetDirectDepProxyWithTag(name string, tag blueprint.DependencyTag) *ModuleProxy {
+	if module := b.bp.GetDirectDepProxyWithTag(name, tag); module != nil {
+		return &ModuleProxy{*module}
+	}
+	return nil
+}
+
 func (b *baseModuleContext) blueprintBaseModuleContext() blueprint.BaseModuleContext {
 	return b.bp
 }
@@ -402,53 +408,30 @@
 	return &aModule
 }
 
-type dep struct {
-	mod blueprint.Module
-	tag blueprint.DependencyTag
-}
-
-func (b *baseModuleContext) getDirectDepsInternal(name string, tag blueprint.DependencyTag) []dep {
-	var deps []dep
+func (b *baseModuleContext) getDirectDepsInternal(name string, tag blueprint.DependencyTag) []Module {
+	var deps []Module
 	b.VisitDirectDeps(func(module Module) {
 		if module.base().BaseModuleName() == name {
 			returnedTag := b.bp.OtherModuleDependencyTag(module)
 			if tag == nil || returnedTag == tag {
-				deps = append(deps, dep{module, returnedTag})
+				deps = append(deps, module)
 			}
 		}
 	})
 	return deps
 }
 
-func (b *baseModuleContext) getDirectDepInternal(name string, tag blueprint.DependencyTag) (blueprint.Module, blueprint.DependencyTag) {
-	deps := b.getDirectDepsInternal(name, tag)
-	if len(deps) == 1 {
-		return deps[0].mod, deps[0].tag
-	} else if len(deps) >= 2 {
-		panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q",
-			name, b.ModuleName()))
-	} else {
-		return nil, nil
-	}
-}
-
-func (b *baseModuleContext) getDirectDepFirstTag(name string) (blueprint.Module, blueprint.DependencyTag) {
-	foundDeps := b.getDirectDepsInternal(name, nil)
-	deps := map[blueprint.Module]bool{}
-	for _, dep := range foundDeps {
-		deps[dep.mod] = true
-	}
-	if len(deps) == 1 {
-		return foundDeps[0].mod, foundDeps[0].tag
-	} else if len(deps) >= 2 {
-		// this could happen if two dependencies have the same name in different namespaces
-		// TODO(b/186554727): this should not occur if namespaces are handled within
-		// getDirectDepsInternal.
-		panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q",
-			name, b.ModuleName()))
-	} else {
-		return nil, nil
-	}
+func (b *baseModuleContext) getDirectDepsProxyInternal(name string, tag blueprint.DependencyTag) []ModuleProxy {
+	var deps []ModuleProxy
+	b.VisitDirectDepsProxy(func(module ModuleProxy) {
+		if OtherModuleProviderOrDefault(b, module, CommonModuleInfoKey).BaseModuleName == name {
+			returnedTag := b.OtherModuleDependencyTag(module)
+			if tag == nil || returnedTag == tag {
+				deps = append(deps, module)
+			}
+		}
+	})
+	return deps
 }
 
 func (b *baseModuleContext) GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module {
@@ -461,11 +444,14 @@
 	return deps
 }
 
-// GetDirectDep returns the Module and DependencyTag for the direct dependency with the specified
-// name, or nil if none exists. If there are multiple dependencies on the same module it returns the
-// first DependencyTag.
-func (b *baseModuleContext) GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag) {
-	return b.getDirectDepFirstTag(name)
+func (b *baseModuleContext) GetDirectDepsProxyWithTag(tag blueprint.DependencyTag) []ModuleProxy {
+	var deps []ModuleProxy
+	b.VisitDirectDepsProxy(func(module ModuleProxy) {
+		if b.OtherModuleDependencyTag(module) == tag {
+			deps = append(deps, module)
+		}
+	})
+	return deps
 }
 
 func (b *baseModuleContext) VisitDirectDeps(visit func(Module)) {
diff --git a/android/config.go b/android/config.go
index d78bbf7..e3be0a0 100644
--- a/android/config.go
+++ b/android/config.go
@@ -289,6 +289,10 @@
 	return c.config.productVariables.GetBuildFlagBool("RELEASE_USE_SYSTEM_FEATURE_BUILD_FLAGS")
 }
 
+func (c Config) ReleaseFingerprintAconfigPackages() bool {
+	return c.config.productVariables.GetBuildFlagBool("RELEASE_FINGERPRINT_ACONFIG_PACKAGES")
+}
+
 // A DeviceConfig object represents the configuration for a particular device
 // being built. For now there will only be one of these, but in the future there
 // may be multiple devices being built.
@@ -1317,11 +1321,16 @@
 }
 
 func (c *config) RunErrorProne() bool {
-	return c.IsEnvTrue("RUN_ERROR_PRONE")
+	return c.IsEnvTrue("RUN_ERROR_PRONE") || c.RunErrorProneInline()
 }
 
+// Returns if the errorprone build should be run "inline", that is, using errorprone as part
+// of the main javac compilation instead of its own separate compilation. This is good for CI
+// but bad for local development, because if you toggle errorprone+inline on/off it will repeatedly
+// clobber java files from the old configuration.
 func (c *config) RunErrorProneInline() bool {
-	return c.IsEnvTrue("RUN_ERROR_PRONE_INLINE")
+	value := strings.ToLower(c.Getenv("RUN_ERROR_PRONE"))
+	return c.IsEnvTrue("RUN_ERROR_PRONE_INLINE") || value == "inline"
 }
 
 // XrefCorpusName returns the Kythe cross-reference corpus name.
diff --git a/android/config_test.go b/android/config_test.go
index adb5ffa..4fdcc9c 100644
--- a/android/config_test.go
+++ b/android/config_test.go
@@ -77,7 +77,7 @@
 func TestProductConfigAnnotations(t *testing.T) {
 	err := validateConfigAnnotations(&ProductVariables{})
 	if err != nil {
-		t.Errorf(err.Error())
+		t.Error(err.Error())
 	}
 }
 
diff --git a/android/early_module_context.go b/android/early_module_context.go
index 5e971ef..8d28285 100644
--- a/android/early_module_context.go
+++ b/android/early_module_context.go
@@ -182,7 +182,7 @@
 }
 
 func (e *earlyModuleContext) OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{}) {
-	e.EarlyModuleContext.OtherModulePropertyErrorf(module, property, fmt, args...)
+	e.EarlyModuleContext.OtherModulePropertyErrorf(getWrappedModule(module), property, fmt, args...)
 }
 
 func (e *earlyModuleContext) HasMutatorFinished(mutatorName string) bool {
diff --git a/android/filegroup.go b/android/filegroup.go
index 67e5add1f..4daff8f 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -104,7 +104,6 @@
 	if fg.properties.Path != nil {
 		srcs = PathsWithModuleSrcSubDir(ctx, srcs, String(fg.properties.Path))
 	}
-	SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: srcs.Strings()})
 
 	var aconfigDeclarations []string
 	var intermediateCacheOutputPaths Paths
diff --git a/android/license_metadata.go b/android/license_metadata.go
index 3df36e6..d15dfa8 100644
--- a/android/license_metadata.go
+++ b/android/license_metadata.go
@@ -15,11 +15,11 @@
 package android
 
 import (
-	"github.com/google/blueprint/depset"
 	"sort"
 	"strings"
 
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/depset"
 	"github.com/google/blueprint/proptools"
 )
 
@@ -64,8 +64,8 @@
 	var allDepOutputFiles Paths
 	var allDepMetadataDepSets []depset.DepSet[Path]
 
-	ctx.VisitDirectDeps(func(dep Module) {
-		if !dep.Enabled(ctx) {
+	ctx.VisitDirectDepsProxy(func(dep ModuleProxy) {
+		if !OtherModuleProviderOrDefault(ctx, dep, CommonModuleInfoKey).Enabled {
 			return
 		}
 
@@ -81,7 +81,7 @@
 
 		if info, ok := OtherModuleProvider(ctx, dep, LicenseMetadataProvider); ok {
 			allDepMetadataFiles = append(allDepMetadataFiles, info.LicenseMetadataPath)
-			if isContainer || isInstallDepNeeded(dep, ctx.OtherModuleDependencyTag(dep)) {
+			if isContainer || isInstallDepNeeded(ctx, dep) {
 				allDepMetadataDepSets = append(allDepMetadataDepSets, info.LicenseMetadataDepSet)
 			}
 
diff --git a/android/module.go b/android/module.go
index c2f4342..72dba04 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1475,12 +1475,13 @@
 func (m *ModuleBase) computeInstallDeps(ctx ModuleContext) ([]depset.DepSet[InstallPath], []depset.DepSet[PackagingSpec]) {
 	var installDeps []depset.DepSet[InstallPath]
 	var packagingSpecs []depset.DepSet[PackagingSpec]
-	ctx.VisitDirectDeps(func(dep Module) {
-		if isInstallDepNeeded(dep, ctx.OtherModuleDependencyTag(dep)) {
+	ctx.VisitDirectDepsProxy(func(dep ModuleProxy) {
+		if isInstallDepNeeded(ctx, dep) {
 			// Installation is still handled by Make, so anything hidden from Make is not
 			// installable.
 			info := OtherModuleProviderOrDefault(ctx, dep, InstallFilesProvider)
-			if !dep.IsHideFromMake() && !dep.IsSkipInstall() {
+			commonInfo := OtherModuleProviderOrDefault(ctx, dep, CommonModuleInfoKey)
+			if !commonInfo.HideFromMake && !commonInfo.SkipInstall {
 				installDeps = append(installDeps, info.TransitiveInstallFiles)
 			}
 			// Add packaging deps even when the dependency is not installed so that uninstallable
@@ -1494,13 +1495,13 @@
 
 // isInstallDepNeeded returns true if installing the output files of the current module
 // should also install the output files of the given dependency and dependency tag.
-func isInstallDepNeeded(dep Module, tag blueprint.DependencyTag) bool {
+func isInstallDepNeeded(ctx ModuleContext, dep ModuleProxy) bool {
 	// Don't add a dependency from the platform to a library provided by an apex.
-	if dep.base().commonProperties.UninstallableApexPlatformVariant {
+	if OtherModuleProviderOrDefault(ctx, dep, CommonModuleInfoKey).UninstallableApexPlatformVariant {
 		return false
 	}
 	// Only install modules if the dependency tag is an InstallDepNeeded tag.
-	return IsInstallDepNeededTag(tag)
+	return IsInstallDepNeededTag(ctx.OtherModuleDependencyTag(dep))
 }
 
 func (m *ModuleBase) NoAddressSanitizer() bool {
@@ -1873,6 +1874,13 @@
 	CanHaveApexVariants     bool
 	MinSdkVersion           string
 	NotAvailableForPlatform bool
+	// UninstallableApexPlatformVariant is set by MakeUninstallable called by the apex
+	// mutator.  MakeUninstallable also sets HideFromMake.  UninstallableApexPlatformVariant
+	// is used to avoid adding install or packaging dependencies into libraries provided
+	// by apexes.
+	UninstallableApexPlatformVariant bool
+	HideFromMake                     bool
+	SkipInstall                      bool
 }
 
 var CommonModuleInfoKey = blueprint.NewProvider[CommonModuleInfo]()
@@ -2138,10 +2146,13 @@
 	buildComplianceMetadataProvider(ctx, m)
 
 	commonData := CommonModuleInfo{
-		ReplacedByPrebuilt:      m.commonProperties.ReplacedByPrebuilt,
-		CompileTarget:           m.commonProperties.CompileTarget,
-		SkipAndroidMkProcessing: shouldSkipAndroidMkProcessing(ctx, m),
-		BaseModuleName:          m.BaseModuleName(),
+		ReplacedByPrebuilt:               m.commonProperties.ReplacedByPrebuilt,
+		CompileTarget:                    m.commonProperties.CompileTarget,
+		SkipAndroidMkProcessing:          shouldSkipAndroidMkProcessing(ctx, m),
+		BaseModuleName:                   m.BaseModuleName(),
+		UninstallableApexPlatformVariant: m.commonProperties.UninstallableApexPlatformVariant,
+		HideFromMake:                     m.commonProperties.HideFromMake,
+		SkipInstall:                      m.commonProperties.SkipInstall,
 	}
 	if mm, ok := m.module.(interface {
 		MinSdkVersion(ctx EarlyModuleContext) ApiLevel
@@ -2737,6 +2748,7 @@
 
 	if octx, ok := ctx.(OutputFilesProviderModuleContext); ok {
 		if octx.EqualModules(octx.Module(), module) {
+			// It is the current module, we can access the srcs through interface
 			if sourceFileProducer, ok := module.(SourceFileProducer); ok {
 				return sourceFileProducer.Srcs(), nil
 			}
diff --git a/android/module_context.go b/android/module_context.go
index b097117..b59e33d 100644
--- a/android/module_context.go
+++ b/android/module_context.go
@@ -440,10 +440,27 @@
 }
 
 func (m *moduleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) Module {
-	if module, _ := m.getDirectDepInternal(name, tag); module != nil {
-		return module.(Module)
+	deps := m.getDirectDepsInternal(name, tag)
+	if len(deps) == 1 {
+		return deps[0]
+	} else if len(deps) >= 2 {
+		panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q",
+			name, m.ModuleName()))
+	} else {
+		return nil
 	}
-	return nil
+}
+
+func (m *moduleContext) GetDirectDepProxyWithTag(name string, tag blueprint.DependencyTag) *ModuleProxy {
+	deps := m.getDirectDepsProxyInternal(name, tag)
+	if len(deps) == 1 {
+		return &deps[0]
+	} else if len(deps) >= 2 {
+		panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q",
+			name, m.ModuleName()))
+	} else {
+		return nil
+	}
 }
 
 func (m *moduleContext) ModuleSubDir() string {
diff --git a/android/namespace.go b/android/namespace.go
index 8b3ebc4..9ba5025 100644
--- a/android/namespace.go
+++ b/android/namespace.go
@@ -332,7 +332,7 @@
 	if isAbs {
 		// if the user gave a fully-qualified name, we don't need to look for other
 		// modules that they might have been referring to
-		return fmt.Errorf(text)
+		return fmt.Errorf("%s", text)
 	}
 
 	// determine which namespaces the module can be found in
@@ -368,7 +368,7 @@
 		text += fmt.Sprintf("\nOr did you mean %q?", guess)
 	}
 
-	return fmt.Errorf(text)
+	return fmt.Errorf("%s", text)
 }
 
 func (r *NameResolver) GetNamespace(ctx blueprint.NamespaceContext) blueprint.Namespace {
diff --git a/android/testing.go b/android/testing.go
index 765839f..6c4f4f8 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -1157,7 +1157,7 @@
 	var p AndroidMkEntriesProvider
 	var ok bool
 	if p, ok = mod.(AndroidMkEntriesProvider); !ok {
-		t.Errorf("module does not implement AndroidMkEntriesProvider: " + mod.Name())
+		t.Error("module does not implement AndroidMkEntriesProvider: " + mod.Name())
 	}
 
 	entriesList := p.AndroidMkEntries()
@@ -1177,7 +1177,7 @@
 	t.Helper()
 	var ok bool
 	if _, ok = mod.(AndroidMkProviderInfoProducer); !ok {
-		t.Errorf("module does not implement AndroidMkProviderInfoProducer: " + mod.Name())
+		t.Error("module does not implement AndroidMkProviderInfoProducer: " + mod.Name())
 	}
 
 	info := OtherModuleProviderOrDefault(ctx, mod, AndroidMkInfoProvider)
@@ -1197,7 +1197,7 @@
 	var p AndroidMkDataProvider
 	var ok bool
 	if p, ok = mod.(AndroidMkDataProvider); !ok {
-		t.Fatalf("module does not implement AndroidMkDataProvider: " + mod.Name())
+		t.Fatal("module does not implement AndroidMkDataProvider: " + mod.Name())
 	}
 	data := p.AndroidMk()
 	data.fillInData(ctx, mod)
diff --git a/android/vintf_fragment_test.go b/android/vintf_fragment_test.go
index cd90b98..cb038f5 100644
--- a/android/vintf_fragment_test.go
+++ b/android/vintf_fragment_test.go
@@ -31,6 +31,6 @@
 
 	vintfFragmentBuild := testResult.TestContext.ModuleForTests("test_vintf_fragment", "android_common").Rule("assemble_vintf")
 	if !strings.Contains(vintfFragmentBuild.RuleParams.Command, "assemble_vintf") {
-		t.Errorf("Vintf_manifest build command does not process with assemble_vintf : " + vintfFragmentBuild.RuleParams.Command)
+		t.Error("Vintf_manifest build command does not process with assemble_vintf : " + vintfFragmentBuild.RuleParams.Command)
 	}
 }
diff --git a/apex/builder.go b/apex/builder.go
index 4c91dd0..c85d0a0 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -70,7 +70,7 @@
 	pctx.HostBinToolVariable("extract_apks", "extract_apks")
 	pctx.HostBinToolVariable("make_f2fs", "make_f2fs")
 	pctx.HostBinToolVariable("sload_f2fs", "sload_f2fs")
-	pctx.HostBinToolVariable("make_erofs", "make_erofs")
+	pctx.HostBinToolVariable("make_erofs", "mkfs.erofs")
 	pctx.HostBinToolVariable("apex_compression_tool", "apex_compression_tool")
 	pctx.HostBinToolVariable("dexdeps", "dexdeps")
 	pctx.HostBinToolVariable("apex_sepolicy_tests", "apex_sepolicy_tests")
@@ -275,6 +275,12 @@
 		})
 		files = append(files, newApexFile(ctx, apexAconfigFile, "aconfig_flags", "etc", etc, nil))
 
+		// To enable fingerprint, we need to have v2 storage files. The default version is 1.
+		storageFilesVersion := 1
+		if ctx.Config().ReleaseFingerprintAconfigPackages() {
+			storageFilesVersion = 2
+		}
+
 		for _, info := range createStorageInfo {
 			outputFile := android.PathForModuleOut(ctx, info.Output_file)
 			ctx.Build(pctx, android.BuildParams{
@@ -286,6 +292,7 @@
 					"container":   ctx.ModuleName(),
 					"file_type":   info.File_type,
 					"cache_files": android.JoinPathsWithPrefix(aconfigFiles, "--cache "),
+					"version":     strconv.Itoa(storageFilesVersion),
 				},
 			})
 			files = append(files, newApexFile(ctx, outputFile, info.File_type, "etc", etc, nil))
diff --git a/bpf/bpf.go b/bpf/bpf.go
index 3b7073e..3f34382 100644
--- a/bpf/bpf.go
+++ b/bpf/bpf.go
@@ -230,8 +230,6 @@
 		ctx.PackageFile(installDir, obj.Base(), obj)
 	}
 
-	android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: srcs.Strings()})
-
 	ctx.SetOutputFiles(bpf.objs, "")
 }
 
diff --git a/bpf/libbpf/libbpf_prog.go b/bpf/libbpf/libbpf_prog.go
index 3b26d46..44013e5 100644
--- a/bpf/libbpf/libbpf_prog.go
+++ b/bpf/libbpf/libbpf_prog.go
@@ -239,8 +239,6 @@
 		ctx.PackageFile(installDir, obj.Base(), obj)
 	}
 
-	android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: srcs.Strings()})
-
 	ctx.SetOutputFiles(libbpf.objs, "")
 }
 
diff --git a/cc/afdo.go b/cc/afdo.go
index 03dc271..828e494 100644
--- a/cc/afdo.go
+++ b/cc/afdo.go
@@ -65,8 +65,8 @@
 }
 
 func getFdoProfilePathFromDep(ctx ModuleContext) string {
-	fdoProfileDeps := ctx.GetDirectDepsWithTag(FdoProfileTag)
-	if len(fdoProfileDeps) > 0 && fdoProfileDeps[0] != nil {
+	fdoProfileDeps := ctx.GetDirectDepsProxyWithTag(FdoProfileTag)
+	if len(fdoProfileDeps) > 0 {
 		if info, ok := android.OtherModuleProvider(ctx, fdoProfileDeps[0], FdoProfileProvider); ok {
 			return info.Path.String()
 		}
diff --git a/cc/cc.go b/cc/cc.go
index 284ab8b..d8d2a06 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -46,16 +46,72 @@
 var CcMakeVarsInfoProvider = blueprint.NewProvider[*CcMakeVarsInfo]()
 
 type CcObjectInfo struct {
-	objFiles   android.Paths
-	tidyFiles  android.Paths
-	kytheFiles android.Paths
+	ObjFiles   android.Paths
+	TidyFiles  android.Paths
+	KytheFiles android.Paths
 }
 
 var CcObjectInfoProvider = blueprint.NewProvider[CcObjectInfo]()
 
+type AidlInterfaceInfo struct {
+	// list of aidl_interface sources
+	Sources []string
+	// root directory of AIDL sources
+	AidlRoot string
+	// AIDL backend language (e.g. "cpp", "ndk")
+	Lang string
+	// list of flags passed to AIDL generator
+	Flags []string
+}
+
+type CompilerInfo struct {
+	Srcs android.Paths
+	// list of module-specific flags that will be used for C and C++ compiles.
+	Cflags               proptools.Configurable[[]string]
+	AidlInterfaceInfo    AidlInterfaceInfo
+	LibraryDecoratorInfo *LibraryDecoratorInfo
+}
+
+type LinkerInfo struct {
+	WholeStaticLibs proptools.Configurable[[]string]
+	// list of modules that should be statically linked into this module.
+	StaticLibs proptools.Configurable[[]string]
+	// list of modules that should be dynamically linked into this module.
+	SharedLibs proptools.Configurable[[]string]
+	// list of modules that should only provide headers for this module.
+	HeaderLibs           proptools.Configurable[[]string]
+	UnstrippedOutputFile android.Path
+
+	BinaryDecoratorInfo    *BinaryDecoratorInfo
+	LibraryDecoratorInfo   *LibraryDecoratorInfo
+	TestBinaryInfo         *TestBinaryInfo
+	BenchmarkDecoratorInfo *BenchmarkDecoratorInfo
+	ObjectLinkerInfo       *ObjectLinkerInfo
+}
+
+type BinaryDecoratorInfo struct{}
+type LibraryDecoratorInfo struct {
+	ExportIncludeDirs proptools.Configurable[[]string]
+}
+
+type LibraryInfo struct {
+	StubsVersion string
+}
+
+type TestBinaryInfo struct {
+	Gtest bool
+}
+type BenchmarkDecoratorInfo struct{}
+type ObjectLinkerInfo struct{}
+
 // Common info about the cc module.
 type CcInfo struct {
-	HasStubsVariants bool
+	HasStubsVariants       bool
+	IsPrebuilt             bool
+	CmakeSnapshotSupported bool
+	CompilerInfo           *CompilerInfo
+	LinkerInfo             *LinkerInfo
+	LibraryInfo            *LibraryInfo
 }
 
 var CcInfoProvider = blueprint.NewProvider[CcInfo]()
@@ -1194,11 +1250,6 @@
 	return false
 }
 
-func (c *Module) IsRustFFI() bool {
-	// cc modules are not Rust modules
-	return false
-}
-
 func (c *Module) Module() android.Module {
 	return c
 }
@@ -2069,8 +2120,6 @@
 		})
 	}
 
-	android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: deps.GeneratedSources.Strings()})
-
 	if Bool(c.Properties.Cmake_snapshot_supported) {
 		android.SetProvider(ctx, cmakeSnapshotSourcesProvider, android.GlobFiles(ctx, ctx.ModuleDir()+"/**/*", nil))
 	}
@@ -2122,13 +2171,13 @@
 	}
 
 	ccObjectInfo := CcObjectInfo{
-		kytheFiles: objs.kytheFiles,
+		KytheFiles: objs.kytheFiles,
 	}
 	if !ctx.Config().KatiEnabled() || !android.ShouldSkipAndroidMkProcessing(ctx, c) {
-		ccObjectInfo.objFiles = objs.objFiles
-		ccObjectInfo.tidyFiles = objs.tidyFiles
+		ccObjectInfo.ObjFiles = objs.objFiles
+		ccObjectInfo.TidyFiles = objs.tidyFiles
 	}
-	if len(ccObjectInfo.kytheFiles)+len(ccObjectInfo.objFiles)+len(ccObjectInfo.tidyFiles) > 0 {
+	if len(ccObjectInfo.KytheFiles)+len(ccObjectInfo.ObjFiles)+len(ccObjectInfo.TidyFiles) > 0 {
 		android.SetProvider(ctx, CcObjectInfoProvider, ccObjectInfo)
 	}
 
@@ -2136,9 +2185,58 @@
 		StaticExecutable: c.StaticExecutable(),
 	})
 
-	android.SetProvider(ctx, CcInfoProvider, CcInfo{
-		HasStubsVariants: c.HasStubsVariants(),
-	})
+	ccInfo := CcInfo{
+		HasStubsVariants:       c.HasStubsVariants(),
+		IsPrebuilt:             c.IsPrebuilt(),
+		CmakeSnapshotSupported: proptools.Bool(c.Properties.Cmake_snapshot_supported),
+	}
+	if c.compiler != nil {
+		ccInfo.CompilerInfo = &CompilerInfo{
+			Srcs:   c.compiler.(CompiledInterface).Srcs(),
+			Cflags: c.compiler.baseCompilerProps().Cflags,
+			AidlInterfaceInfo: AidlInterfaceInfo{
+				Sources:  c.compiler.baseCompilerProps().AidlInterface.Sources,
+				AidlRoot: c.compiler.baseCompilerProps().AidlInterface.AidlRoot,
+				Lang:     c.compiler.baseCompilerProps().AidlInterface.Lang,
+				Flags:    c.compiler.baseCompilerProps().AidlInterface.Flags,
+			},
+		}
+		switch decorator := c.compiler.(type) {
+		case *libraryDecorator:
+			ccInfo.CompilerInfo.LibraryDecoratorInfo = &LibraryDecoratorInfo{
+				ExportIncludeDirs: decorator.flagExporter.Properties.Export_include_dirs,
+			}
+		}
+	}
+	if c.linker != nil {
+		ccInfo.LinkerInfo = &LinkerInfo{
+			WholeStaticLibs:      c.linker.baseLinkerProps().Whole_static_libs,
+			StaticLibs:           c.linker.baseLinkerProps().Static_libs,
+			SharedLibs:           c.linker.baseLinkerProps().Shared_libs,
+			HeaderLibs:           c.linker.baseLinkerProps().Header_libs,
+			UnstrippedOutputFile: c.UnstrippedOutputFile(),
+		}
+		switch decorator := c.linker.(type) {
+		case *binaryDecorator:
+			ccInfo.LinkerInfo.BinaryDecoratorInfo = &BinaryDecoratorInfo{}
+		case *libraryDecorator:
+			ccInfo.LinkerInfo.LibraryDecoratorInfo = &LibraryDecoratorInfo{}
+		case *testBinary:
+			ccInfo.LinkerInfo.TestBinaryInfo = &TestBinaryInfo{
+				Gtest: decorator.testDecorator.gtest(),
+			}
+		case *benchmarkDecorator:
+			ccInfo.LinkerInfo.BenchmarkDecoratorInfo = &BenchmarkDecoratorInfo{}
+		case *objectLinker:
+			ccInfo.LinkerInfo.ObjectLinkerInfo = &ObjectLinkerInfo{}
+		}
+	}
+	if c.library != nil {
+		ccInfo.LibraryInfo = &LibraryInfo{
+			StubsVersion: c.library.stubsVersion(),
+		}
+	}
+	android.SetProvider(ctx, CcInfoProvider, ccInfo)
 
 	c.setOutputFiles(ctx)
 
@@ -2172,7 +2270,7 @@
 	complianceMetadataInfo.SetStringValue(android.ComplianceMetadataProp.BUILT_FILES, c.outputFile.String())
 
 	// Static deps
-	staticDeps := ctx.GetDirectDepsWithTag(StaticDepTag(false))
+	staticDeps := ctx.GetDirectDepsProxyWithTag(StaticDepTag(false))
 	staticDepNames := make([]string, 0, len(staticDeps))
 	for _, dep := range staticDeps {
 		staticDepNames = append(staticDepNames, dep.Name())
@@ -2186,7 +2284,7 @@
 	complianceMetadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEP_FILES, android.FirstUniqueStrings(staticDepPaths))
 
 	// Whole static deps
-	wholeStaticDeps := ctx.GetDirectDepsWithTag(StaticDepTag(true))
+	wholeStaticDeps := ctx.GetDirectDepsProxyWithTag(StaticDepTag(true))
 	wholeStaticDepNames := make([]string, 0, len(wholeStaticDeps))
 	for _, dep := range wholeStaticDeps {
 		wholeStaticDepNames = append(wholeStaticDepNames, dep.Name())
@@ -3993,7 +4091,7 @@
 func (ks *kytheExtractAllSingleton) GenerateBuildActions(ctx android.SingletonContext) {
 	var xrefTargets android.Paths
 	ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
-		files := android.OtherModuleProviderOrDefault(ctx, module, CcObjectInfoProvider).kytheFiles
+		files := android.OtherModuleProviderOrDefault(ctx, module, CcObjectInfoProvider).KytheFiles
 		if len(files) > 0 {
 			xrefTargets = append(xrefTargets, files...)
 		}
diff --git a/cc/cmake_module_aidl.txt b/cc/cmake_module_aidl.txt
index 84755a3..3622648 100644
--- a/cc/cmake_module_aidl.txt
+++ b/cc/cmake_module_aidl.txt
@@ -1,11 +1,11 @@
 # <<.M.Name>>
 
-<<setList .M.Name "_SRCS" "" (getAidlSources .M)>>
+<<setList .M.Name "_SRCS" "" (getAidlSources .CcInfo)>>
 
-<<setList .M.Name "_AIDLFLAGS" "" (getCompilerProperties .M).AidlInterface.Flags>>
+<<setList .M.Name "_AIDLFLAGS" "" (getAidlInterface .CcInfo).Flags>>
 
-add_aidl_library(<<.M.Name>> <<(getCompilerProperties .M).AidlInterface.Lang>>
-    "${ANDROID_BUILD_TOP}/<<.Ctx.OtherModuleDir .M>>/<<(getCompilerProperties .M).AidlInterface.AidlRoot>>"
+add_aidl_library(<<.M.Name>> <<(getAidlInterface .CcInfo).Lang>>
+    "${ANDROID_BUILD_TOP}/<<.Ctx.OtherModuleDir .M>>/<<(getAidlInterface .CcInfo).AidlRoot>>"
     "${<<.M.Name>>_SRCS}"
     "${<<.M.Name>>_AIDLFLAGS}")
 add_library(android::<<.M.Name>> ALIAS <<.M.Name>>)
diff --git a/cc/cmake_module_cc.txt b/cc/cmake_module_cc.txt
index 0f6e62f..a57e053 100644
--- a/cc/cmake_module_cc.txt
+++ b/cc/cmake_module_cc.txt
@@ -1,14 +1,14 @@
-<<$srcs := getSources .M>>
-<<$includeDirs := getIncludeDirs .Ctx .M>>
-<<$cflags := getCflagsProperty .Ctx .M>>
+<<$srcs := getSources .Ctx .CcInfo>>
+<<$includeDirs := getIncludeDirs .Ctx .M .CcInfo>>
+<<$cflags := getCflagsProperty .Ctx .CcInfo>>
 <<$deps := mapLibraries .Ctx .M (concat5
-(getWholeStaticLibsProperty .Ctx .M)
-(getStaticLibsProperty .Ctx .M)
-(getSharedLibsProperty .Ctx .M)
-(getHeaderLibsProperty .Ctx .M)
-(getExtraLibs .M)
+(getWholeStaticLibsProperty .Ctx .CcInfo)
+(getStaticLibsProperty .Ctx .CcInfo)
+(getSharedLibsProperty .Ctx .CcInfo)
+(getHeaderLibsProperty .Ctx .CcInfo)
+(getExtraLibs .CcInfo)
 ) .Pprop.LibraryMapping>>
-<<$moduleType := getModuleType .M>>
+<<$moduleType := getModuleType .CcInfo>>
 <<$moduleTypeCmake := "executable">>
 <<if eq $moduleType "library">>
 <<$moduleTypeCmake = "library">>
diff --git a/cc/cmake_snapshot.go b/cc/cmake_snapshot.go
index f553f27..a40b863 100644
--- a/cc/cmake_snapshot.go
+++ b/cc/cmake_snapshot.go
@@ -196,39 +196,36 @@
 
 			return list.String()
 		},
-		"getSources": func(m *Module) android.Paths {
-			return m.compiler.(CompiledInterface).Srcs()
+		"getSources": func(ctx android.ModuleContext, info *CcInfo) android.Paths {
+			return info.CompilerInfo.Srcs
 		},
 		"getModuleType": getModuleType,
-		"getCompilerProperties": func(m *Module) BaseCompilerProperties {
-			return m.compiler.baseCompilerProps()
+		"getAidlInterface": func(info *CcInfo) AidlInterfaceInfo {
+			return info.CompilerInfo.AidlInterfaceInfo
 		},
-		"getCflagsProperty": func(ctx android.ModuleContext, m *Module) []string {
-			prop := m.compiler.baseCompilerProps().Cflags
+		"getCflagsProperty": func(ctx android.ModuleContext, info *CcInfo) []string {
+			prop := info.CompilerInfo.Cflags
 			return prop.GetOrDefault(ctx, nil)
 		},
-		"getLinkerProperties": func(m *Module) BaseLinkerProperties {
-			return m.linker.baseLinkerProps()
-		},
-		"getWholeStaticLibsProperty": func(ctx android.ModuleContext, m *Module) []string {
-			prop := m.linker.baseLinkerProps().Whole_static_libs
+		"getWholeStaticLibsProperty": func(ctx android.ModuleContext, info *CcInfo) []string {
+			prop := info.LinkerInfo.WholeStaticLibs
 			return prop.GetOrDefault(ctx, nil)
 		},
-		"getStaticLibsProperty": func(ctx android.ModuleContext, m *Module) []string {
-			prop := m.linker.baseLinkerProps().Static_libs
+		"getStaticLibsProperty": func(ctx android.ModuleContext, info *CcInfo) []string {
+			prop := info.LinkerInfo.StaticLibs
 			return prop.GetOrDefault(ctx, nil)
 		},
-		"getSharedLibsProperty": func(ctx android.ModuleContext, m *Module) []string {
-			prop := m.linker.baseLinkerProps().Shared_libs
+		"getSharedLibsProperty": func(ctx android.ModuleContext, info *CcInfo) []string {
+			prop := info.LinkerInfo.SharedLibs
 			return prop.GetOrDefault(ctx, nil)
 		},
-		"getHeaderLibsProperty": func(ctx android.ModuleContext, m *Module) []string {
-			prop := m.linker.baseLinkerProps().Header_libs
+		"getHeaderLibsProperty": func(ctx android.ModuleContext, info *CcInfo) []string {
+			prop := info.LinkerInfo.HeaderLibs
 			return prop.GetOrDefault(ctx, nil)
 		},
 		"getExtraLibs":   getExtraLibs,
 		"getIncludeDirs": getIncludeDirs,
-		"mapLibraries": func(ctx android.ModuleContext, m *Module, libs []string, mapping map[string]LibraryMappingProperty) []string {
+		"mapLibraries": func(ctx android.ModuleContext, m android.ModuleProxy, libs []string, mapping map[string]LibraryMappingProperty) []string {
 			var mappedLibs []string
 			for _, lib := range libs {
 				mappedLib, exists := mapping[lib]
@@ -249,8 +246,8 @@
 			mappedLibs = slices.Compact(mappedLibs)
 			return mappedLibs
 		},
-		"getAidlSources": func(m *Module) []string {
-			aidlInterface := m.compiler.baseCompilerProps().AidlInterface
+		"getAidlSources": func(info *CcInfo) []string {
+			aidlInterface := info.CompilerInfo.AidlInterfaceInfo
 			aidlRoot := aidlInterface.AidlRoot + string(filepath.Separator)
 			if aidlInterface.AidlRoot == "" {
 				aidlRoot = ""
@@ -340,14 +337,14 @@
 	moduleDirs := map[string][]string{}
 	sourceFiles := map[string]android.Path{}
 	visitedModules := map[string]bool{}
-	var pregeneratedModules []*Module
-	ctx.WalkDeps(func(dep_a android.Module, parent android.Module) bool {
-		moduleName := ctx.OtherModuleName(dep_a)
+	var pregeneratedModules []android.ModuleProxy
+	ctx.WalkDepsProxy(func(dep, parent android.ModuleProxy) bool {
+		moduleName := ctx.OtherModuleName(dep)
 		if visited := visitedModules[moduleName]; visited {
 			return false // visit only once
 		}
 		visitedModules[moduleName] = true
-		dep, ok := dep_a.(*Module)
+		ccInfo, ok := android.OtherModuleProvider(ctx, dep, CcInfoProvider)
 		if !ok {
 			return false // not a cc module
 		}
@@ -363,15 +360,15 @@
 		if slices.Contains(ignoredSystemLibs, moduleName) {
 			return false // system libs built in-tree for Android
 		}
-		if dep.IsPrebuilt() {
+		if ccInfo.IsPrebuilt {
 			return false // prebuilts are not supported
 		}
-		if dep.compiler == nil {
+		if ccInfo.CompilerInfo == nil {
 			return false // unsupported module type
 		}
-		isAidlModule := dep.compiler.baseCompilerProps().AidlInterface.Lang != ""
+		isAidlModule := ccInfo.CompilerInfo.AidlInterfaceInfo.Lang != ""
 
-		if !proptools.Bool(dep.Properties.Cmake_snapshot_supported) {
+		if !ccInfo.CmakeSnapshotSupported {
 			ctx.OtherModulePropertyErrorf(dep, "cmake_snapshot_supported",
 				"CMake snapshots not supported, despite being a dependency for %s",
 				ctx.OtherModuleName(parent))
@@ -389,12 +386,14 @@
 		}
 		moduleFragment := executeTemplate(templateToUse, &templateBuffer, struct {
 			Ctx      *android.ModuleContext
-			M        *Module
+			M        android.ModuleProxy
+			CcInfo   *CcInfo
 			Snapshot *CmakeSnapshot
 			Pprop    *cmakeProcessedProperties
 		}{
 			&ctx,
 			dep,
+			&ccInfo,
 			m,
 			&pprop,
 		})
@@ -415,7 +414,7 @@
 	// Enumerate sources for pregenerated modules
 	if m.Properties.Include_sources {
 		for _, dep := range pregeneratedModules {
-			if !proptools.Bool(dep.Properties.Cmake_snapshot_supported) {
+			if !android.OtherModuleProviderOrDefault(ctx, dep, CcInfoProvider).CmakeSnapshotSupported {
 				ctx.OtherModulePropertyErrorf(dep, "cmake_snapshot_supported",
 					"Pregenerated CMake snapshots not supported, despite being requested for %s",
 					ctx.ModuleName())
@@ -491,7 +490,7 @@
 	if len(m.Properties.Prebuilts) > 0 {
 		var prebuiltsList android.Paths
 
-		ctx.VisitDirectDepsWithTag(cmakeSnapshotPrebuiltTag, func(dep android.Module) {
+		ctx.VisitDirectDepsProxyWithTag(cmakeSnapshotPrebuiltTag, func(dep android.ModuleProxy) {
 			for _, file := range android.OtherModuleProviderOrDefault(
 				ctx, dep, android.InstallFilesProvider).InstallFiles {
 				prebuiltsList = append(prebuiltsList, file)
@@ -523,42 +522,37 @@
 	}}
 }
 
-func getModuleType(m *Module) string {
-	switch m.linker.(type) {
-	case *binaryDecorator:
+func getModuleType(info *CcInfo) string {
+	if info.LinkerInfo.BinaryDecoratorInfo != nil {
 		return "executable"
-	case *libraryDecorator:
+	} else if info.LinkerInfo.LibraryDecoratorInfo != nil {
 		return "library"
-	case *testBinary:
+	} else if info.LinkerInfo.TestBinaryInfo != nil || info.LinkerInfo.BenchmarkDecoratorInfo != nil {
 		return "test"
-	case *benchmarkDecorator:
-		return "test"
-	case *objectLinker:
+	} else if info.LinkerInfo.ObjectLinkerInfo != nil {
 		return "object"
 	}
-	panic(fmt.Sprintf("Unexpected module type: %T", m.linker))
+	panic(fmt.Sprintf("Unexpected module type for LinkerInfo"))
 }
 
-func getExtraLibs(m *Module) []string {
-	switch decorator := m.linker.(type) {
-	case *testBinary:
-		if decorator.testDecorator.gtest() {
+func getExtraLibs(info *CcInfo) []string {
+	if info.LinkerInfo.TestBinaryInfo != nil {
+		if info.LinkerInfo.TestBinaryInfo.Gtest {
 			return []string{
 				"libgtest",
 				"libgtest_main",
 			}
 		}
-	case *benchmarkDecorator:
+	} else if info.LinkerInfo.BenchmarkDecoratorInfo != nil {
 		return []string{"libgoogle-benchmark"}
 	}
 	return nil
 }
 
-func getIncludeDirs(ctx android.ModuleContext, m *Module) []string {
+func getIncludeDirs(ctx android.ModuleContext, m android.ModuleProxy, info *CcInfo) []string {
 	moduleDir := ctx.OtherModuleDir(m) + string(filepath.Separator)
-	switch decorator := m.compiler.(type) {
-	case *libraryDecorator:
-		return sliceWithPrefix(moduleDir, decorator.flagExporter.Properties.Export_include_dirs.GetOrDefault(ctx, nil))
+	if info.CompilerInfo.LibraryDecoratorInfo != nil {
+		return sliceWithPrefix(moduleDir, info.CompilerInfo.LibraryDecoratorInfo.ExportIncludeDirs.GetOrDefault(ctx, nil))
 	}
 	return nil
 }
diff --git a/cc/compiler.go b/cc/compiler.go
index 91f107c..f2bced1 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -367,7 +367,7 @@
 	modulePath := ctx.ModuleDir()
 
 	reuseObjs := false
-	if len(ctx.GetDirectDepsWithTag(reuseObjTag)) > 0 {
+	if len(ctx.GetDirectDepsProxyWithTag(reuseObjTag)) > 0 {
 		reuseObjs = true
 	}
 
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 26ac7d1..911a81c 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -288,7 +288,7 @@
 }
 
 func (fuzzBin *fuzzBinary) install(ctx ModuleContext, file android.Path) {
-	fuzzBin.fuzzPackagedModule = PackageFuzzModule(ctx, fuzzBin.fuzzPackagedModule, pctx)
+	fuzzBin.fuzzPackagedModule = PackageFuzzModule(ctx, fuzzBin.fuzzPackagedModule)
 
 	installBase := "fuzz"
 
@@ -345,7 +345,7 @@
 	fuzzBin.binaryDecorator.baseInstaller.install(ctx, file)
 }
 
-func PackageFuzzModule(ctx android.ModuleContext, fuzzPackagedModule fuzz.FuzzPackagedModule, pctx android.PackageContext) fuzz.FuzzPackagedModule {
+func PackageFuzzModule(ctx android.ModuleContext, fuzzPackagedModule fuzz.FuzzPackagedModule) fuzz.FuzzPackagedModule {
 	fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, fuzzPackagedModule.FuzzProperties.Corpus)
 	fuzzPackagedModule.Corpus = append(fuzzPackagedModule.Corpus, android.PathsForModuleSrc(ctx, fuzzPackagedModule.FuzzProperties.Device_common_corpus)...)
 
@@ -638,7 +638,7 @@
 	ctx.WalkDeps(func(child, parent android.Module) bool {
 
 		// If this is a Rust module which is not rust_ffi_shared, we still want to bundle any transitive
-		// shared dependencies (even for rust_ffi_rlib or rust_ffi_static)
+		// shared dependencies (even for rust_ffi_static)
 		if rustmod, ok := child.(LinkableInterface); ok && rustmod.RustLibraryInterface() && !rustmod.Shared() {
 			if recursed[ctx.OtherModuleName(child)] {
 				return false
diff --git a/cc/library.go b/cc/library.go
index a3a2f5c..c9114fd 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -1216,7 +1216,7 @@
 // Visits the stub variants of the library and returns a struct containing the stub .so paths
 func addStubDependencyProviders(ctx ModuleContext) []SharedStubLibrary {
 	stubsInfo := []SharedStubLibrary{}
-	stubs := ctx.GetDirectDepsWithTag(stubImplDepTag)
+	stubs := ctx.GetDirectDepsProxyWithTag(stubImplDepTag)
 	if len(stubs) > 0 {
 		for _, stub := range stubs {
 			stubInfo, ok := android.OtherModuleProvider(ctx, stub, SharedLibraryInfoProvider)
@@ -1225,8 +1225,12 @@
 				continue
 			}
 			flagInfo, _ := android.OtherModuleProvider(ctx, stub, FlagExporterInfoProvider)
+			ccInfo, ok := android.OtherModuleProvider(ctx, stub, CcInfoProvider)
+			if !ok || ccInfo.LibraryInfo == nil {
+				panic(fmt.Errorf("couldn't find library info for %s", stub))
+			}
 			stubsInfo = append(stubsInfo, SharedStubLibrary{
-				Version:           moduleLibraryInterface(stub).stubsVersion(),
+				Version:           ccInfo.LibraryInfo.StubsVersion,
 				SharedLibraryInfo: stubInfo,
 				FlagExporterInfo:  flagInfo,
 			})
@@ -2122,7 +2126,7 @@
 		} else {
 			// Header only
 		}
-	} else if library, ok := ctx.Module().(LinkableInterface); ok && (library.CcLibraryInterface() || library.RustLibraryInterface()) {
+	} else if library, ok := ctx.Module().(LinkableInterface); ok && (library.CcLibraryInterface()) {
 		// Non-cc.Modules may need an empty variant for their mutators.
 		variations := []string{}
 		if library.NonCcVariants() {
@@ -2177,7 +2181,7 @@
 		}
 		buildStatic := library.BuildStaticVariant() && !isLLNDK
 		buildShared := library.BuildSharedVariant()
-		if library.BuildRlibVariant() && library.IsRustFFI() && !buildStatic && (incomingVariation == "static" || incomingVariation == "") {
+		if library.BuildRlibVariant() && !buildStatic && (incomingVariation == "static" || incomingVariation == "") {
 			// Rust modules do not build static libs, but rlibs are used as if they
 			// were via `static_libs`. Thus we need to alias the BuildRlibVariant
 			// to "static" for Rust FFI libraries.
diff --git a/cc/linkable.go b/cc/linkable.go
index 1a9a9ab..78ea71c 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -102,9 +102,6 @@
 	IsPrebuilt() bool
 	Toc() android.OptionalPath
 
-	// IsRustFFI returns true if this is a Rust FFI library.
-	IsRustFFI() bool
-
 	// IsFuzzModule returns true if this a *_fuzz module.
 	IsFuzzModule() bool
 
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 2411614..197a4b2 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -296,20 +296,20 @@
 }
 
 func (this *stubDecorator) findImplementationLibrary(ctx ModuleContext) android.Path {
-	dep := ctx.GetDirectDepWithTag(strings.TrimSuffix(ctx.ModuleName(), ndkLibrarySuffix),
+	dep := ctx.GetDirectDepProxyWithTag(strings.TrimSuffix(ctx.ModuleName(), ndkLibrarySuffix),
 		stubImplementation)
 	if dep == nil {
-		ctx.ModuleErrorf("Could not find implementation for stub")
+		ctx.ModuleErrorf("Could not find implementation for stub: ")
 		return nil
 	}
-	impl, ok := dep.(*Module)
+	info, ok := android.OtherModuleProvider(ctx, *dep, CcInfoProvider)
 	if !ok {
 		ctx.ModuleErrorf("Implementation for stub is not correct module type")
 		return nil
 	}
-	output := impl.UnstrippedOutputFile()
+	output := info.LinkerInfo.UnstrippedOutputFile
 	if output == nil {
-		ctx.ModuleErrorf("implementation module (%s) has no output", impl)
+		ctx.ModuleErrorf("implementation module (%s) has no output", *dep)
 		return nil
 	}
 
diff --git a/cc/tidy.go b/cc/tidy.go
index 6481b95..18e6f35 100644
--- a/cc/tidy.go
+++ b/cc/tidy.go
@@ -222,8 +222,8 @@
 	ctx.VisitAllModuleVariantProxies(module, func(variant android.ModuleProxy) {
 		osName := android.OtherModuleProviderOrDefault(ctx, variant, android.CommonModuleInfoKey).CompileTarget.Os.Name
 		info := android.OtherModuleProviderOrDefault(ctx, variant, CcObjectInfoProvider)
-		addToOSGroup(osName, info.objFiles, allObjFileGroups, subsetObjFileGroups)
-		addToOSGroup(osName, info.tidyFiles, allTidyFileGroups, subsetTidyFileGroups)
+		addToOSGroup(osName, info.ObjFiles, allObjFileGroups, subsetObjFileGroups)
+		addToOSGroup(osName, info.TidyFiles, allTidyFileGroups, subsetTidyFileGroups)
 	})
 
 	// (2) Add an all-OS group, with "" or "subset" name, to include all os-specific phony targets.
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index c119823..7926292 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -197,7 +197,7 @@
 	rbeMetricsFile := filepath.Join(logsDir, c.logsPrefix+"rbe_metrics.pb")
 	soongBuildMetricsFile := filepath.Join(logsDir, c.logsPrefix+"soong_build_metrics.pb")
 	buildTraceFile := filepath.Join(logsDir, c.logsPrefix+"build.trace.gz")
-	executionMetricsFile := filepath.Join(logsDir, c.logsPrefix+"soong_execution_metrics.pb")
+	executionMetricsFile := filepath.Join(logsDir, c.logsPrefix+"execution_metrics.pb")
 
 	metricsFiles := []string{
 		buildErrorFile,        // build error strings
diff --git a/etc/avbpubkey.go b/etc/avbpubkey.go
index 3f998d4..dc242ce 100644
--- a/etc/avbpubkey.go
+++ b/etc/avbpubkey.go
@@ -51,6 +51,7 @@
 		Command: `${avbtool} extract_public_key --key ${in} --output ${out}.tmp` +
 			` && ( if cmp -s ${out}.tmp ${out} ; then rm ${out}.tmp ; else mv ${out}.tmp ${out} ; fi )`,
 		CommandDeps: []string{"${avbtool}"},
+		Restat:      true,
 		Description: "Extracting system_other avb key",
 	})
 
diff --git a/filesystem/aconfig_files.go b/filesystem/aconfig_files.go
index 492ec69..9a3ca54 100644
--- a/filesystem/aconfig_files.go
+++ b/filesystem/aconfig_files.go
@@ -16,6 +16,7 @@
 
 import (
 	"android/soong/android"
+	"strconv"
 
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
@@ -74,6 +75,12 @@
 	installAconfigStorageDir := dir.Join(ctx, "etc", "aconfig")
 	builder.Command().Text("mkdir -p").Text(installAconfigStorageDir.String())
 
+	// To enable fingerprint, we need to have v2 storage files. The default version is 1.
+	storageFilesVersion := 1
+	if ctx.Config().ReleaseFingerprintAconfigPackages() {
+		storageFilesVersion = 2
+	}
+
 	generatePartitionAconfigStorageFile := func(fileType, fileName string) {
 		outputPath := installAconfigStorageDir.Join(ctx, fileName)
 		builder.Command().
@@ -81,7 +88,8 @@
 			FlagWithArg("create-storage --container ", container).
 			FlagWithArg("--file ", fileType).
 			FlagWithOutput("--out ", outputPath).
-			FlagWithArg("--cache ", installAconfigFlagsPath.String())
+			FlagWithArg("--cache ", installAconfigFlagsPath.String()).
+			FlagWithArg("--version ", strconv.Itoa(storageFilesVersion))
 		f.appendToEntry(ctx, outputPath)
 	}
 
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 7ffdf69..2244aff 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -537,6 +537,12 @@
 		builder.Command().Text("ln -sf").Text(proptools.ShellEscape(target)).Text(dst.String())
 		f.appendToEntry(ctx, dst)
 	}
+
+	// https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=2835;drc=b186569ef00ff2f2a1fab28aedc75ebc32bcd67b
+	if f.partitionName() == "recovery" {
+		builder.Command().Text("mkdir -p").Text(rootDir.Join(ctx, "root/linkerconfig").String())
+		builder.Command().Text("touch").Text(rootDir.Join(ctx, "root/linkerconfig/ld.config.txt").String())
+	}
 }
 
 func (f *filesystem) copyPackagingSpecs(ctx android.ModuleContext, builder *android.RuleBuilder, specs map[string]android.PackagingSpec, rootDir, rebasedDir android.WritablePath) []string {
diff --git a/fsgen/config.go b/fsgen/config.go
index 31f721b..a217600 100644
--- a/fsgen/config.go
+++ b/fsgen/config.go
@@ -110,7 +110,6 @@
 	// filesystem module.
 	commonPartitionDirs = []string{
 		// From generic_rootdirs in build/make/target/product/generic/Android.bp
-		"acct",
 		"apex",
 		"bootstrap-apex",
 		"config",
diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go
index 4e1ca9e..59470d3 100644
--- a/fsgen/filesystem_creator.go
+++ b/fsgen/filesystem_creator.go
@@ -599,12 +599,14 @@
 		Stem           *string
 		Product_config *string
 		Android_info   *string
+		Licenses       []string
 	}{
 		Name:           proptools.StringPtr(generatedModuleName(ctx.Config(), "vendor-build.prop")),
 		Vendor:         proptools.BoolPtr(true),
 		Stem:           proptools.StringPtr("build.prop"),
 		Product_config: proptools.StringPtr(":product_config"),
 		Android_info:   proptools.StringPtr(":" + androidInfoProp.Name()),
+		Licenses:       []string{"Android-Apache-2.0"},
 	}
 	vendorBuildProp := ctx.CreateModule(
 		android.BuildPropFactory,
@@ -763,8 +765,9 @@
 	}
 
 	fsProps.Is_auto_generated = proptools.BoolPtr(true)
-	// TODO(b/381120092): Verify mount_point for system partition
-	fsProps.Mount_point = proptools.StringPtr(partitionType)
+	if partitionType != "system" {
+		fsProps.Mount_point = proptools.StringPtr(partitionType)
+	}
 
 	partitionSpecificFsProps(ctx, fsProps, partitionVars, partitionType)
 
diff --git a/genrule/genrule.go b/genrule/genrule.go
index ac62b8d..6137c70 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -455,7 +455,6 @@
 	srcFiles = append(srcFiles, addLabelsForInputs("device_first_srcs", g.properties.Device_first_srcs.GetOrDefault(ctx, nil), nil)...)
 	srcFiles = append(srcFiles, addLabelsForInputs("device_common_srcs", g.properties.Device_common_srcs.GetOrDefault(ctx, nil), nil)...)
 	srcFiles = append(srcFiles, addLabelsForInputs("common_os_srcs", g.properties.Common_os_srcs.GetOrDefault(ctx, nil), nil)...)
-	android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: srcFiles.Strings()})
 
 	var copyFrom android.Paths
 	var outputFiles android.WritablePaths
diff --git a/genrule/genrule_test.go b/genrule/genrule_test.go
index f190750..688db07 100644
--- a/genrule/genrule_test.go
+++ b/genrule/genrule_test.go
@@ -24,7 +24,6 @@
 
 	"android/soong/android"
 
-	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
 )
 
@@ -694,13 +693,6 @@
 
 	expectedCmd := "cp in1 __SBOX_SANDBOX_DIR__/out/out"
 	android.AssertStringEquals(t, "cmd", expectedCmd, gen.rawCommands[0])
-
-	srcsFileProvider, ok := android.OtherModuleProvider(result.TestContext, gen, blueprint.SrcsFileProviderKey)
-	if !ok {
-		t.Fatal("Expected genrule to have a SrcsFileProviderData, but did not")
-	}
-	expectedSrcs := []string{"in1"}
-	android.AssertDeepEquals(t, "srcs", expectedSrcs, srcsFileProvider.SrcPaths)
 }
 
 func TestGenruleAllowMissingDependencies(t *testing.T) {
diff --git a/java/aar.go b/java/aar.go
index d9a8c0e..c09ed9e 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -1046,6 +1046,8 @@
 		AconfigTextFiles: aconfigTextFilePaths,
 	})
 
+	android.SetProvider(ctx, AndroidLibraryInfoProvider, AndroidLibraryInfo{})
+
 	a.setOutputFiles(ctx)
 }
 
@@ -1574,6 +1576,8 @@
 		JniPackages: a.jniPackages,
 	})
 
+	android.SetProvider(ctx, AndroidLibraryInfoProvider, AndroidLibraryInfo{})
+
 	ctx.SetOutputFiles([]android.Path{a.implementationAndResourcesJarFile}, "")
 	ctx.SetOutputFiles([]android.Path{a.aarPath}, ".aar")
 }
diff --git a/java/app.go b/java/app.go
index b8c85fb..b0dcbb0 100644
--- a/java/app.go
+++ b/java/app.go
@@ -52,6 +52,12 @@
 
 var FlagsPackagesProvider = blueprint.NewProvider[FlagsPackages]()
 
+type AndroidLibraryInfo struct {
+	// Empty for now
+}
+
+var AndroidLibraryInfoProvider = blueprint.NewProvider[AndroidLibraryInfo]()
+
 func RegisterAppBuildComponents(ctx android.RegistrationContext) {
 	ctx.RegisterModuleType("android_app", AndroidAppFactory)
 	ctx.RegisterModuleType("android_test", AndroidTestFactory)
@@ -424,6 +430,8 @@
 		EmbeddedJNILibs: embeddedJniLibs,
 	})
 
+	android.SetProvider(ctx, AndroidLibraryInfoProvider, AndroidLibraryInfo{})
+
 	a.requiredModuleNames = a.getRequiredModuleNames(ctx)
 }
 
diff --git a/java/base.go b/java/base.go
index 18a875b..5c1ef85 100644
--- a/java/base.go
+++ b/java/base.go
@@ -1241,7 +1241,6 @@
 	uniqueSrcFiles = append(uniqueSrcFiles, uniqueJavaFiles...)
 	uniqueSrcFiles = append(uniqueSrcFiles, uniqueKtFiles...)
 	j.uniqueSrcFiles = uniqueSrcFiles
-	android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: uniqueSrcFiles.Strings()})
 
 	// We don't currently run annotation processors in turbine, which means we can't use turbine
 	// generated header jars when an annotation processor that generates API is enabled.  One
diff --git a/java/fuzz.go b/java/fuzz.go
index dba8815..79cd042 100644
--- a/java/fuzz.go
+++ b/java/fuzz.go
@@ -107,7 +107,7 @@
 }
 
 func (j *JavaFuzzTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	j.fuzzPackagedModule = cc.PackageFuzzModule(ctx, j.fuzzPackagedModule, pctx)
+	j.fuzzPackagedModule = cc.PackageFuzzModule(ctx, j.fuzzPackagedModule)
 
 	_, sharedDeps := cc.CollectAllSharedDependencies(ctx)
 	for _, dep := range sharedDeps {
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 991f847..a0affe0 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1479,7 +1479,6 @@
 				ctx.CheckbuildFile(installFilesInfo.CheckbuildTarget)
 			}
 		}
-		android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: module.implLibraryModule.uniqueSrcFiles.Strings()})
 	}
 
 	// Make the set of components exported by this module available for use elsewhere.
diff --git a/python/python.go b/python/python.go
index d3e5743..be9411b 100644
--- a/python/python.go
+++ b/python/python.go
@@ -447,7 +447,6 @@
 // GenerateAndroidBuildActions performs build actions common to all Python modules
 func (p *PythonLibraryModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	expandedSrcs := android.PathsForModuleSrcExcludes(ctx, p.properties.Srcs, p.properties.Exclude_srcs)
-	android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: expandedSrcs.Strings()})
 	// Keep before any early returns.
 	android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
 		TestOnly:       Bool(p.sourceProperties.Test_only),
diff --git a/rust/benchmark.go b/rust/benchmark.go
index 8c3e515..eaa2176 100644
--- a/rust/benchmark.go
+++ b/rust/benchmark.go
@@ -89,7 +89,7 @@
 	return rlibAutoDep
 }
 
-func (benchmark *benchmarkDecorator) stdLinkage(ctx *depsContext) RustLinkage {
+func (benchmark *benchmarkDecorator) stdLinkage(device bool) RustLinkage {
 	return RlibLinkage
 }
 
diff --git a/rust/binary.go b/rust/binary.go
index cba29a0..d22041b 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -165,11 +165,11 @@
 	}
 }
 
-func (binary *binaryDecorator) stdLinkage(ctx *depsContext) RustLinkage {
+func (binary *binaryDecorator) stdLinkage(device bool) RustLinkage {
 	if binary.preferRlib() {
 		return RlibLinkage
 	}
-	return binary.baseCompiler.stdLinkage(ctx)
+	return binary.baseCompiler.stdLinkage(device)
 }
 
 func (binary *binaryDecorator) binary() bool {
diff --git a/rust/compiler.go b/rust/compiler.go
index fd86917..b93019b 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -30,9 +30,8 @@
 type RustLinkage int
 
 const (
-	DefaultLinkage RustLinkage = iota
+	DylibLinkage RustLinkage = iota
 	RlibLinkage
-	DylibLinkage
 )
 
 type compiler interface {
@@ -69,7 +68,7 @@
 	Disabled() bool
 	SetDisabled()
 
-	stdLinkage(ctx *depsContext) RustLinkage
+	stdLinkage(device bool) RustLinkage
 	noStdlibs() bool
 
 	unstrippedOutputFilePath() android.Path
@@ -316,11 +315,11 @@
 	return aliases
 }
 
-func (compiler *baseCompiler) stdLinkage(ctx *depsContext) RustLinkage {
+func (compiler *baseCompiler) stdLinkage(device bool) RustLinkage {
 	// For devices, we always link stdlibs in as dylibs by default.
 	if compiler.preferRlib() {
 		return RlibLinkage
-	} else if ctx.Device() {
+	} else if device {
 		return DylibLinkage
 	} else {
 		return RlibLinkage
diff --git a/rust/config/global.go b/rust/config/global.go
index 8e06c8d..66ffc0b 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -25,7 +25,7 @@
 var (
 	pctx = android.NewPackageContext("android/soong/rust/config")
 
-	RustDefaultVersion = "1.82.0"
+	RustDefaultVersion = "1.81.0"
 	RustDefaultBase    = "prebuilts/rust/"
 	DefaultEdition     = "2021"
 	Stdlibs            = []string{
diff --git a/rust/fuzz.go b/rust/fuzz.go
index 1770d2e..9e8efd7 100644
--- a/rust/fuzz.go
+++ b/rust/fuzz.go
@@ -121,7 +121,7 @@
 	return out
 }
 
-func (fuzzer *fuzzDecorator) stdLinkage(ctx *depsContext) RustLinkage {
+func (fuzzer *fuzzDecorator) stdLinkage(device bool) RustLinkage {
 	return RlibLinkage
 }
 
@@ -130,7 +130,7 @@
 }
 
 func (fuzz *fuzzDecorator) install(ctx ModuleContext) {
-	fuzz.fuzzPackagedModule = cc.PackageFuzzModule(ctx, fuzz.fuzzPackagedModule, pctx)
+	fuzz.fuzzPackagedModule = cc.PackageFuzzModule(ctx, fuzz.fuzzPackagedModule)
 
 	installBase := "fuzz"
 
diff --git a/rust/fuzz_test.go b/rust/fuzz_test.go
index 6cb8b93..3598c99 100644
--- a/rust/fuzz_test.go
+++ b/rust/fuzz_test.go
@@ -145,6 +145,6 @@
 		t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_static ('libcc_transitive_dep'): %#v", fuzz_static_libtest.FuzzSharedLibraries().String())
 	}
 	if !strings.Contains(fuzz_staticffi_libtest.FuzzSharedLibraries().String(), ":libcc_transitive_dep.so") {
-		t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_rlib ('libcc_transitive_dep'): %#v", fuzz_staticffi_libtest.FuzzSharedLibraries().String())
+		t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_static ('libcc_transitive_dep'): %#v", fuzz_staticffi_libtest.FuzzSharedLibraries().String())
 	}
 }
diff --git a/rust/image_test.go b/rust/image_test.go
index d84eb10..0581fa7 100644
--- a/rust/image_test.go
+++ b/rust/image_test.go
@@ -22,14 +22,13 @@
 	"android/soong/cc"
 )
 
-// Test that cc modules can depend on vendor_available rust_ffi_rlib/rust_ffi_static libraries.
+// Test that cc modules can depend on vendor_available rust_ffi_static libraries.
 func TestVendorLinkage(t *testing.T) {
 	ctx := testRust(t, `
 			cc_binary {
 				name: "fizz_vendor_available",
 				static_libs: [
 					"libfoo_vendor",
-					"libfoo_vendor_static"
 				],
 				vendor_available: true,
 			}
@@ -38,14 +37,8 @@
 				static_libs: ["libfoo_vendor"],
 				soc_specific: true,
 			}
-			rust_ffi_rlib {
-				name: "libfoo_vendor",
-				crate_name: "foo",
-				srcs: ["foo.rs"],
-				vendor_available: true,
-			}
 			rust_ffi_static {
-				name: "libfoo_vendor_static",
+				name: "libfoo_vendor",
 				crate_name: "foo",
 				srcs: ["foo.rs"],
 				vendor_available: true,
@@ -54,8 +47,8 @@
 
 	vendorBinary := ctx.ModuleForTests("fizz_vendor_available", "android_vendor_arm64_armv8-a").Module().(*cc.Module)
 
-	if android.InList("libfoo_vendor_static.vendor", vendorBinary.Properties.AndroidMkStaticLibs) {
-		t.Errorf("vendorBinary should not have a staticlib dependency on libfoo_vendor_static.vendor: %#v", vendorBinary.Properties.AndroidMkStaticLibs)
+	if android.InList("libfoo_vendor.vendor", vendorBinary.Properties.AndroidMkStaticLibs) {
+		t.Errorf("vendorBinary should not have a staticlib dependency on libfoo_vendor.vendor: %#v", vendorBinary.Properties.AndroidMkStaticLibs)
 	}
 }
 
@@ -107,26 +100,19 @@
 
 }
 
-// Test that cc modules can link against vendor_ramdisk_available rust_ffi_rlib and rust_ffi_static libraries.
+// Test that cc modules can link against vendor_ramdisk_available rust_ffi_static libraries.
 func TestVendorRamdiskLinkage(t *testing.T) {
 	ctx := testRust(t, `
 			cc_library_shared {
 				name: "libcc_vendor_ramdisk",
 				static_libs: [
 					"libfoo_vendor_ramdisk",
-					"libfoo_static_vendor_ramdisk"
 				],
 				system_shared_libs: [],
 				vendor_ramdisk_available: true,
 			}
-			rust_ffi_rlib {
-				name: "libfoo_vendor_ramdisk",
-				crate_name: "foo",
-				srcs: ["foo.rs"],
-				vendor_ramdisk_available: true,
-			}
 			rust_ffi_static {
-				name: "libfoo_static_vendor_ramdisk",
+				name: "libfoo_vendor_ramdisk",
 				crate_name: "foo",
 				srcs: ["foo.rs"],
 				vendor_ramdisk_available: true,
@@ -135,8 +121,8 @@
 
 	vendorRamdiskLibrary := ctx.ModuleForTests("libcc_vendor_ramdisk", "android_vendor_ramdisk_arm64_armv8-a_shared").Module().(*cc.Module)
 
-	if android.InList("libfoo_static_vendor_ramdisk.vendor_ramdisk", vendorRamdiskLibrary.Properties.AndroidMkStaticLibs) {
-		t.Errorf("libcc_vendor_ramdisk should not have a dependency on the libfoo_static_vendor_ramdisk static library")
+	if android.InList("libfoo_vendor_ramdisk.vendor_ramdisk", vendorRamdiskLibrary.Properties.AndroidMkStaticLibs) {
+		t.Errorf("libcc_vendor_ramdisk should not have a dependency on the libfoo_vendor_ramdisk static library")
 	}
 }
 
diff --git a/rust/library.go b/rust/library.go
index 9f9c402..14a2b65 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -40,15 +40,10 @@
 	android.RegisterModuleType("rust_library_host_rlib", RustLibraryRlibHostFactory)
 	android.RegisterModuleType("rust_ffi", RustFFIFactory)
 	android.RegisterModuleType("rust_ffi_shared", RustFFISharedFactory)
-	android.RegisterModuleType("rust_ffi_rlib", RustFFIRlibFactory)
 	android.RegisterModuleType("rust_ffi_host", RustFFIHostFactory)
 	android.RegisterModuleType("rust_ffi_host_shared", RustFFISharedHostFactory)
-	android.RegisterModuleType("rust_ffi_host_rlib", RustFFIRlibHostFactory)
-
-	// TODO: Remove when all instances of rust_ffi_static have been switched to rust_ffi_rlib
-	// Alias rust_ffi_static to the rust_ffi_rlib factory
-	android.RegisterModuleType("rust_ffi_static", RustFFIRlibFactory)
-	android.RegisterModuleType("rust_ffi_host_static", RustFFIRlibHostFactory)
+	android.RegisterModuleType("rust_ffi_static", RustLibraryRlibFactory)
+	android.RegisterModuleType("rust_ffi_host_static", RustLibraryRlibHostFactory)
 }
 
 type VariantLibraryProperties struct {
@@ -126,8 +121,6 @@
 	includeDirs       android.Paths
 	sourceProvider    SourceProvider
 
-	isFFI bool
-
 	// table-of-contents file for cdylib crates to optimize out relinking when possible
 	tocFile android.OptionalPath
 }
@@ -168,8 +161,6 @@
 	BuildOnlyShared()
 
 	toc() android.OptionalPath
-
-	isFFILibrary() bool
 }
 
 func (library *libraryDecorator) nativeCoverage() bool {
@@ -274,13 +265,13 @@
 	}
 }
 
-func (library *libraryDecorator) stdLinkage(ctx *depsContext) RustLinkage {
-	if library.static() || library.MutatedProperties.VariantIsStaticStd || (library.rlib() && library.isFFILibrary()) {
+func (library *libraryDecorator) stdLinkage(device bool) RustLinkage {
+	if library.static() || library.MutatedProperties.VariantIsStaticStd {
 		return RlibLinkage
 	} else if library.baseCompiler.preferRlib() {
 		return RlibLinkage
 	}
-	return DefaultLinkage
+	return DylibLinkage
 }
 
 var _ compiler = (*libraryDecorator)(nil)
@@ -295,8 +286,7 @@
 	return module.Init()
 }
 
-// rust_ffi produces all FFI variants (rust_ffi_shared, rust_ffi_static, and
-// rust_ffi_rlib).
+// rust_ffi produces all FFI variants (rust_ffi_shared, rust_ffi_static).
 func RustFFIFactory() android.Module {
 	module, library := NewRustLibrary(android.HostAndDeviceSupported)
 	library.BuildOnlyFFI()
@@ -310,7 +300,7 @@
 	return module.Init()
 }
 
-// rust_library_rlib produces an rlib (Rust crate type "rlib").
+// rust_library_rlib and rust_ffi_static produces an rlib (Rust crate type "rlib").
 func RustLibraryRlibFactory() android.Module {
 	module, library := NewRustLibrary(android.HostAndDeviceSupported)
 	library.BuildOnlyRlib()
@@ -334,7 +324,7 @@
 }
 
 // rust_ffi_host produces all FFI variants for the host
-// (rust_ffi_rlib_host, rust_ffi_static_host, and rust_ffi_shared_host).
+// (rust_ffi_static_host and rust_ffi_shared_host).
 func RustFFIHostFactory() android.Module {
 	module, library := NewRustLibrary(android.HostSupported)
 	library.BuildOnlyFFI()
@@ -349,8 +339,8 @@
 	return module.Init()
 }
 
-// rust_library_rlib_host produces an rlib for the host (Rust crate
-// type "rlib").
+// rust_library_rlib_host and rust_ffi_static_host produces an rlib for the host
+// (Rust crate type "rlib").
 func RustLibraryRlibHostFactory() android.Module {
 	module, library := NewRustLibrary(android.HostSupported)
 	library.BuildOnlyRlib()
@@ -365,33 +355,12 @@
 	return module.Init()
 }
 
-// rust_ffi_rlib_host produces an rlib for the host (Rust crate
-// type "rlib").
-func RustFFIRlibHostFactory() android.Module {
-	module, library := NewRustLibrary(android.HostSupported)
-	library.BuildOnlyRlib()
-
-	library.isFFI = true
-	return module.Init()
-}
-
-// rust_ffi_rlib produces an rlib (Rust crate type "rlib").
-func RustFFIRlibFactory() android.Module {
-	module, library := NewRustLibrary(android.HostAndDeviceSupported)
-	library.BuildOnlyRlib()
-
-	library.isFFI = true
-	return module.Init()
-}
-
 func (library *libraryDecorator) BuildOnlyFFI() {
 	library.MutatedProperties.BuildDylib = false
 	// we build rlibs for later static ffi linkage.
 	library.MutatedProperties.BuildRlib = true
 	library.MutatedProperties.BuildShared = true
 	library.MutatedProperties.BuildStatic = false
-
-	library.isFFI = true
 }
 
 func (library *libraryDecorator) BuildOnlyRust() {
@@ -420,8 +389,6 @@
 	library.MutatedProperties.BuildDylib = false
 	library.MutatedProperties.BuildShared = false
 	library.MutatedProperties.BuildStatic = true
-
-	library.isFFI = true
 }
 
 func (library *libraryDecorator) BuildOnlyShared() {
@@ -429,12 +396,6 @@
 	library.MutatedProperties.BuildDylib = false
 	library.MutatedProperties.BuildStatic = false
 	library.MutatedProperties.BuildShared = true
-
-	library.isFFI = true
-}
-
-func (library *libraryDecorator) isFFILibrary() bool {
-	return library.isFFI
 }
 
 func NewRustLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
@@ -523,7 +484,9 @@
 
 	flags = CommonLibraryCompilerFlags(ctx, flags)
 
-	if library.isFFI {
+	if library.rlib() || library.shared() {
+		// rlibs collect include dirs as well since they are used to
+		// produce staticlibs in the final C linkages
 		library.includeDirs = append(library.includeDirs, android.PathsForModuleSrc(ctx, library.Properties.Include_dirs)...)
 		library.includeDirs = append(library.includeDirs, android.PathsForModuleSrc(ctx, library.Properties.Export_include_dirs)...)
 	}
@@ -857,11 +820,7 @@
 		// Only create a variant if a library is actually being built.
 		if library, ok := m.compiler.(libraryInterface); ok {
 			if library.rlib() && !library.sysroot() {
-				if library.isFFILibrary() {
-					return []string{"rlib-std"}
-				} else {
-					return []string{"rlib-std", "dylib-std"}
-				}
+				return []string{"rlib-std", "dylib-std"}
 			}
 		}
 	}
diff --git a/rust/library_test.go b/rust/library_test.go
index adbf4fe..256cb35 100644
--- a/rust/library_test.go
+++ b/rust/library_test.go
@@ -202,9 +202,9 @@
 
 func TestNativeDependencyOfRlib(t *testing.T) {
 	ctx := testRust(t, `
-		rust_ffi_rlib {
-			name: "libffi_rlib",
-			crate_name: "ffi_rlib",
+		rust_ffi_static {
+			name: "libffi_static",
+			crate_name: "ffi_static",
 			rlibs: ["librust_rlib"],
 			srcs: ["foo.rs"],
 		}
@@ -227,7 +227,7 @@
 
 	rustRlibRlibStd := ctx.ModuleForTests("librust_rlib", "android_arm64_armv8-a_rlib_rlib-std")
 	rustRlibDylibStd := ctx.ModuleForTests("librust_rlib", "android_arm64_armv8-a_rlib_dylib-std")
-	ffiRlib := ctx.ModuleForTests("libffi_rlib", "android_arm64_armv8-a_rlib_rlib-std")
+	ffiRlib := ctx.ModuleForTests("libffi_static", "android_arm64_armv8-a_rlib_rlib-std")
 
 	modules := []android.TestingModule{
 		rustRlibRlibStd,
@@ -412,10 +412,10 @@
 		t.Errorf("Device rust_ffi_shared does not link libstd as an dylib")
 	}
 	if !android.InList("libstd", libbarFFIRlib.Properties.AndroidMkRlibs) {
-		t.Errorf("Device rust_ffi_rlib does not link libstd as an rlib")
+		t.Errorf("Device rust_ffi_static does not link libstd as an rlib")
 	}
 	if !android.InList("libfoo.rlib-std", libbarFFIRlib.Properties.AndroidMkRlibs) {
-		t.Errorf("Device rust_ffi_rlib does not link dependent rustlib rlib-std variant")
+		t.Errorf("Device rust_ffi_static does not link dependent rustlib rlib-std variant")
 	}
 	if !android.InList("libstd", libbarRlibStd.Properties.AndroidMkRlibs) {
 		t.Errorf("rust_ffi with prefer_rlib does not link libstd as an rlib")
diff --git a/rust/rust.go b/rust/rust.go
index 6fc682f..246670f 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -595,7 +595,7 @@
 	if mod.compiler != nil {
 		// use build{Static,Shared}() instead of {static,shared}() here because this might be called before
 		// VariantIs{Static,Shared} is set.
-		if lib, ok := mod.compiler.(libraryInterface); ok && (lib.buildShared() || lib.buildStatic()) {
+		if lib, ok := mod.compiler.(libraryInterface); ok && (lib.buildShared() || lib.buildStatic() || lib.buildRlib()) {
 			return true
 		}
 	}
@@ -681,15 +681,6 @@
 	panic(fmt.Errorf("BuildRlibVariant called on non-library module: %q", mod.BaseModuleName()))
 }
 
-func (mod *Module) IsRustFFI() bool {
-	if mod.compiler != nil {
-		if library, ok := mod.compiler.(libraryInterface); ok {
-			return library.isFFILibrary()
-		}
-	}
-	return false
-}
-
 func (mod *Module) BuildSharedVariant() bool {
 	if mod.compiler != nil {
 		if library, ok := mod.compiler.(libraryInterface); ok {
@@ -955,7 +946,6 @@
 			mod.sourceProvider.setOutputFiles(sourceLib.sourceProvider.Srcs())
 		}
 		ctx.CheckbuildFile(mod.sourceProvider.Srcs()...)
-		android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: mod.sourceProvider.Srcs().Strings()})
 	}
 
 	if mod.compiler != nil && !mod.compiler.Disabled() {
@@ -1237,6 +1227,8 @@
 	ctx.VisitDirectDeps(func(dep android.Module) {
 		depName := ctx.OtherModuleName(dep)
 		depTag := ctx.OtherModuleDependencyTag(dep)
+		modStdLinkage := mod.compiler.stdLinkage(ctx.Device())
+
 		if _, exists := skipModuleList[depName]; exists {
 			return
 		}
@@ -1265,6 +1257,14 @@
 					depPaths.transitiveImplementationDeps = append(depPaths.transitiveImplementationDeps, info.ImplementationDeps)
 				}
 
+				if !rustDep.compiler.noStdlibs() {
+					rustDepStdLinkage := rustDep.compiler.stdLinkage(ctx.Device())
+					if rustDepStdLinkage != modStdLinkage {
+						ctx.ModuleErrorf("Rust dependency %q has the wrong StdLinkage; expected %#v, got %#v", depName, modStdLinkage, rustDepStdLinkage)
+						return
+					}
+				}
+
 			case depTag == rlibDepTag:
 				rlib, ok := rustDep.compiler.(libraryInterface)
 				if !ok || !rlib.rlib() {
@@ -1285,6 +1285,14 @@
 					depPaths.transitiveImplementationDeps = append(depPaths.transitiveImplementationDeps, info.ImplementationDeps)
 				}
 
+				if !rustDep.compiler.noStdlibs() {
+					rustDepStdLinkage := rustDep.compiler.stdLinkage(ctx.Device())
+					if rustDepStdLinkage != modStdLinkage {
+						ctx.ModuleErrorf("Rust dependency %q has the wrong StdLinkage; expected %#v, got %#v", depName, modStdLinkage, rustDepStdLinkage)
+						return
+					}
+				}
+
 			case depTag == procMacroDepTag:
 				directProcMacroDeps = append(directProcMacroDeps, rustDep)
 				mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, makeLibName)
@@ -1603,7 +1611,7 @@
 	}
 
 	stdLinkage := "dylib-std"
-	if mod.compiler.stdLinkage(ctx) == RlibLinkage {
+	if mod.compiler.stdLinkage(ctx.Device()) == RlibLinkage {
 		stdLinkage = "rlib-std"
 	}
 
@@ -1670,7 +1678,7 @@
 
 	// stdlibs
 	if deps.Stdlibs != nil {
-		if mod.compiler.stdLinkage(ctx) == RlibLinkage {
+		if mod.compiler.stdLinkage(ctx.Device()) == RlibLinkage {
 			for _, lib := range deps.Stdlibs {
 				actx.AddVariationDependencies(append(commonDepVariations, []blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}}...),
 					rlibDepTag, lib)
diff --git a/rust/rust_test.go b/rust/rust_test.go
index 767508d..90c1f61 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -434,21 +434,21 @@
 
 func TestRustRlibs(t *testing.T) {
 	ctx := testRust(t, `
-		rust_ffi_rlib {
+		rust_ffi_static {
 			name: "libbar",
 			crate_name: "bar",
 			srcs: ["src/lib.rs"],
 			export_include_dirs: ["bar_includes"]
 		}
 
-		rust_ffi_rlib {
+		rust_ffi_static {
 			name: "libfoo",
 			crate_name: "foo",
 			srcs: ["src/lib.rs"],
 			export_include_dirs: ["foo_includes"]
 		}
 
-		rust_ffi_rlib {
+		rust_ffi_static {
 			name: "libbuzz",
 			crate_name: "buzz",
 			srcs: ["src/lib.rs"],
@@ -547,3 +547,31 @@
 		t.Errorf("expected %q got %q", expected, got)
 	}
 }
+
+func TestStdLinkMismatch(t *testing.T) {
+	// Test that we catch cases where the std linkage mismatches. This leads to
+	// a confusing rustc error where a crate is declared missing despite being
+	// passed in as a rustlib dependency / via the --extern flag. Thus, we want
+	// to make sure we detect it in Soong.
+
+	// libfoo depends on libbar as an rlib, but does not link libstd as an rlib.
+	// libbar only links libstd as an rlib (prefer_rlib).
+	testRustError(t, "wrong StdLinkage", `
+		rust_library {
+			name: "libfoo",
+			crate_name: "foo",
+			srcs: [
+				"foo.rs",
+			],
+			rlibs: ["libbar"],
+		}
+		rust_library {
+			name: "libbar",
+			crate_name: "bar",
+			srcs: [
+				"bar.rs",
+			],
+			prefer_rlib: true,
+		}
+	`)
+}
diff --git a/rust/test.go b/rust/test.go
index 20ccfb3..dce5e03 100644
--- a/rust/test.go
+++ b/rust/test.go
@@ -238,7 +238,7 @@
 	return module.Init()
 }
 
-func (test *testDecorator) stdLinkage(ctx *depsContext) RustLinkage {
+func (test *testDecorator) stdLinkage(device bool) RustLinkage {
 	return RlibLinkage
 }
 
diff --git a/rust/testing.go b/rust/testing.go
index 32cc823..0ce1b66 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -188,12 +188,10 @@
 	ctx.RegisterModuleType("rust_fuzz_host", RustFuzzHostFactory)
 	ctx.RegisterModuleType("rust_ffi", RustFFIFactory)
 	ctx.RegisterModuleType("rust_ffi_shared", RustFFISharedFactory)
-	ctx.RegisterModuleType("rust_ffi_rlib", RustFFIRlibFactory)
-	ctx.RegisterModuleType("rust_ffi_static", RustFFIRlibFactory)
+	ctx.RegisterModuleType("rust_ffi_static", RustLibraryRlibFactory)
 	ctx.RegisterModuleType("rust_ffi_host", RustFFIHostFactory)
 	ctx.RegisterModuleType("rust_ffi_host_shared", RustFFISharedHostFactory)
-	ctx.RegisterModuleType("rust_ffi_host_rlib", RustFFIRlibHostFactory)
-	ctx.RegisterModuleType("rust_ffi_host_static", RustFFIRlibHostFactory)
+	ctx.RegisterModuleType("rust_ffi_host_static", RustLibraryRlibHostFactory)
 	ctx.RegisterModuleType("rust_proc_macro", ProcMacroFactory)
 	ctx.RegisterModuleType("rust_protobuf", RustProtobufFactory)
 	ctx.RegisterModuleType("rust_protobuf_host", RustProtobufHostFactory)
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 7f5a426..60c5317 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -314,8 +314,6 @@
 
 	s.properties.SubName = s.GetSubname(ctx)
 
-	android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: []string{s.sourceFilePath.String()}})
-
 	ctx.SetOutputFiles(android.Paths{s.outputFilePath}, "")
 }
 
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
index 77d5853..25fbc41 100644
--- a/sysprop/sysprop_library.go
+++ b/sysprop/sysprop_library.go
@@ -346,7 +346,6 @@
 			ctx.PropertyErrorf("srcs", "srcs contains non-sysprop file %q", syspropFile.String())
 		}
 	}
-	android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: srcs.Strings()})
 
 	if ctx.Failed() {
 		return
diff --git a/ui/execution_metrics/execution_metrics.go b/ui/execution_metrics/execution_metrics.go
index 4ea251f..db78449 100644
--- a/ui/execution_metrics/execution_metrics.go
+++ b/ui/execution_metrics/execution_metrics.go
@@ -204,8 +204,7 @@
 	if c.MetricsAggregationDir == "" {
 		return nil
 	}
-	msg := c.GetMetrics()
-	msg.CommandArgs = args
+	msg := c.GetMetrics(args)
 
 	if _, err := os.Stat(filepath.Dir(path)); err != nil {
 		if err = os.MkdirAll(filepath.Dir(path), 0775); err != nil {
@@ -219,7 +218,14 @@
 	return os.WriteFile(path, data, 0644)
 }
 
-func (c *ExecutionMetrics) GetMetrics() *soong_metrics_proto.AggregatedFileList {
+func (c *ExecutionMetrics) GetMetrics(args []string) *soong_metrics_proto.ExecutionMetrics {
+	return &soong_metrics_proto.ExecutionMetrics{
+		CommandArgs:  args,
+		ChangedFiles: c.getChangedFiles(),
+	}
+}
+
+func (c *ExecutionMetrics) getChangedFiles() *soong_metrics_proto.AggregatedFileList {
 	fl := c.fileList
 	if fl == nil {
 		return nil
diff --git a/ui/metrics/metrics_proto/metrics.pb.go b/ui/metrics/metrics_proto/metrics.pb.go
index 0aa51b1..8cbc568 100644
--- a/ui/metrics/metrics_proto/metrics.pb.go
+++ b/ui/metrics/metrics_proto/metrics.pb.go
@@ -2080,6 +2080,64 @@
 	return nil
 }
 
+// This is created by soong_ui from SoongExexcutionMetrics files.
+type ExecutionMetrics struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The arguments provided on the command line.
+	CommandArgs []string `protobuf:"bytes,1,rep,name=command_args,json=commandArgs" json:"command_args,omitempty"`
+	// Changed files detected by the build.
+	ChangedFiles *AggregatedFileList `protobuf:"bytes,2,opt,name=changed_files,json=changedFiles" json:"changed_files,omitempty"`
+}
+
+func (x *ExecutionMetrics) Reset() {
+	*x = ExecutionMetrics{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_metrics_proto_msgTypes[19]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ExecutionMetrics) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ExecutionMetrics) ProtoMessage() {}
+
+func (x *ExecutionMetrics) ProtoReflect() protoreflect.Message {
+	mi := &file_metrics_proto_msgTypes[19]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ExecutionMetrics.ProtoReflect.Descriptor instead.
+func (*ExecutionMetrics) Descriptor() ([]byte, []int) {
+	return file_metrics_proto_rawDescGZIP(), []int{19}
+}
+
+func (x *ExecutionMetrics) GetCommandArgs() []string {
+	if x != nil {
+		return x.CommandArgs
+	}
+	return nil
+}
+
+func (x *ExecutionMetrics) GetChangedFiles() *AggregatedFileList {
+	if x != nil {
+		return x.ChangedFiles
+	}
+	return nil
+}
+
 // This is created by soong_ui from the various
 // android.find_input_delta_proto.FileList metrics provided to it by
 // find_input_delta.
@@ -2088,8 +2146,6 @@
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	// The arguments provided on the command line.
-	CommandArgs []string `protobuf:"bytes,1,rep,name=command_args,json=commandArgs" json:"command_args,omitempty"`
 	// The (possibly truncated list of) added files.
 	Additions []string `protobuf:"bytes,2,rep,name=additions" json:"additions,omitempty"`
 	// The (possibly truncated list of) changed files.
@@ -2105,7 +2161,7 @@
 func (x *AggregatedFileList) Reset() {
 	*x = AggregatedFileList{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_metrics_proto_msgTypes[19]
+		mi := &file_metrics_proto_msgTypes[20]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2118,7 +2174,7 @@
 func (*AggregatedFileList) ProtoMessage() {}
 
 func (x *AggregatedFileList) ProtoReflect() protoreflect.Message {
-	mi := &file_metrics_proto_msgTypes[19]
+	mi := &file_metrics_proto_msgTypes[20]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2131,14 +2187,7 @@
 
 // Deprecated: Use AggregatedFileList.ProtoReflect.Descriptor instead.
 func (*AggregatedFileList) Descriptor() ([]byte, []int) {
-	return file_metrics_proto_rawDescGZIP(), []int{19}
-}
-
-func (x *AggregatedFileList) GetCommandArgs() []string {
-	if x != nil {
-		return x.CommandArgs
-	}
-	return nil
+	return file_metrics_proto_rawDescGZIP(), []int{20}
 }
 
 func (x *AggregatedFileList) GetAdditions() []string {
@@ -2194,7 +2243,7 @@
 func (x *FileCount) Reset() {
 	*x = FileCount{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_metrics_proto_msgTypes[20]
+		mi := &file_metrics_proto_msgTypes[21]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2207,7 +2256,7 @@
 func (*FileCount) ProtoMessage() {}
 
 func (x *FileCount) ProtoReflect() protoreflect.Message {
-	mi := &file_metrics_proto_msgTypes[20]
+	mi := &file_metrics_proto_msgTypes[21]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2220,7 +2269,7 @@
 
 // Deprecated: Use FileCount.ProtoReflect.Descriptor instead.
 func (*FileCount) Descriptor() ([]byte, []int) {
-	return file_metrics_proto_rawDescGZIP(), []int{20}
+	return file_metrics_proto_rawDescGZIP(), []int{21}
 }
 
 func (x *FileCount) GetExtension() string {
@@ -2272,7 +2321,7 @@
 func (x *OptimizedBuildMetrics_TargetOptimizationResult) Reset() {
 	*x = OptimizedBuildMetrics_TargetOptimizationResult{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_metrics_proto_msgTypes[21]
+		mi := &file_metrics_proto_msgTypes[22]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2285,7 +2334,7 @@
 func (*OptimizedBuildMetrics_TargetOptimizationResult) ProtoMessage() {}
 
 func (x *OptimizedBuildMetrics_TargetOptimizationResult) ProtoReflect() protoreflect.Message {
-	mi := &file_metrics_proto_msgTypes[21]
+	mi := &file_metrics_proto_msgTypes[22]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2352,7 +2401,7 @@
 func (x *OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact) Reset() {
 	*x = OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_metrics_proto_msgTypes[22]
+		mi := &file_metrics_proto_msgTypes[23]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2365,7 +2414,7 @@
 func (*OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact) ProtoMessage() {}
 
 func (x *OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact) ProtoReflect() protoreflect.Message {
-	mi := &file_metrics_proto_msgTypes[22]
+	mi := &file_metrics_proto_msgTypes[23]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2808,33 +2857,40 @@
 	0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69,
 	0x7a, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x6d,
 	0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x69, 0x6e,
-	0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x22, 0xe6, 0x01,
-	0x0a, 0x12, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65,
-	0x4c, 0x69, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x5f,
-	0x61, 0x72, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x6d,
-	0x61, 0x6e, 0x64, 0x41, 0x72, 0x67, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74,
-	0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x64, 0x64, 0x69,
-	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73,
-	0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12,
-	0x1c, 0x0a, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03,
-	0x28, 0x09, 0x52, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a,
-	0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01,
-	0x28, 0x0d, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x12, 0x36,
-	0x0a, 0x06, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e,
-	0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74,
-	0x72, 0x69, 0x63, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x06,
-	0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22, 0x8b, 0x01, 0x0a, 0x09, 0x46, 0x69, 0x6c, 0x65, 0x43,
-	0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,
-	0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,
-	0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73,
-	0x12, 0x24, 0x0a, 0x0d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-	0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63,
-	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69,
-	0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74,
-	0x69, 0x6f, 0x6e, 0x73, 0x42, 0x28, 0x5a, 0x26, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f,
-	0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x75, 0x69, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
-	0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x83, 0x01,
+	0x0a, 0x10, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x72, 0x69,
+	0x63, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x61, 0x72,
+	0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
+	0x64, 0x41, 0x72, 0x67, 0x73, 0x12, 0x4c, 0x0a, 0x0d, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64,
+	0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x73,
+	0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69,
+	0x63, 0x73, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x46, 0x69, 0x6c,
+	0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x46, 0x69,
+	0x6c, 0x65, 0x73, 0x22, 0xc9, 0x01, 0x0a, 0x12, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74,
+	0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64,
+	0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61,
+	0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e,
+	0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67,
+	0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18,
+	0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+	0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x18,
+	0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x44, 0x65, 0x6c, 0x74,
+	0x61, 0x12, 0x36, 0x0a, 0x06, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28,
+	0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f,
+	0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e,
+	0x74, 0x52, 0x06, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22,
+	0x8b, 0x01, 0x0a, 0x09, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1c, 0x0a,
+	0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x61,
+	0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09,
+	0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x6d, 0x6f, 0x64,
+	0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d,
+	0x52, 0x0d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12,
+	0x1c, 0x0a, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01,
+	0x28, 0x0d, 0x52, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x28, 0x5a,
+	0x26, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x75,
+	0x69, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63,
+	0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
 }
 
 var (
@@ -2850,7 +2906,7 @@
 }
 
 var file_metrics_proto_enumTypes = make([]protoimpl.EnumInfo, 5)
-var file_metrics_proto_msgTypes = make([]protoimpl.MessageInfo, 23)
+var file_metrics_proto_msgTypes = make([]protoimpl.MessageInfo, 24)
 var file_metrics_proto_goTypes = []interface{}{
 	(MetricsBase_BuildVariant)(0),                          // 0: soong_build_metrics.MetricsBase.BuildVariant
 	(MetricsBase_Arch)(0),                                  // 1: soong_build_metrics.MetricsBase.Arch
@@ -2876,10 +2932,11 @@
 	(*CriticalPathInfo)(nil),                               // 21: soong_build_metrics.CriticalPathInfo
 	(*JobInfo)(nil),                                        // 22: soong_build_metrics.JobInfo
 	(*OptimizedBuildMetrics)(nil),                          // 23: soong_build_metrics.OptimizedBuildMetrics
-	(*AggregatedFileList)(nil),                             // 24: soong_build_metrics.AggregatedFileList
-	(*FileCount)(nil),                                      // 25: soong_build_metrics.FileCount
-	(*OptimizedBuildMetrics_TargetOptimizationResult)(nil), // 26: soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult
-	(*OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact)(nil), // 27: soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult.OutputArtifact
+	(*ExecutionMetrics)(nil),                               // 24: soong_build_metrics.ExecutionMetrics
+	(*AggregatedFileList)(nil),                             // 25: soong_build_metrics.AggregatedFileList
+	(*FileCount)(nil),                                      // 26: soong_build_metrics.FileCount
+	(*OptimizedBuildMetrics_TargetOptimizationResult)(nil), // 27: soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult
+	(*OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact)(nil), // 28: soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult.OutputArtifact
 }
 var file_metrics_proto_depIdxs = []int32{
 	0,  // 0: soong_build_metrics.MetricsBase.target_build_variant:type_name -> soong_build_metrics.MetricsBase.BuildVariant
@@ -2915,15 +2972,16 @@
 	22, // 30: soong_build_metrics.CriticalPathInfo.long_running_jobs:type_name -> soong_build_metrics.JobInfo
 	10, // 31: soong_build_metrics.OptimizedBuildMetrics.analysis_perf:type_name -> soong_build_metrics.PerfInfo
 	10, // 32: soong_build_metrics.OptimizedBuildMetrics.packaging_perf:type_name -> soong_build_metrics.PerfInfo
-	26, // 33: soong_build_metrics.OptimizedBuildMetrics.target_result:type_name -> soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult
-	25, // 34: soong_build_metrics.AggregatedFileList.counts:type_name -> soong_build_metrics.FileCount
-	10, // 35: soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult.packaging_perf:type_name -> soong_build_metrics.PerfInfo
-	27, // 36: soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult.output_artifact:type_name -> soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult.OutputArtifact
-	37, // [37:37] is the sub-list for method output_type
-	37, // [37:37] is the sub-list for method input_type
-	37, // [37:37] is the sub-list for extension type_name
-	37, // [37:37] is the sub-list for extension extendee
-	0,  // [0:37] is the sub-list for field type_name
+	27, // 33: soong_build_metrics.OptimizedBuildMetrics.target_result:type_name -> soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult
+	25, // 34: soong_build_metrics.ExecutionMetrics.changed_files:type_name -> soong_build_metrics.AggregatedFileList
+	26, // 35: soong_build_metrics.AggregatedFileList.counts:type_name -> soong_build_metrics.FileCount
+	10, // 36: soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult.packaging_perf:type_name -> soong_build_metrics.PerfInfo
+	28, // 37: soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult.output_artifact:type_name -> soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult.OutputArtifact
+	38, // [38:38] is the sub-list for method output_type
+	38, // [38:38] is the sub-list for method input_type
+	38, // [38:38] is the sub-list for extension type_name
+	38, // [38:38] is the sub-list for extension extendee
+	0,  // [0:38] is the sub-list for field type_name
 }
 
 func init() { file_metrics_proto_init() }
@@ -3161,7 +3219,7 @@
 			}
 		}
 		file_metrics_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*AggregatedFileList); i {
+			switch v := v.(*ExecutionMetrics); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -3173,7 +3231,7 @@
 			}
 		}
 		file_metrics_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*FileCount); i {
+			switch v := v.(*AggregatedFileList); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -3185,7 +3243,7 @@
 			}
 		}
 		file_metrics_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*OptimizedBuildMetrics_TargetOptimizationResult); i {
+			switch v := v.(*FileCount); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -3197,6 +3255,18 @@
 			}
 		}
 		file_metrics_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*OptimizedBuildMetrics_TargetOptimizationResult); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_metrics_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact); i {
 			case 0:
 				return &v.state
@@ -3215,7 +3285,7 @@
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_metrics_proto_rawDesc,
 			NumEnums:      5,
-			NumMessages:   23,
+			NumMessages:   24,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
diff --git a/ui/metrics/metrics_proto/metrics.proto b/ui/metrics/metrics_proto/metrics.proto
index 8437b65..69067ab 100644
--- a/ui/metrics/metrics_proto/metrics.proto
+++ b/ui/metrics/metrics_proto/metrics.proto
@@ -452,13 +452,19 @@
   }
 }
 
+// This is created by soong_ui from SoongExexcutionMetrics files.
+message ExecutionMetrics {
+  // The arguments provided on the command line.
+  repeated string command_args = 1;
+
+  // Changed files detected by the build.
+  optional AggregatedFileList changed_files = 2;
+}
+
 // This is created by soong_ui from the various
 // android.find_input_delta_proto.FileList metrics provided to it by
 // find_input_delta.
 message AggregatedFileList {
-  // The arguments provided on the command line.
-  repeated string command_args = 1;
-
   // The (possibly truncated list of) added files.
   repeated string additions = 2;
 
@@ -473,6 +479,8 @@
 
   // Counts by extension.
   repeated FileCount counts = 6;
+
+  reserved 1;
 }
 
 message FileCount {