Add prebuilt_apex.

Bug: 127789981
Test: apex_test.go + com.android.tzdata.apex
Change-Id: I09bb0a4b2acf310c55c789569da3c9d755638232
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 5bd0e2d..df25a89 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -18,6 +18,7 @@
 	"fmt"
 
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/proptools"
 )
 
 // This file implements common functionality for handling modules that may exist as prebuilts,
@@ -42,6 +43,7 @@
 	properties PrebuiltProperties
 	module     Module
 	srcs       *[]string
+	src        *string
 }
 
 func (p *Prebuilt) Name(name string) string {
@@ -49,19 +51,27 @@
 }
 
 func (p *Prebuilt) SingleSourcePath(ctx ModuleContext) Path {
-	if len(*p.srcs) == 0 {
-		ctx.PropertyErrorf("srcs", "missing prebuilt source file")
-		return nil
-	}
+	if p.srcs != nil {
+		if len(*p.srcs) == 0 {
+			ctx.PropertyErrorf("srcs", "missing prebuilt source file")
+			return nil
+		}
 
-	if len(*p.srcs) > 1 {
-		ctx.PropertyErrorf("srcs", "multiple prebuilt source files")
-		return nil
-	}
+		if len(*p.srcs) > 1 {
+			ctx.PropertyErrorf("srcs", "multiple prebuilt source files")
+			return nil
+		}
 
-	// Return the singleton source after expanding any filegroup in the
-	// sources.
-	return PathForModuleSrc(ctx, (*p.srcs)[0])
+		// Return the singleton source after expanding any filegroup in the
+		// sources.
+		return PathForModuleSrc(ctx, (*p.srcs)[0])
+	} else {
+		if proptools.String(p.src) == "" {
+			ctx.PropertyErrorf("src", "missing prebuilt source file")
+			return nil
+		}
+		return PathForModuleSrc(ctx, *p.src)
+	}
 }
 
 func InitPrebuiltModule(module PrebuiltInterface, srcs *[]string) {
@@ -70,13 +80,19 @@
 	p.srcs = srcs
 }
 
+func InitSingleSourcePrebuiltModule(module PrebuiltInterface, src *string) {
+	p := module.Prebuilt()
+	module.AddProperties(&p.properties)
+	p.src = src
+}
+
 type PrebuiltInterface interface {
 	Module
 	Prebuilt() *Prebuilt
 }
 
 func RegisterPrebuiltsPreArchMutators(ctx RegisterMutatorsContext) {
-	ctx.BottomUp("prebuilts", prebuiltMutator).Parallel()
+	ctx.BottomUp("prebuilts", PrebuiltMutator).Parallel()
 }
 
 func RegisterPrebuiltsPostDepsMutators(ctx RegisterMutatorsContext) {
@@ -84,9 +100,9 @@
 	ctx.BottomUp("prebuilt_postdeps", PrebuiltPostDepsMutator).Parallel()
 }
 
-// prebuiltMutator ensures that there is always a module with an undecorated name, and marks
+// PrebuiltMutator ensures that there is always a module with an undecorated name, and marks
 // prebuilt modules that have both a prebuilt and a source module.
-func prebuiltMutator(ctx BottomUpMutatorContext) {
+func PrebuiltMutator(ctx BottomUpMutatorContext) {
 	if m, ok := ctx.Module().(PrebuiltInterface); ok && m.Prebuilt() != nil {
 		p := m.Prebuilt()
 		name := m.base().BaseModuleName()
@@ -104,7 +120,7 @@
 func PrebuiltSelectModuleMutator(ctx TopDownMutatorContext) {
 	if m, ok := ctx.Module().(PrebuiltInterface); ok && m.Prebuilt() != nil {
 		p := m.Prebuilt()
-		if p.srcs == nil {
+		if p.srcs == nil && p.src == nil {
 			panic(fmt.Errorf("prebuilt module did not have InitPrebuiltModule called on it"))
 		}
 		if !p.properties.SourceExists {
@@ -143,7 +159,11 @@
 // usePrebuilt returns true if a prebuilt should be used instead of the source module.  The prebuilt
 // will be used if it is marked "prefer" or if the source module is disabled.
 func (p *Prebuilt) usePrebuilt(ctx TopDownMutatorContext, source Module) bool {
-	if len(*p.srcs) == 0 {
+	if p.srcs != nil && len(*p.srcs) == 0 {
+		return false
+	}
+
+	if p.src != nil && *p.src == "" {
 		return false
 	}