Merge "Add platform_compat_config to sdk"
diff --git a/android/config.go b/android/config.go
index 19706f5..0de8928 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1389,7 +1389,10 @@
 }
 
 func (c *deviceConfig) BoardSepolicyVers() string {
-	return String(c.config.productVariables.BoardSepolicyVers)
+	if ver := String(c.config.productVariables.BoardSepolicyVers); ver != "" {
+		return ver
+	}
+	return c.PlatformSepolicyVersion()
 }
 
 func (c *deviceConfig) BoardReqdMaskPolicy() []string {
diff --git a/android/namespace_test.go b/android/namespace_test.go
index dea287d..08e221a 100644
--- a/android/namespace_test.go
+++ b/android/namespace_test.go
@@ -697,7 +697,7 @@
 		testModule, ok := candidate.(*testModule)
 		if ok {
 			if testModule.properties.Id == id {
-				module = TestingModule{testModule}
+				module = newTestingModule(ctx.config, testModule)
 			}
 		}
 	}
diff --git a/android/packaging.go b/android/packaging.go
index 9b901ce..72c0c17 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -59,7 +59,8 @@
 	packagingBase() *PackagingBase
 
 	// AddDeps adds dependencies to the `deps` modules. This should be called in DepsMutator.
-	// When adding the dependencies, depTag is used as the tag.
+	// When adding the dependencies, depTag is used as the tag. If `deps` modules are meant to
+	// be copied to a zip in CopyDepsToZip, `depTag` should implement PackagingItem marker interface.
 	AddDeps(ctx BottomUpMutatorContext, depTag blueprint.DependencyTag)
 
 	// CopyDepsToZip zips the built artifacts of the dependencies into the given zip file and
@@ -167,6 +168,24 @@
 	return ret
 }
 
