Fix few issues with filegroups

Bug: http://b/64121881
Bug: http://b/78188880

- Allow filegroup's properties to be extended by a LoadHook
- Support a filegroup (':module') in a prebuilt's 'Srcs' property to
export files from a different path as the prebuilt's sources.

This change also includes a refactoring that moves genrule/filegroup.go
to android/filegroup.go so that FileGroupFactory is visible in
prebuilt_test.go.

Test: Test
https://android-review.googlesource.com/c/platform/development/+/469159
in clang-tools branch on Linux, Darwin.  Test regular build in
aosp/master.

Change-Id: I3ff6215ab2e62955f039fd1086c31f1bd50ebcf6
diff --git a/Android.bp b/Android.bp
index ad2ad47..f2289da 100644
--- a/Android.bp
+++ b/Android.bp
@@ -46,6 +46,7 @@
         "android/defaults.go",
         "android/defs.go",
         "android/expand.go",
+        "android/filegroup.go",
         "android/hooks.go",
         "android/makevars.go",
         "android/module.go",
@@ -186,7 +187,6 @@
         "soong-shared",
     ],
     srcs: [
-        "genrule/filegroup.go",
         "genrule/genrule.go",
     ],
     pluginFor: ["soong_build"],
diff --git a/genrule/filegroup.go b/android/filegroup.go
similarity index 75%
rename from genrule/filegroup.go
rename to android/filegroup.go
index 2cff5fe..b284ce0 100644
--- a/genrule/filegroup.go
+++ b/android/filegroup.go
@@ -12,17 +12,16 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package genrule
+package android
 
 import (
-	"android/soong/android"
 	"io"
 	"strings"
 	"text/template"
 )
 
 func init() {
-	android.RegisterModuleType("filegroup", FileGroupFactory)
+	RegisterModuleType("filegroup", FileGroupFactory)
 }
 
 type fileGroupProperties struct {
@@ -43,34 +42,34 @@
 }
 
 type fileGroup struct {
-	android.ModuleBase
+	ModuleBase
 	properties fileGroupProperties
-	srcs       android.Paths
+	srcs       Paths
 }
 
-var _ android.SourceFileProducer = (*fileGroup)(nil)
+var _ SourceFileProducer = (*fileGroup)(nil)
 
 // 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() android.Module {
+func FileGroupFactory() Module {
 	module := &fileGroup{}
 	module.AddProperties(&module.properties)
-	android.InitAndroidModule(module)
+	InitAndroidModule(module)
 	return module
 }
 
