Merge "Support transitive proguard specs in android_library_import" into main
diff --git a/android/base_module_context.go b/android/base_module_context.go
index 3367b06..c4922f4 100644
--- a/android/base_module_context.go
+++ b/android/base_module_context.go
@@ -219,7 +219,7 @@
 
 	// EvaluateConfiguration makes ModuleContext a valid proptools.ConfigurableEvaluator, so this context
 	// can be used to evaluate the final value of Configurable properties.
-	EvaluateConfiguration(parser.SelectType, string) (string, bool)
+	EvaluateConfiguration(parser.SelectType, string, string) (string, bool)
 }
 
 type baseModuleContext struct {
@@ -577,38 +577,6 @@
 	return sb.String()
 }
 
-func (m *baseModuleContext) EvaluateConfiguration(ty parser.SelectType, condition string) (string, bool) {
-	switch ty {
-	case parser.SelectTypeReleaseVariable:
-		if v, ok := m.Config().productVariables.BuildFlags[condition]; ok {
-			return v, true
-		}
-		return "", false
-	case parser.SelectTypeProductVariable:
-		// TODO(b/323382414): Might add these on a case-by-case basis
-		m.ModuleErrorf("TODO(b/323382414): Product variables are not yet supported in selects")
-		return "", false
-	case parser.SelectTypeSoongConfigVariable:
-		parts := strings.Split(condition, ":")
-		namespace := parts[0]
-		variable := parts[1]
-		if n, ok := m.Config().productVariables.VendorVars[namespace]; ok {
-			if v, ok := n[variable]; ok {
-				return v, true
-			}
-		}
-		return "", false
-	case parser.SelectTypeVariant:
-		if condition == "arch" {
-			if !m.ArchReady() {
-				m.ModuleErrorf("A select on arch was attempted before the arch mutator ran")
-				return "", false
-			}
-			return m.Arch().ArchType.Name, true
-		}
-		m.ModuleErrorf("Unknown variant " + condition)
-		return "", false
-	default:
-		panic("Should be unreachable")
-	}
+func (m *baseModuleContext) EvaluateConfiguration(ty parser.SelectType, property, condition string) (string, bool) {
+	return m.Module().ConfigurableEvaluator(m).EvaluateConfiguration(ty, property, condition)
 }
diff --git a/android/config.go b/android/config.go
index 18f89fb..2ee3b93 100644
--- a/android/config.go
+++ b/android/config.go
@@ -872,7 +872,7 @@
 // require them to run and get the current build thumbprint. This ensures they
 // don't rebuild on every incremental build when the build thumbprint changes.
 func (c *config) BuildThumbprintFile(ctx PathContext) Path {
-	return PathForOutput(ctx, String(c.productVariables.BuildThumbprintFile))
+	return PathForArbitraryOutput(ctx, "target", "product", c.DeviceName(), String(c.productVariables.BuildThumbprintFile))
 }
 
 // DeviceName returns the name of the current device target.
diff --git a/android/early_module_context.go b/android/early_module_context.go
index 8f75773..cf1b5fc 100644
--- a/android/early_module_context.go
+++ b/android/early_module_context.go
@@ -15,9 +15,10 @@
 package android
 
 import (
-	"github.com/google/blueprint"
 	"os"
 	"text/scanner"
+
+	"github.com/google/blueprint"
 )
 
 // EarlyModuleContext provides methods that can be called early, as soon as the properties have
@@ -54,6 +55,9 @@
 	// PropertyErrorf reports an error at the line number of a property in the module definition.
 	PropertyErrorf(property, fmt string, args ...interface{})
 
+	// OtherModulePropertyErrorf reports an error at the line number of a property in the given module definition.
+	OtherModulePropertyErrorf(module Module, property, fmt string, args ...interface{})
+
 	// Failed returns true if any errors have been reported.  In most cases the module can continue with generating
 	// build rules after an error, allowing it to report additional errors in a single run, but in cases where the error
 	// has prevented the module from creating necessary data it can return early when Failed returns true.
@@ -167,3 +171,7 @@
 func (e *earlyModuleContext) Namespace() *Namespace {
 	return e.EarlyModuleContext.Namespace().(*Namespace)
 }
+
+func (e *earlyModuleContext) OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{}) {
+	e.EarlyModuleContext.OtherModulePropertyErrorf(module, property, fmt, args)
+}
diff --git a/android/module.go b/android/module.go
index c0597fa..9f1d5ef 100644
--- a/android/module.go
+++ b/android/module.go
@@ -29,6 +29,7 @@
 	"android/soong/bazel"
 
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/parser"
 	"github.com/google/blueprint/proptools"
 )
 
@@ -123,6 +124,8 @@
 	// TransitivePackagingSpecs returns the PackagingSpecs for this module and any transitive
 	// dependencies with dependency tags for which IsInstallDepNeeded() returns true.
 	TransitivePackagingSpecs() []PackagingSpec
+
+	ConfigurableEvaluator(ctx ConfigAndErrorContext) proptools.ConfigurableEvaluator
 }
 
 // Qualified id for a module
@@ -1230,6 +1233,10 @@
 	return distFiles
 }
 
+func (m *ModuleBase) ArchReady() bool {
+	return m.commonProperties.ArchReady
+}
+
 func (m *ModuleBase) Target() Target {
 	return m.commonProperties.CompileTarget
 }