+// PackagingItem is a marker interface for dependency tags.
+// Direct dependencies with a tag implementing PackagingItem are packaged in CopyDepsToZip().
+type PackagingItem interface {
+	// IsPackagingItem returns true if the dep is to be packaged
+	IsPackagingItem() bool
+}
+
+// DepTag provides default implementation of PackagingItem interface.
+// PackagingBase-derived modules can define their own dependency tag by embedding this, which
+// can be passed to AddDeps() or AddDependencies().
+type PackagingItemAlwaysDepTag struct {
+}
+
+// IsPackagingItem returns true if the dep is to be packaged
+func (PackagingItemAlwaysDepTag) IsPackagingItem() bool {
+	return true
+}
+
 // See PackageModule.AddDeps
 func (p *PackagingBase) AddDeps(ctx BottomUpMutatorContext, depTag blueprint.DependencyTag) {
 	for _, t := range p.getSupportedTargets(ctx) {
@@ -182,16 +201,15 @@
 // See PackageModule.CopyDepsToZip
 func (p *PackagingBase) CopyDepsToZip(ctx ModuleContext, zipOut WritablePath) (entries []string) {
 	m := make(map[string]PackagingSpec)
-	ctx.WalkDeps(func(child Module, parent Module) bool {
-		if !IsInstallDepNeeded(ctx.OtherModuleDependencyTag(child)) {
-			return false
+	ctx.VisitDirectDeps(func(child Module) {
+		if pi, ok := ctx.OtherModuleDependencyTag(child).(PackagingItem); !ok || !pi.IsPackagingItem() {
+			return
 		}
-		for _, ps := range child.PackagingSpecs() {
+		for _, ps := range child.TransitivePackagingSpecs() {
 			if _, ok := m[ps.relPathInPackage]; !ok {
 				m[ps.relPathInPackage] = ps
 			}
 		}
-		return true
 	})
 
 	builder := NewRuleBuilder(pctx, ctx)
diff --git a/android/packaging_test.go b/android/packaging_test.go
index f29de76..f91dc5d 100644
--- a/android/packaging_test.go
+++ b/android/packaging_test.go
@@ -56,7 +56,9 @@
 type packageTestModule struct {
 	ModuleBase
 	PackagingBase
-
+	properties struct {
+		Install_deps []string `android:`
+	}
 	entries []string
 }
 
@@ -64,6 +66,7 @@
 	module := &packageTestModule{}
 	InitPackageModule(module)
 	InitAndroidMultiTargetsArchModule(module, DeviceSupported, MultilibCommon)
+	module.AddProperties(&module.properties)
 	return module
 }
 
@@ -71,11 +74,18 @@
 	module := &packageTestModule{}
 	InitPackageModule(module)
 	InitAndroidArchModule(module, DeviceSupported, MultilibBoth)
+	module.AddProperties(&module.properties)
 	return module
 }
 
+type packagingDepTag struct {
+	blueprint.BaseDependencyTag
+	PackagingItemAlwaysDepTag
+}
+
 func (m *packageTestModule) DepsMutator(ctx BottomUpMutatorContext) {
-	m.AddDeps(ctx, installDepTag{})
+	m.AddDeps(ctx, packagingDepTag{})
+	ctx.AddDependency(ctx.Module(), installDepTag{}, m.properties.Install_deps...)
 }
 
 func (m *packageTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
@@ -337,4 +347,21 @@
 			},
 		}
 		`, []string{"lib64/foo", "lib64/bar"})
+
+	runPackagingTest(t, multiTarget,
+		`
+		component {
+			name: "foo",
+		}
+
+		component {
+			name: "bar",
+		}
+
+		package_module {
+			name: "package",
+			deps: ["foo"],
+			install_deps: ["bar"],
+		}
+		`, []string{"lib64/foo"})
 }
diff --git a/android/register.go b/android/register.go
index c9e66e9..900edfa 100644
--- a/android/register.go
+++ b/android/register.go
@@ -263,8 +263,9 @@
 //   ctx := android.NewTestContext(config)
 //   RegisterBuildComponents(ctx)
 var InitRegistrationContext RegistrationContext = &initRegistrationContext{
-	moduleTypes:    make(map[string]ModuleFactory),
-	singletonTypes: make(map[string]SingletonFactory),
+	moduleTypes:       make(map[string]ModuleFactory),
+	singletonTypes:    make(map[string]SingletonFactory),
+	preSingletonTypes: make(map[string]SingletonFactory),
 }
 
 // Make sure the TestContext implements RegistrationContext.
diff --git a/android/rule_builder_test.go b/android/rule_builder_test.go
index f41d61b..9cd60a2 100644
--- a/android/rule_builder_test.go
+++ b/android/rule_builder_test.go
@@ -562,46 +562,44 @@
 		AssertBoolEquals(t, "RuleParams.Restat", wantRestat, params.RuleParams.Restat)
 
 		wantImplicits := append([]string{"bar"}, extraImplicits...)
-		AssertArrayString(t, "Implicits", wantImplicits, params.Implicits.Strings())
+		AssertPathsRelativeToTopEquals(t, "Implicits", wantImplicits, params.Implicits)
 
-		AssertStringEquals(t, "Output", wantOutput, params.Output.String())
+		AssertPathRelativeToTopEquals(t, "Output", wantOutput, params.Output)
 
 		if len(params.ImplicitOutputs) != 0 {
 			t.Errorf("want ImplicitOutputs = [], got %q", params.ImplicitOutputs.Strings())
 		}
 
-		AssertStringEquals(t, "Depfile", wantDepfile, params.Depfile.String())
+		AssertPathRelativeToTopEquals(t, "Depfile", wantDepfile, params.Depfile)
 
 		if params.Deps != blueprint.DepsGCC {
 			t.Errorf("want Deps = %q, got %q", blueprint.DepsGCC, params.Deps)
 		}
 	}
 
-	buildDir := result.Config.BuildDir()
-
 	t.Run("module", func(t *testing.T) {
-		outFile := filepath.Join(buildDir, ".intermediates", "foo", "gen", "foo")
-		check(t, result.ModuleForTests("foo", "").Rule("rule"),
+		outFile := "out/soong/.intermediates/foo/gen/foo"
+		check(t, result.ModuleForTests("foo", "").Rule("rule").RelativeToTop(),
 			"cp bar "+outFile,
 			outFile, outFile+".d", true, nil, nil)
 	})
 	t.Run("sbox", func(t *testing.T) {
-		outDir := filepath.Join(buildDir, ".intermediates", "foo_sbox")
+		outDir := "out/soong/.intermediates/foo_sbox"
 		outFile := filepath.Join(outDir, "gen/foo_sbox")
 		depFile := filepath.Join(outDir, "gen/foo_sbox.d")
 		manifest := filepath.Join(outDir, "sbox.textproto")
-		sbox := filepath.Join(buildDir, "host", result.Config.PrebuiltOS(), "bin/sbox")
-		sandboxPath := shared.TempDirForOutDir(buildDir)
+		sbox := filepath.Join("out", "soong", "host", result.Config.PrebuiltOS(), "bin/sbox")
+		sandboxPath := shared.TempDirForOutDir("out/soong")
 
 		cmd := `rm -rf ` + outDir + `/gen && ` +
 			sbox + ` --sandbox-path ` + sandboxPath + ` --manifest ` + manifest
 
-		check(t, result.ModuleForTests("foo_sbox", "").Output("gen/foo_sbox"),
+		check(t, result.ModuleForTests("foo_sbox", "").Output("gen/foo_sbox").RelativeToTop(),
 			cmd, outFile, depFile, false, []string{manifest}, []string{sbox})
 	})
 	t.Run("singleton", func(t *testing.T) {
-		outFile := filepath.Join(buildDir, "singleton/gen/baz")
-		check(t, result.SingletonForTests("rule_builder_test").Rule("rule"),
+		outFile := filepath.Join("out/soong/singleton/gen/baz")
+		check(t, result.SingletonForTests("rule_builder_test").Rule("rule").RelativeToTop(),
 			"cp bar "+outFile, outFile, outFile+".d", true, nil, nil)
 	})
 }
diff --git a/android/testing.go b/android/testing.go
index af360fa..f17de31 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -479,7 +479,7 @@
 		}
 	}
 
-	return TestingModule{module}
+	return newTestingModule(ctx.config, module)
 }
 
 func (ctx *TestContext) ModuleVariantsForTests(name string) []string {
@@ -499,8 +499,8 @@
 		n := ctx.SingletonName(s)
 		if n == name {
 			return TestingSingleton{
-				singleton: s.(*singletonAdaptor).Singleton,
-				provider:  s.(testBuildProvider),
+				baseTestingComponent: newBaseTestingComponent(ctx.config, s.(testBuildProvider)),
+				singleton:            s.(*singletonAdaptor).Singleton,
 			}
 		}
 		allSingletonNames = append(allSingletonNames, n)
@@ -522,62 +522,170 @@
 type TestingBuildParams struct {
 	BuildParams
 	RuleParams blueprint.RuleParams
+
+	config Config
 }
 
-func newTestingBuildParams(provider testBuildProvider, bparams BuildParams) TestingBuildParams {
+// RelativeToTop creates a new instance of this which has had any usages of the current test's
+// temporary and test specific build directory replaced with a path relative to the notional top.
+//
+// The parts of this structure which are changed are:
+// * BuildParams
+//   * Args
+//   * Path instances are intentionally not modified, use AssertPathRelativeToTopEquals or
+//     AssertPathsRelativeToTopEquals instead which do something similar.
+//
+// * RuleParams
+//   * Command
+//   * Depfile
+//   * Rspfile
+//   * RspfileContent
+//   * SymlinkOutputs
+//   * CommandDeps
+//   * CommandOrderOnly
+//
+// See PathRelativeToTop for more details.
+func (p TestingBuildParams) RelativeToTop() TestingBuildParams {
+	// If this is not a valid params then just return it back. That will make it easy to use with the
+	// Maybe...() methods.
+	if p.Rule == nil {
+		return p
+	}
+	if p.config.config == nil {
+		panic("cannot call RelativeToTop() on a TestingBuildParams previously returned by RelativeToTop()")
+	}
+	// Take a copy of the build params and replace any args that contains test specific temporary
+	// paths with paths relative to the top.
+	bparams := p.BuildParams
+	bparams.Args = normalizeStringMapRelativeToTop(p.config, bparams.Args)
+
+	// Ditto for any fields in the RuleParams.
+	rparams := p.RuleParams
+	rparams.Command = normalizeStringRelativeToTop(p.config, rparams.Command)
+	rparams.Depfile = normalizeStringRelativeToTop(p.config, rparams.Depfile)
+	rparams.Rspfile = normalizeStringRelativeToTop(p.config, rparams.Rspfile)
+	rparams.RspfileContent = normalizeStringRelativeToTop(p.config, rparams.RspfileContent)
+	rparams.SymlinkOutputs = normalizeStringArrayRelativeToTop(p.config, rparams.SymlinkOutputs)
+	rparams.CommandDeps = normalizeStringArrayRelativeToTop(p.config, rparams.CommandDeps)
+	rparams.CommandOrderOnly = normalizeStringArrayRelativeToTop(p.config, rparams.CommandOrderOnly)
+
 	return TestingBuildParams{
 		BuildParams: bparams,
-		RuleParams:  provider.RuleParamsForTests()[bparams.Rule],
+		RuleParams:  rparams,
 	}
 }
 
-func maybeBuildParamsFromRule(provider testBuildProvider, rule string) (TestingBuildParams, []string) {
+// baseTestingComponent provides functionality common to both TestingModule and TestingSingleton.
+type baseTestingComponent struct {
+	config   Config
+	provider testBuildProvider
+}
+
+func newBaseTestingComponent(config Config, provider testBuildProvider) baseTestingComponent {
+	return baseTestingComponent{config, provider}
+}
+
+// A function that will normalize a string containing paths, e.g. ninja command, by replacing
+// any references to the test specific temporary build directory that changes with each run to a
+// fixed path relative to a notional top directory.
+//
+// This is similar to StringPathRelativeToTop except that assumes the string is a single path
+// containing at most one instance of the temporary build directory at the start of the path while
+// this assumes that there can be any number at any position.
+func normalizeStringRelativeToTop(config Config, s string) string {
+	// The buildDir usually looks something like: /tmp/testFoo2345/001
+	//
+	// Replace any usage of the buildDir with out/soong, e.g. replace "/tmp/testFoo2345/001" with
+	// "out/soong".
+	outSoongDir := filepath.Clean(config.buildDir)
+	re := regexp.MustCompile(`\Q` + outSoongDir + `\E\b`)
+	s = re.ReplaceAllString(s, "out/soong")
+
+	// Replace any usage of the buildDir/.. with out, e.g. replace "/tmp/testFoo2345" with
+	// "out". This must come after the previous replacement otherwise this would replace
+	// "/tmp/testFoo2345/001" with "out/001" instead of "out/soong".
+	outDir := filepath.Dir(outSoongDir)
+	re = regexp.MustCompile(`\Q` + outDir + `\E\b`)
+	s = re.ReplaceAllString(s, "out")
+
+	return s
+}
+
+// normalizeStringArrayRelativeToTop creates a new slice constructed by applying
+// normalizeStringRelativeToTop to each item in the slice.
+func normalizeStringArrayRelativeToTop(config Config, slice []string) []string {
+	newSlice := make([]string, len(slice))
+	for i, s := range slice {
+		newSlice[i] = normalizeStringRelativeToTop(config, s)
+	}
+	return newSlice
+}
+
+// normalizeStringMapRelativeToTop creates a new map constructed by applying
+// normalizeStringRelativeToTop to each value in the map.
+func normalizeStringMapRelativeToTop(config Config, m map[string]string) map[string]string {
+	newMap := map[string]string{}
+	for k, v := range m {
+		newMap[k] = normalizeStringRelativeToTop(config, v)
+	}
+	return newMap
+}
+
+func (b baseTestingComponent) newTestingBuildParams(bparams BuildParams) TestingBuildParams {
+	return TestingBuildParams{
+		config:      b.config,
+		BuildParams: bparams,
+		RuleParams:  b.provider.RuleParamsForTests()[bparams.Rule],
+	}
+}
+
+func (b baseTestingComponent) maybeBuildParamsFromRule(rule string) (TestingBuildParams, []string) {
 	var searchedRules []string
-	for _, p := range provider.BuildParamsForTests() {
+	for _, p := range b.provider.BuildParamsForTests() {
 		searchedRules = append(searchedRules, p.Rule.String())
 		if strings.Contains(p.Rule.String(), rule) {
-			return newTestingBuildParams(provider, p), searchedRules
+			return b.newTestingBuildParams(p), searchedRules
 		}
 	}
 	return TestingBuildParams{}, searchedRules
 }
 
-func buildParamsFromRule(provider testBuildProvider, rule string) TestingBuildParams {
-	p, searchRules := maybeBuildParamsFromRule(provider, rule)
+func (b baseTestingComponent) buildParamsFromRule(rule string) TestingBuildParams {
+	p, searchRules := b.maybeBuildParamsFromRule(rule)
 	if p.Rule == nil {
 		panic(fmt.Errorf("couldn't find rule %q.\nall rules: %v", rule, searchRules))
 	}
 	return p
 }
 
-func maybeBuildParamsFromDescription(provider testBuildProvider, desc string) TestingBuildParams {
-	for _, p := range provider.BuildParamsForTests() {
+func (b baseTestingComponent) maybeBuildParamsFromDescription(desc string) TestingBuildParams {
+	for _, p := range b.provider.BuildParamsForTests() {
 		if strings.Contains(p.Description, desc) {
-			return newTestingBuildParams(provider, p)
+			return b.newTestingBuildParams(p)
 		}
 	}
 	return TestingBuildParams{}
 }
 
-func buildParamsFromDescription(provider testBuildProvider, desc string) TestingBuildParams {
-	p := maybeBuildParamsFromDescription(provider, desc)
+func (b baseTestingComponent) buildParamsFromDescription(desc string) TestingBuildParams {
+	p := b.maybeBuildParamsFromDescription(desc)
 	if p.Rule == nil {
 		panic(fmt.Errorf("couldn't find description %q", desc))
 	}
 	return p
 }
 
-func maybeBuildParamsFromOutput(provider testBuildProvider, file string) (TestingBuildParams, []string) {
+func (b baseTestingComponent) maybeBuildParamsFromOutput(file string) (TestingBuildParams, []string) {
 	var searchedOutputs []string
-	for _, p := range provider.BuildParamsForTests() {
+	for _, p := range b.provider.BuildParamsForTests() {
 		outputs := append(WritablePaths(nil), p.Outputs...)
 		outputs = append(outputs, p.ImplicitOutputs...)
 		if p.Output != nil {
 			outputs = append(outputs, p.Output)
 		}
 		for _, f := range outputs {
-			if f.String() == file || f.Rel() == file {
-				return newTestingBuildParams(provider, p), nil
+			if f.String() == file || f.Rel() == file || PathRelativeToTop(f) == file {
+				return b.newTestingBuildParams(p), nil
 			}
 			searchedOutputs = append(searchedOutputs, f.Rel())
 		}
@@ -585,18 +693,18 @@
 	return TestingBuildParams{}, searchedOutputs
 }
 
-func buildParamsFromOutput(provider testBuildProvider, file string) TestingBuildParams {
-	p, searchedOutputs := maybeBuildParamsFromOutput(provider, file)
+func (b baseTestingComponent) buildParamsFromOutput(file string) TestingBuildParams {
+	p, searchedOutputs := b.maybeBuildParamsFromOutput(file)
 	if p.Rule == nil {
-		panic(fmt.Errorf("couldn't find output %q.\nall outputs: %v",
-			file, searchedOutputs))
+		panic(fmt.Errorf("couldn't find output %q.\nall outputs:\n    %s\n",
+			file, strings.Join(searchedOutputs, "\n    ")))
 	}
 	return p
 }
 
-func allOutputs(provider testBuildProvider) []string {
+func (b baseTestingComponent) allOutputs() []string {
 	var outputFullPaths []string
-	for _, p := range provider.BuildParamsForTests() {
+	for _, p := range b.provider.BuildParamsForTests() {
 		outputs := append(WritablePaths(nil), p.Outputs...)
 		outputs = append(outputs, p.ImplicitOutputs...)
 		if p.Output != nil {
@@ -607,64 +715,78 @@
 	return outputFullPaths
 }
 
+// MaybeRule finds a call to ctx.Build with BuildParams.Rule set to a rule with the given name.  Returns an empty
+// BuildParams if no rule is found.
+func (b baseTestingComponent) MaybeRule(rule string) TestingBuildParams {
+	r, _ := b.maybeBuildParamsFromRule(rule)
+	return r
+}
+
+// Rule finds a call to ctx.Build with BuildParams.Rule set to a rule with the given name.  Panics if no rule is found.
+func (b baseTestingComponent) Rule(rule string) TestingBuildParams {
+	return b.buildParamsFromRule(rule)
+}
+
+// MaybeDescription finds a call to ctx.Build with BuildParams.Description set to a the given string.  Returns an empty
+// BuildParams if no rule is found.
+func (b baseTestingComponent) MaybeDescription(desc string) TestingBuildParams {
+	return b.maybeBuildParamsFromDescription(desc)
+}
+
+// Description finds a call to ctx.Build with BuildParams.Description set to a the given string.  Panics if no rule is
+// found.
+func (b baseTestingComponent) Description(desc string) TestingBuildParams {
+	return b.buildParamsFromDescription(desc)
+}
+
+// MaybeOutput finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputs whose String() or Rel()
+// value matches the provided string.  Returns an empty BuildParams if no rule is found.
+func (b baseTestingComponent) MaybeOutput(file string) TestingBuildParams {
+	p, _ := b.maybeBuildParamsFromOutput(file)
+	return p
+}
+
+// Output finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputs whose String() or Rel()
+// value matches the provided string.  Panics if no rule is found.
+func (b baseTestingComponent) Output(file string) TestingBuildParams {
+	return b.buildParamsFromOutput(file)
+}
+
+// AllOutputs returns all 'BuildParams.Output's and 'BuildParams.Outputs's in their full path string forms.
+func (b baseTestingComponent) AllOutputs() []string {
+	return b.allOutputs()
+}
+
 // TestingModule is wrapper around an android.Module that provides methods to find information about individual
 // ctx.Build parameters for verification in tests.
 type TestingModule struct {
+	baseTestingComponent
 	module Module
 }
 
+func newTestingModule(config Config, module Module) TestingModule {
+	return TestingModule{
+		newBaseTestingComponent(config, module),
+		module,
+	}
+}
+
 // Module returns the Module wrapped by the TestingModule.
 func (m TestingModule) Module() Module {
 	return m.module
 }
 
-// MaybeRule finds a call to ctx.Build with BuildParams.Rule set to a rule with the given name.  Returns an empty
-// BuildParams if no rule is found.
-func (m TestingModule) MaybeRule(rule string) TestingBuildParams {
-	r, _ := maybeBuildParamsFromRule(m.module, rule)
-	return r
-}
-
-// Rule finds a call to ctx.Build with BuildParams.Rule set to a rule with the given name.  Panics if no rule is found.
-func (m TestingModule) Rule(rule string) TestingBuildParams {
-	return buildParamsFromRule(m.module, rule)
-}
-
-// MaybeDescription finds a call to ctx.Build with BuildParams.Description set to a the given string.  Returns an empty
-// BuildParams if no rule is found.
-func (m TestingModule) MaybeDescription(desc string) TestingBuildParams {
-	return maybeBuildParamsFromDescription(m.module, desc)
-}
-
-// Description finds a call to ctx.Build with BuildParams.Description set to a the given string.  Panics if no rule is
-// found.
-func (m TestingModule) Description(desc string) TestingBuildParams {
-	return buildParamsFromDescription(m.module, desc)
-}
-
-// MaybeOutput finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputs whose String() or Rel()
-// value matches the provided string.  Returns an empty BuildParams if no rule is found.
-func (m TestingModule) MaybeOutput(file string) TestingBuildParams {
-	p, _ := maybeBuildParamsFromOutput(m.module, file)
-	return p
-}
-
-// Output finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputs whose String() or Rel()
-// value matches the provided string.  Panics if no rule is found.
-func (m TestingModule) Output(file string) TestingBuildParams {
-	return buildParamsFromOutput(m.module, file)
-}
-
-// AllOutputs returns all 'BuildParams.Output's and 'BuildParams.Outputs's in their full path string forms.
-func (m TestingModule) AllOutputs() []string {
-	return allOutputs(m.module)
+// VariablesForTestsRelativeToTop returns a copy of the Module.VariablesForTests() with every value
+// having any temporary build dir usages replaced with paths relative to a notional top.
+func (m TestingModule) VariablesForTestsRelativeToTop() map[string]string {
+	return normalizeStringMapRelativeToTop(m.config, m.module.VariablesForTests())
 }
 
 // TestingSingleton is wrapper around an android.Singleton that provides methods to find information about individual
 // ctx.Build parameters for verification in tests.
 type TestingSingleton struct {
+	baseTestingComponent
 	singleton Singleton
-	provider  testBuildProvider
 }
 
 // Singleton returns the Singleton wrapped by the TestingSingleton.
@@ -672,48 +794,6 @@
 	return s.singleton
 }
 
-// MaybeRule finds a call to ctx.Build with BuildParams.Rule set to a rule with the given name.  Returns an empty
-// BuildParams if no rule is found.
-func (s TestingSingleton) MaybeRule(rule string) TestingBuildParams {
-	r, _ := maybeBuildParamsFromRule(s.provider, rule)
-	return r
-}
-
-// Rule finds a call to ctx.Build with BuildParams.Rule set to a rule with the given name.  Panics if no rule is found.
-func (s TestingSingleton) Rule(rule string) TestingBuildParams {
-	return buildParamsFromRule(s.provider, rule)
-}
-
-// MaybeDescription finds a call to ctx.Build with BuildParams.Description set to a the given string.  Returns an empty
-// BuildParams if no rule is found.
-func (s TestingSingleton) MaybeDescription(desc string) TestingBuildParams {
-	return maybeBuildParamsFromDescription(s.provider, desc)
-}
-
-// Description finds a call to ctx.Build with BuildParams.Description set to a the given string.  Panics if no rule is
-// found.
-func (s TestingSingleton) Description(desc string) TestingBuildParams {
-	return buildParamsFromDescription(s.provider, desc)
-}
-
-// MaybeOutput finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputs whose String() or Rel()
-// value matches the provided string.  Returns an empty BuildParams if no rule is found.
-func (s TestingSingleton) MaybeOutput(file string) TestingBuildParams {
-	p, _ := maybeBuildParamsFromOutput(s.provider, file)
-	return p
-}
-
-// Output finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputs whose String() or Rel()
-// value matches the provided string.  Panics if no rule is found.
-func (s TestingSingleton) Output(file string) TestingBuildParams {
-	return buildParamsFromOutput(s.provider, file)
-}
-
-// AllOutputs returns all 'BuildParams.Output's and 'BuildParams.Outputs's in their full path string forms.
-func (s TestingSingleton) AllOutputs() []string {
-	return allOutputs(s.provider)
-}
-
 func FailIfErrored(t *testing.T, errs []error) {
 	t.Helper()
 	if len(errs) > 0 {
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 8974eba..b2bd6bd 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -91,7 +91,7 @@
 
 var dependencyTag = struct {
 	blueprint.BaseDependencyTag
-	android.InstallAlwaysNeededDependencyTag
+	android.PackagingItemAlwaysDepTag
 }{}
 
 func (f *filesystem) DepsMutator(ctx android.BottomUpMutatorContext) {
diff --git a/java/aar.go b/java/aar.go
index 554ea67..67b9ef0 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -40,15 +40,14 @@
 
 func init() {
 	RegisterAARBuildComponents(android.InitRegistrationContext)
-
-	android.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
-		ctx.TopDown("propagate_rro_enforcement", propagateRROEnforcementMutator).Parallel()
-	})
 }
 
 func RegisterAARBuildComponents(ctx android.RegistrationContext) {
 	ctx.RegisterModuleType("android_library_import", AARImportFactory)
 	ctx.RegisterModuleType("android_library", AndroidLibraryFactory)
+	ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
+		ctx.TopDown("propagate_rro_enforcement", propagateRROEnforcementMutator).Parallel()
+	})
 }
 
 //
diff --git a/java/android_resources.go b/java/android_resources.go
index 4d420cf..6864ebb 100644
--- a/java/android_resources.go
+++ b/java/android_resources.go
@@ -22,8 +22,11 @@
 )
 
 func init() {
-	android.RegisterPreSingletonType("overlay", OverlaySingletonFactory)
+	registerOverlayBuildComponents(android.InitRegistrationContext)
+}
 
+func registerOverlayBuildComponents(ctx android.RegistrationContext) {
+	ctx.RegisterPreSingletonType("overlay", OverlaySingletonFactory)
 }
 
 var androidResourceIgnoreFilenames = []string{
diff --git a/java/java_test.go b/java/java_test.go
index 913ed87..d27a73d 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -71,11 +71,11 @@
 	cc.PrepareForTestWithCcBuildComponents,
 	// Include all the default java modules.
 	PrepareForTestWithJavaDefaultModules,
+	PrepareForTestWithOverlayBuildComponents,
 	python.PrepareForTestWithPythonBuildComponents,
 	android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
 		ctx.RegisterModuleType("java_plugin", PluginFactory)
 
-		ctx.RegisterPreSingletonType("overlay", OverlaySingletonFactory)
 		ctx.RegisterPreSingletonType("sdk_versions", sdkPreSingletonFactory)
 	}),
 	dexpreopt.PrepareForTestWithDexpreopt,
@@ -126,10 +126,6 @@
 	// Register module types and mutators from cc needed for JNI testing
 	cc.RegisterRequiredBuildComponentsForTest(ctx)
 
-	ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
-		ctx.TopDown("propagate_rro_enforcement", propagateRROEnforcementMutator).Parallel()
-	})
-
 	return ctx
 }
 
diff --git a/java/testing.go b/java/testing.go
index 26d7c93..b0290dc 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -54,6 +54,8 @@
 	android.FixtureAddTextFile(defaultJavaDir+"/Android.bp", GatherRequiredDepsForTest()),
 )
 
+var PrepareForTestWithOverlayBuildComponents = android.FixtureRegisterWithContext(registerOverlayBuildComponents)
+
 // Prepare a fixture to use all java module types, mutators and singletons fully.
 //
 // This should only be used by tests that want to run with as much of the build enabled as possible.
diff --git a/scripts/strip.sh b/scripts/strip.sh
index 5b7a6da..43e6cbf 100755
--- a/scripts/strip.sh
+++ b/scripts/strip.sh
@@ -87,7 +87,7 @@
         comm -13 "${outfile}.dynsyms" "${outfile}.funcsyms" > "${outfile}.keep_symbols"
         echo >> "${outfile}.keep_symbols" # Ensure that the keep_symbols file is not empty.
         "${CROSS_COMPILE}objcopy" --rename-section .debug_frame=saved_debug_frame "${outfile}.debug" "${outfile}.mini_debuginfo"
-        "${CROSS_COMPILE}objcopy" -S --remove-section .gdb_index --remove-section .comment --keep-symbols="${outfile}.keep_symbols" "${outfile}.mini_debuginfo"
+        "${CROSS_COMPILE}objcopy" -S --remove-section .gdb_index --remove-section .comment --remove-section .rustc --keep-symbols="${outfile}.keep_symbols" "${outfile}.mini_debuginfo"
         "${CROSS_COMPILE}objcopy" --rename-section saved_debug_frame=.debug_frame "${outfile}.mini_debuginfo"
         "${XZ}" --block-size=64k --threads=0 "${outfile}.mini_debuginfo"