-func (fg *fileGroup) DepsMutator(ctx android.BottomUpMutatorContext) {
-	android.ExtractSourcesDeps(ctx, fg.properties.Srcs)
-	android.ExtractSourcesDeps(ctx, fg.properties.Exclude_srcs)
+func (fg *fileGroup) DepsMutator(ctx BottomUpMutatorContext) {
+	ExtractSourcesDeps(ctx, fg.properties.Srcs)
+	ExtractSourcesDeps(ctx, fg.properties.Exclude_srcs)
 }
 
-func (fg *fileGroup) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+func (fg *fileGroup) GenerateAndroidBuildActions(ctx ModuleContext) {
 	fg.srcs = ctx.ExpandSourcesSubDir(fg.properties.Srcs, fg.properties.Exclude_srcs, String(fg.properties.Path))
 }
 
-func (fg *fileGroup) Srcs() android.Paths {
-	return append(android.Paths{}, fg.srcs...)
+func (fg *fileGroup) Srcs() Paths {
+	return append(Paths{}, fg.srcs...)
 }
 
 var androidMkTemplate = template.Must(template.New("filegroup").Parse(`
@@ -81,9 +80,9 @@
 .KATI_READONLY := {{.makeVar}}
 `))
 
-func (fg *fileGroup) AndroidMk() android.AndroidMkData {
-	return android.AndroidMkData{
-		Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
+func (fg *fileGroup) AndroidMk() AndroidMkData {
+	return AndroidMkData{
+		Custom: func(w io.Writer, name, prefix, moduleDir string, data AndroidMkData) {
 			if makeVar := String(fg.properties.Export_to_make_var); makeVar != "" {
 				androidMkTemplate.Execute(w, map[string]string{
 					"makeVar": makeVar,
diff --git a/android/module.go b/android/module.go
index a011f57..3bd256a 100644
--- a/android/module.go
+++ b/android/module.go
@@ -323,6 +323,7 @@
 		&base.nameProperties,
 		&base.commonProperties,
 		&base.variableProperties)
+	base.customizableProperties = m.GetProperties()
 }
 
 func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 9356aab..47c5cf5 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -59,7 +59,9 @@
 		return nil
 	}
 
-	return PathForModuleSrc(ctx, (*p.srcs)[0])
+	// Return the singleton source after expanding any filegroup in the
+	// sources.
+	return ctx.ExpandSource((*p.srcs)[0], "")
 }
 
 func InitPrebuiltModule(module PrebuiltInterface, srcs *[]string) {
@@ -79,7 +81,7 @@
 
 func RegisterPrebuiltsPostDepsMutators(ctx RegisterMutatorsContext) {
 	ctx.TopDown("prebuilt_select", PrebuiltSelectModuleMutator).Parallel()
-	ctx.BottomUp("prebuilt_replace", PrebuiltReplaceMutator).Parallel()
+	ctx.BottomUp("prebuilt_postdeps", PrebuiltPostDepsMutator).Parallel()
 }
 
 // prebuiltMutator ensures that there is always a module with an undecorated name, and marks
@@ -119,10 +121,12 @@
 	}
 }
 
-// PrebuiltReplaceMutator replaces dependencies on the source module with dependencies on the
-// prebuilt when both modules exist and the prebuilt should be used.  When the prebuilt should not
-// be used, disable installing it.
-func PrebuiltReplaceMutator(ctx BottomUpMutatorContext) {
+// PrebuiltPostDepsMutator does two operations.  It replace dependencies on the
+// source module with dependencies on the prebuilt when both modules exist and
+// the prebuilt should be used.  When the prebuilt should not be used, disable
+// installing it.  Secondly, it also adds a sourcegroup to any filegroups found
+// in the prebuilt's 'Srcs' property.
+func PrebuiltPostDepsMutator(ctx BottomUpMutatorContext) {
 	if m, ok := ctx.Module().(PrebuiltInterface); ok && m.Prebuilt() != nil {
 		p := m.Prebuilt()
 		name := m.base().BaseModuleName()
@@ -133,6 +137,9 @@
 		} else {
 			m.SkipInstall()
 		}
+		if len(*p.srcs) > 0 {
+			ExtractSourceDeps(ctx, &(*p.srcs)[0])
+		}
 	}
 }
 
diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go
index 69ce16a..cd1ffae 100644
--- a/android/prebuilt_test.go
+++ b/android/prebuilt_test.go
@@ -109,6 +109,19 @@
 			}`,
 		prebuilt: false,
 	},
+	{
+		name: "prebuilt file from filegroup preferred",
+		modules: `
+			filegroup {
+				name: "fg",
+			}
+			prebuilt {
+				name: "bar",
+				prefer: true,
+				srcs: [":fg"],
+			}`,
+		prebuilt: true,
+	},
 }
 
 func TestPrebuilts(t *testing.T) {
@@ -125,6 +138,7 @@
 			ctx := NewTestContext()
 			ctx.PreArchMutators(RegisterPrebuiltsPreArchMutators)
 			ctx.PostDepsMutators(RegisterPrebuiltsPostDepsMutators)
+			ctx.RegisterModuleType("filegroup", ModuleFactoryAdaptor(FileGroupFactory))
 			ctx.RegisterModuleType("prebuilt", ModuleFactoryAdaptor(newPrebuiltModule))
 			ctx.RegisterModuleType("source", ModuleFactoryAdaptor(newSourceModule))
 			ctx.Register()
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 10c1aba..9b4cc0f 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -16,7 +16,6 @@
 
 import (
 	"android/soong/android"
-	"android/soong/genrule"
 
 	"fmt"
 	"io/ioutil"
@@ -62,7 +61,7 @@
 	ctx.RegisterModuleType("llndk_headers", android.ModuleFactoryAdaptor(llndkHeadersFactory))
 	ctx.RegisterModuleType("vendor_public_library", android.ModuleFactoryAdaptor(vendorPublicLibraryFactory))
 	ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(objectFactory))
-	ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(genrule.FileGroupFactory))
+	ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(android.FileGroupFactory))
 	ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
 		ctx.BottomUp("image", vendorMutator).Parallel()
 		ctx.BottomUp("link", linkageMutator).Parallel()
diff --git a/cc/test_data_test.go b/cc/test_data_test.go
index 4a7b0f7..56c3e38 100644
--- a/cc/test_data_test.go
+++ b/cc/test_data_test.go
@@ -22,7 +22,6 @@
 	"testing"
 
 	"android/soong/android"
-	"android/soong/genrule"
 )
 
 type dataFile struct {
@@ -129,7 +128,7 @@
 				"dir/bar/baz":    nil,
 			})
 			ctx.RegisterModuleType("filegroup",
-				android.ModuleFactoryAdaptor(genrule.FileGroupFactory))
+				android.ModuleFactoryAdaptor(android.FileGroupFactory))
 			ctx.RegisterModuleType("test",
 				android.ModuleFactoryAdaptor(newTest))
 			ctx.Register()
diff --git a/java/java_test.go b/java/java_test.go
index 65db68d..d4f2be1 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -78,7 +78,7 @@
 	ctx.RegisterModuleType("java_defaults", android.ModuleFactoryAdaptor(defaultsFactory))
 	ctx.RegisterModuleType("java_system_modules", android.ModuleFactoryAdaptor(SystemModulesFactory))
 	ctx.RegisterModuleType("java_genrule", android.ModuleFactoryAdaptor(genRuleFactory))
-	ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(genrule.FileGroupFactory))
+	ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(android.FileGroupFactory))
 	ctx.RegisterModuleType("genrule", android.ModuleFactoryAdaptor(genrule.GenRuleFactory))
 	ctx.RegisterModuleType("droiddoc", android.ModuleFactoryAdaptor(DroiddocFactory))
 	ctx.RegisterModuleType("droiddoc_host", android.ModuleFactoryAdaptor(DroiddocHostFactory))