@@ -2104,6 +2111,65 @@
 	return proptools.Bool(m.commonProperties.Native_bridge_supported)
 }
 
+type ConfigAndErrorContext interface {
+	Config() Config
+	OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{})
+}
+
+type configurationEvalutor struct {
+	ctx ConfigAndErrorContext
+	m   Module
+}
+
+func (m *ModuleBase) ConfigurableEvaluator(ctx ConfigAndErrorContext) proptools.ConfigurableEvaluator {
+	return configurationEvalutor{
+		ctx: ctx,
+		m:   m.module,
+	}
+}
+
+func (e configurationEvalutor) PropertyErrorf(property string, fmt string, args ...interface{}) {
+	e.ctx.OtherModulePropertyErrorf(e.m, property, fmt, args)
+}
+
+func (e configurationEvalutor) EvaluateConfiguration(ty parser.SelectType, property, condition string) (string, bool) {
+	ctx := e.ctx
+	m := e.m
+	switch ty {
+	case parser.SelectTypeReleaseVariable:
+		if v, ok := ctx.Config().productVariables.BuildFlags[condition]; ok {
+			return v, true
+		}
+		return "", false
+	case parser.SelectTypeProductVariable:
+		// TODO(b/323382414): Might add these on a case-by-case basis
+		ctx.OtherModulePropertyErrorf(m, property, "TODO(b/323382414): Product variables are not yet supported in selects")
+		return "", false
+	case parser.SelectTypeSoongConfigVariable:
+		parts := strings.Split(condition, ":")
+		namespace := parts[0]
+		variable := parts[1]
+		if n, ok := ctx.Config().productVariables.VendorVars[namespace]; ok {
+			if v, ok := n[variable]; ok {
+				return v, true
+			}
+		}
+		return "", false
+	case parser.SelectTypeVariant:
+		if condition == "arch" {
+			if !m.base().ArchReady() {
+				ctx.OtherModulePropertyErrorf(m, property, "A select on arch was attempted before the arch mutator ran")
+				return "", false
+			}
+			return m.base().Arch().ArchType.Name, true
+		}
+		ctx.OtherModulePropertyErrorf(m, property, "Unknown variant %s", condition)
+		return "", false
+	default:
+		panic("Should be unreachable")
+	}
+}
+
 // ModuleNameWithPossibleOverride returns the name of the OverrideModule that overrides the current
 // variant of this OverridableModule, or ctx.ModuleName() if this module is not an OverridableModule
 // or if this variant is not overridden.
diff --git a/android/module_context.go b/android/module_context.go
index 1cab630..d3e2770 100644
--- a/android/module_context.go
+++ b/android/module_context.go
@@ -234,6 +234,8 @@
 	variables   map[string]string
 }
 
+var _ ModuleContext = &moduleContext{}
+
 func (m *moduleContext) ninjaError(params BuildParams, err error) (PackageContext, BuildParams) {
 	return pctx, BuildParams{
 		Rule:            ErrorRule,
diff --git a/android/singleton.go b/android/singleton.go
index 5f93996..76df1eb 100644
--- a/android/singleton.go
+++ b/android/singleton.go
@@ -87,6 +87,9 @@
 	// builder whenever a file matching the pattern as added or removed, without rerunning if a
 	// file that does not match the pattern is added to a searched directory.
 	GlobWithDeps(pattern string, excludes []string) ([]string, error)
+
+	// OtherModulePropertyErrorf reports an error on the line number of the given property of the given module
+	OtherModulePropertyErrorf(module Module, property string, format string, args ...interface{})
 }
 
 type singletonAdaptor struct {
@@ -279,3 +282,7 @@
 func (s *singletonContextAdaptor) moduleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) {
 	return s.SingletonContext.ModuleProvider(module, provider)
 }
+
+func (s *singletonContextAdaptor) OtherModulePropertyErrorf(module Module, property string, format string, args ...interface{}) {
+	s.blueprintSingletonContext().OtherModulePropertyErrorf(module, property, format, args)
+}
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 183e818..64193b1 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -325,13 +325,6 @@
 	if runtime.GOOS == "darwin" {
 		return false
 	}
-	// abidw doesn't currently handle top-byte-ignore correctly. Disable ABI
-	// dumping for those configs while we wait for a fix. We'll still have ABI
-	// checking coverage from non-hwasan builds.
-	// http://b/190554910
-	if android.InList("hwaddress", config.SanitizeDevice()) {
-		return false
-	}
 	// http://b/156513478
 	return config.ReleaseNdkAbiMonitored()
 }
diff --git a/phony/phony.go b/phony/phony.go
index b8dbd00..68fbf48 100644
--- a/phony/phony.go
+++ b/phony/phony.go
@@ -23,10 +23,16 @@
 )
 
 func init() {
-	android.RegisterModuleType("phony", PhonyFactory)
-	android.RegisterModuleType("phony_rule", PhonyRuleFactory)
+	registerPhonyModuleTypes(android.InitRegistrationContext)
 }
 
+func registerPhonyModuleTypes(ctx android.RegistrationContext) {
+	ctx.RegisterModuleType("phony", PhonyFactory)
+	ctx.RegisterModuleType("phony_rule", PhonyRuleFactory)
+}
+
+var PrepareForTestWithPhony = android.FixtureRegisterWithContext(registerPhonyModuleTypes)
+
 type phony struct {
 	android.ModuleBase
 	requiredModuleNames       []string