Refactor Android.bp build modules for readability

When we compile sepolicy files into a cil file, we first gather all
sepolicy files to create a conf file, and then convert the conf file to
a cil file with checkpolicy. The problem is that checkpolicy is
sensitive to the input order; the conf file should contain statements in
a specific order: classes, initial_sid, access vectors, macros, mls,
etc.

This restriction has made Android.bp migration difficult, and we had to
create a magical module called "se_build_files" to correctly include
source files in the designated order. It works, but significant
readability problem has happened. For example, when we write
":se_build_files{.system_ext_public}", how can we easily figure out that
the tag actually includes plat public + system_ext public + reqd mask,
without taking a look at the build system code?

This change refactors the se_build_files module and se_policy_conf
module, so we can easily see the desginated files for each module, just
like we did in the Android.mk. se_policy_conf module now stably sorts
source files in an order which will make checkpolicy happy.
se_build_files module is also refactored, so one tag can represent
exactly one set of policy files, rather than doing magical works behind
the scene. For example, system_ext public policy module is changed from:

se_policy_conf {
    name: "system_ext_pub_policy.conf",
    // se_build_files automatically adds plat public and reqd mask
    srcs: [":se_build_files{.system_ext_public}"],
}

to:

se_policy_conf {
    name: "system_ext_pub_policy.conf",
    // se_policy_conf automatically sorts the input files
    srcs: [
        ":se_build_files{.plat_public}",
        ":se_build_files{.system_ext_public}",
        ":se_build_files{.reqd_mask}",
    ],
}

