Merge "Revert "install *.so in different paths for their types""
diff --git a/android/mutator.go b/android/mutator.go
index 3420280..940b0ff 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -14,7 +14,11 @@
 
 package android
 
-import "github.com/google/blueprint"
+import (
+	"sync"
+
+	"github.com/google/blueprint"
+)
 
 // Mutator phases:
 //   Pre-arch
@@ -23,36 +27,68 @@
 //   Deps
 //   PostDeps
 
-func registerMutators() {
-	ctx := registerMutatorsContext{}
+var registerMutatorsOnce sync.Once
+var registeredMutators []*mutator
 
-	register := func(funcs []RegisterMutatorFunc) {
-		for _, f := range funcs {
-			f(ctx)
+func registerMutatorsToContext(ctx *blueprint.Context, mutators []*mutator) {
+	for _, t := range mutators {
+		var handle blueprint.MutatorHandle
+		if t.bottomUpMutator != nil {
+			handle = ctx.RegisterBottomUpMutator(t.name, t.bottomUpMutator)
+		} else if t.topDownMutator != nil {
+			handle = ctx.RegisterTopDownMutator(t.name, t.topDownMutator)
+		}
+		if t.parallel {
+			handle.Parallel()
 		}
 	}
-
-	ctx.TopDown("load_hooks", loadHookMutator).Parallel()
-	ctx.BottomUp("prebuilts", prebuiltMutator).Parallel()
-	ctx.BottomUp("defaults_deps", defaultsDepsMutator).Parallel()
-	ctx.TopDown("defaults", defaultsMutator).Parallel()
-
-	register(preArch)
-
-	ctx.BottomUp("arch", archMutator).Parallel()
-	ctx.TopDown("arch_hooks", archHookMutator).Parallel()
-
-	register(preDeps)
-
-	ctx.BottomUp("deps", depsMutator).Parallel()
-
-	ctx.TopDown("prebuilt_select", PrebuiltSelectModuleMutator).Parallel()
-	ctx.BottomUp("prebuilt_replace", PrebuiltReplaceMutator).Parallel()
-
-	register(postDeps)
 }
 
-type registerMutatorsContext struct{}
+func registerMutators(ctx *blueprint.Context) {
+
+	registerMutatorsOnce.Do(func() {
+		ctx := &registerMutatorsContext{}
+
+		register := func(funcs []RegisterMutatorFunc) {
+			for _, f := range funcs {
+				f(ctx)
+			}
+		}
+
+		ctx.TopDown("load_hooks", loadHookMutator).Parallel()
+		ctx.BottomUp("prebuilts", prebuiltMutator).Parallel()
+		ctx.BottomUp("defaults_deps", defaultsDepsMutator).Parallel()
+		ctx.TopDown("defaults", defaultsMutator).Parallel()
+
+		register(preArch)
+
+		ctx.BottomUp("arch", archMutator).Parallel()
+		ctx.TopDown("arch_hooks", archHookMutator).Parallel()
+
+		register(preDeps)
+
+		ctx.BottomUp("deps", depsMutator).Parallel()
+
+		ctx.TopDown("prebuilt_select", PrebuiltSelectModuleMutator).Parallel()
+		ctx.BottomUp("prebuilt_replace", PrebuiltReplaceMutator).Parallel()
+
+		register(postDeps)
+
+		registeredMutators = ctx.mutators
+	})
+
+	registerMutatorsToContext(ctx, registeredMutators)
+}
+
+func RegisterTestMutators(ctx *blueprint.Context) {
+	mutators := registerMutatorsContext{}
+	mutators.BottomUp("deps", depsMutator).Parallel()
+	registerMutatorsToContext(ctx, mutators.mutators)
+}
+
+type registerMutatorsContext struct {
+	mutators []*mutator
+}
 
 type RegisterMutatorsContext interface {
 	TopDown(name string, m AndroidTopDownMutator) MutatorHandle
@@ -99,7 +135,7 @@
 	androidBaseContextImpl
 }
 
-func (registerMutatorsContext) BottomUp(name string, m AndroidBottomUpMutator) MutatorHandle {
+func (x *registerMutatorsContext) BottomUp(name string, m AndroidBottomUpMutator) MutatorHandle {
 	f := func(ctx blueprint.BottomUpMutatorContext) {
 		if a, ok := ctx.Module().(Module); ok {
 			actx := &androidBottomUpMutatorContext{
@@ -110,11 +146,11 @@
 		}
 	}
 	mutator := &mutator{name: name, bottomUpMutator: f}
-	mutators = append(mutators, mutator)
+	x.mutators = append(x.mutators, mutator)
 	return mutator
 }
 
-func (registerMutatorsContext) TopDown(name string, m AndroidTopDownMutator) MutatorHandle {
+func (x *registerMutatorsContext) TopDown(name string, m AndroidTopDownMutator) MutatorHandle {
 	f := func(ctx blueprint.TopDownMutatorContext) {
 		if a, ok := ctx.Module().(Module); ok {
 			actx := &androidTopDownMutatorContext{
@@ -125,7 +161,7 @@
 		}
 	}
 	mutator := &mutator{name: name, topDownMutator: f}
-	mutators = append(mutators, mutator)
+	x.mutators = append(x.mutators, mutator)
 	return mutator
 }
 
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 5f9b4b0..006b66f 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -19,7 +19,11 @@
 // This file implements common functionality for handling modules that may exist as prebuilts,
 // source, or both.
 
-var prebuiltDependencyTag blueprint.BaseDependencyTag
+type prebuiltDependencyTag struct {
+	blueprint.BaseDependencyTag
+}
+
+var prebuiltDepTag prebuiltDependencyTag
 
 type Prebuilt struct {
 	Properties struct {
@@ -64,7 +68,7 @@
 		p := m.Prebuilt()
 		name := m.base().BaseModuleName()
 		if ctx.OtherModuleExists(name) {
-			ctx.AddReverseDependency(ctx.Module(), prebuiltDependencyTag, name)
+			ctx.AddReverseDependency(ctx.Module(), prebuiltDepTag, name)
 			p.Properties.SourceExists = true
 		} else {
 			ctx.Rename(name)
@@ -77,7 +81,7 @@
 func PrebuiltSelectModuleMutator(ctx TopDownMutatorContext) {
 	if s, ok := ctx.Module().(Module); ok {
 		ctx.VisitDirectDeps(func(m blueprint.Module) {
-			if ctx.OtherModuleDependencyTag(m) == prebuiltDependencyTag {
+			if ctx.OtherModuleDependencyTag(m) == prebuiltDepTag {
 				p := m.(PrebuiltInterface).Prebuilt()
 				if p.usePrebuilt(ctx, s) {
 					p.Properties.UsePrebuilt = true
diff --git a/android/register.go b/android/register.go
index d6b290d..9396664 100644
--- a/android/register.go
+++ b/android/register.go
@@ -15,8 +15,6 @@
 package android
 
 import (
-	"sync"
-
 	"github.com/google/blueprint"
 )
 
@@ -51,8 +49,6 @@
 	singletons = append(singletons, singleton{name, factory})
 }
 
-var registerMutatorsOnce sync.Once
-
 func NewContext() *blueprint.Context {
 	ctx := blueprint.NewContext()
 
@@ -64,19 +60,8 @@
 		ctx.RegisterSingletonType(t.name, t.factory)
 	}
 
-	registerMutatorsOnce.Do(registerMutators)
+	registerMutators(ctx)
 
-	for _, t := range mutators {
-		var handle blueprint.MutatorHandle
-		if t.bottomUpMutator != nil {
-			handle = ctx.RegisterBottomUpMutator(t.name, t.bottomUpMutator)
-		} else if t.topDownMutator != nil {
-			handle = ctx.RegisterTopDownMutator(t.name, t.topDownMutator)
-		}
-		if t.parallel {
-			handle.Parallel()
-		}
-	}
 	ctx.RegisterSingletonType("env", EnvSingleton)
 
 	return ctx
diff --git a/cc/test_data_test.go b/cc/test_data_test.go
index e3b1214..9b5a85a 100644
--- a/cc/test_data_test.go
+++ b/cc/test_data_test.go
@@ -22,6 +22,8 @@
 	"testing"
 
 	"android/soong/android"
+	"android/soong/genrule"
+
 	"github.com/google/blueprint"
 )
 
@@ -121,13 +123,15 @@
 
 	for _, test := range testDataTests {
 		t.Run(test.name, func(t *testing.T) {
-			ctx := android.NewContext()
+			ctx := blueprint.NewContext()
+			android.RegisterTestMutators(ctx)
 			ctx.MockFileSystem(map[string][]byte{
 				"Blueprints":     []byte(`subdirs = ["dir"]`),
 				"dir/Blueprints": []byte(test.modules),
 				"dir/baz":        nil,
 				"dir/bar/baz":    nil,
 			})
+			ctx.RegisterModuleType("filegroup", genrule.FileGroupFactory)
 			ctx.RegisterModuleType("test", newTest)
 
 			_, errs := ctx.ParseBlueprintsFiles("Blueprints")
diff --git a/genrule/filegroup.go b/genrule/filegroup.go
index c1d08a8..71c5439 100644
--- a/genrule/filegroup.go
+++ b/genrule/filegroup.go
@@ -21,7 +21,7 @@
 )
 
 func init() {
-	android.RegisterModuleType("filegroup", fileGroupFactory)
+	android.RegisterModuleType("filegroup", FileGroupFactory)
 }
 
 type fileGroupProperties struct {
@@ -48,7 +48,7 @@
 // filegroup modules contain a list of files, and can be used to export files across package
 // boundaries.  filegroups (and genrules) can be referenced from srcs properties of other modules
 // using the syntax ":module".
-func fileGroupFactory() (blueprint.Module, []interface{}) {
+func FileGroupFactory() (blueprint.Module, []interface{}) {
 	module := &fileGroup{}
 
 	return android.InitAndroidModule(module, &module.properties)