Bug: 209933272
Test: build and diff before/after
Change-Id: I97a76ed910645c1607d913fd646c27e87af0afd3
diff --git a/build/soong/build_files.go b/build/soong/build_files.go
index 5de6122..8f77e4f 100644
--- a/build/soong/build_files.go
+++ b/build/soong/build_files.go
@@ -17,7 +17,6 @@
 import (
 	"fmt"
 	"path/filepath"
-	"sort"
 	"strings"
 
 	"android/soong/android"
@@ -29,8 +28,8 @@
 
 // se_build_files gathers policy files from sepolicy dirs, and acts like a filegroup. A tag with
 // partition(plat, system_ext, product) and scope(public, private) is used to select directories.
-// Supported tags are: "plat", "plat_public", "system_ext", "system_ext_public", "product",
-// "product_public", and "reqd_mask".
+// Supported tags are: "plat_public", "plat_private", "system_ext_public", "system_ext_private",
+// "product_public", "product_private", and "reqd_mask".
 func buildFilesFactory() android.Module {
 	module := &buildFiles{}
 	module.AddProperties(&module.properties)
@@ -86,114 +85,18 @@
 
 var _ android.OutputFileProducer = (*buildFiles)(nil)
 
-type partition int
-
-const (
-	system partition = iota
-	system_ext
-	product
-)
-
-type scope int
-
-const (
-	public scope = iota
-	private
-)
-
 type sepolicyDir struct {
-	partition partition
-	scope     scope
-	paths     []string
-}
-
-func (p partition) String() string {
-	switch p {
-	case system:
-		return "plat"
-	case system_ext:
-		return "system_ext"
-	case product:
-		return "product"
-	default:
-		panic(fmt.Sprintf("Unknown partition %#v", p))
-	}
+	tag   string
+	paths []string
 }
 
 func (b *buildFiles) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	// Sepolicy directories should be included in the following order.
-	//   - system_public
-	//   - system_private
-	//   - system_ext_public
-	//   - system_ext_private
-	//   - product_public
-	//   - product_private
-	dirs := []sepolicyDir{
-		sepolicyDir{partition: system, scope: public, paths: []string{filepath.Join(ctx.ModuleDir(), "public")}},
-		sepolicyDir{partition: system, scope: private, paths: []string{filepath.Join(ctx.ModuleDir(), "private")}},
-		sepolicyDir{partition: system_ext, scope: public, paths: ctx.DeviceConfig().SystemExtPublicSepolicyDirs()},
-		sepolicyDir{partition: system_ext, scope: private, paths: ctx.DeviceConfig().SystemExtPrivateSepolicyDirs()},
-		sepolicyDir{partition: product, scope: public, paths: ctx.Config().ProductPublicSepolicyDirs()},
-		sepolicyDir{partition: product, scope: private, paths: ctx.Config().ProductPrivateSepolicyDirs()},
-	}
-
-	if !sort.SliceIsSorted(dirs, func(i, j int) bool {
-		if dirs[i].partition != dirs[j].partition {
-			return dirs[i].partition < dirs[j].partition
-		}
-
-		return dirs[i].scope < dirs[j].scope
-	}) {
-		panic("dirs is not sorted")
-	}
-
-	// Exported cil policy files are built with the following policies.
-	//
-	//   - plat_pub_policy.cil: exported 'system'
-	//   - system_ext_pub_policy.cil: exported 'system' and 'system_ext'
-	//   - pub_policy.cil: exported 'system', 'system_ext', and 'product'
-	//
-	// cil policy files are built with the following policies.
-	//
-	//   - plat_policy.cil: 'system', including private
-	//   - system_ext_policy.cil: 'system_ext', including private
-	//   - product_sepolicy.cil: 'product', including private
-	//
-	// gatherDirsFor collects all needed directories for given partition and scope. For example,
-	//
-	//   - gatherDirsFor(system_ext, private) will return system + system_ext (including private)
-	//   - gatherDirsFor(product, public) will return system + system_ext + product (public only)
-	//
-	// "dirs" should be sorted before calling this.
-	gatherDirsFor := func(p partition, s scope) []string {
-		var ret []string
-
-		for _, d := range dirs {
-			if d.partition <= p && d.scope <= s {
-				ret = append(ret, d.paths...)
-			}
-		}
-
-		return ret
-	}
-
-	reqdMaskDir := filepath.Join(ctx.ModuleDir(), "reqd_mask")
-
 	b.srcs = make(map[string]android.Paths)
-	b.srcs[".reqd_mask"] = b.findSrcsInDirs(ctx, reqdMaskDir)
-
-	for _, p := range []partition{system, system_ext, product} {
-		b.srcs["."+p.String()] = b.findSrcsInDirs(ctx, gatherDirsFor(p, private)...)
-
-		// reqd_mask is needed for public policies
-		b.srcs["."+p.String()+"_public"] = b.findSrcsInDirs(ctx, append(gatherDirsFor(p, public), reqdMaskDir)...)
-	}
-
-	// A special tag, "plat_vendor", includes minimized vendor policies required to boot.
-	//   - system/sepolicy/public
-	//   - system/sepolicy/reqd_mask
-	//   - system/sepolicy/vendor
-	// This is for minimized vendor partition, e.g. microdroid's vendor
-	platVendorDir := filepath.Join(ctx.ModuleDir(), "vendor")
-	b.srcs[".plat_vendor"] = b.findSrcsInDirs(ctx, append(gatherDirsFor(system, public), reqdMaskDir, platVendorDir)...)
+	b.srcs[".reqd_mask"] = b.findSrcsInDirs(ctx, filepath.Join(ctx.ModuleDir(), "reqd_mask"))
+	b.srcs[".plat_public"] = b.findSrcsInDirs(ctx, filepath.Join(ctx.ModuleDir(), "public"))
+	b.srcs[".plat_private"] = b.findSrcsInDirs(ctx, filepath.Join(ctx.ModuleDir(), "private"))
+	b.srcs[".system_ext_public"] = b.findSrcsInDirs(ctx, ctx.DeviceConfig().SystemExtPublicSepolicyDirs()...)
+	b.srcs[".system_ext_private"] = b.findSrcsInDirs(ctx, ctx.DeviceConfig().SystemExtPrivateSepolicyDirs()...)
+	b.srcs[".product_public"] = b.findSrcsInDirs(ctx, ctx.Config().ProductPublicSepolicyDirs()...)
+	b.srcs[".product_private"] = b.findSrcsInDirs(ctx, ctx.Config().ProductPrivateSepolicyDirs()...)
 }