sepolicy: support /system_ext and /product mapping files

Install mapping files in SYSTEM_EXT_PRIVATE_POLICY and
PRODUCT_PRIVATE_POLICY into /system_ext and /product respectively.

Bug: 141084341
Test: boot taimen
Test: system mapping files are unchanged
Test: create mapping files in device/google/wahoo/sepolicy/ and check
that they are correctly expanded and installed.
Change-Id: I4d251c957b30a16df71eec47c871e24e5fc773a4
diff --git a/Android.bp b/Android.bp
index b3e26ba..4973c13 100644
--- a/Android.bp
+++ b/Android.bp
@@ -71,27 +71,95 @@
 }
 
 se_cil_compat_map {
-    name: "26.0.cil",
+    name: "plat_26.0.cil",
+    stem: "26.0.cil",
     bottom_half: [":26.0.board.compat.map"],
-    top_half: "27.0.cil",
+    top_half: "plat_27.0.cil",
 }
 
 se_cil_compat_map {
-    name: "27.0.cil",
+    name: "plat_27.0.cil",
+    stem: "27.0.cil",
     bottom_half: [":27.0.board.compat.map"],
-    top_half: "28.0.cil",
+    top_half: "plat_28.0.cil",
 }
 
 se_cil_compat_map {
-    name: "28.0.cil",
+    name: "plat_28.0.cil",
+    stem: "28.0.cil",
     bottom_half: [":28.0.board.compat.map"],
-    top_half: "29.0.cil",
+    top_half: "plat_29.0.cil",
 }
 
 se_cil_compat_map {
-    name: "29.0.cil",
+    name: "plat_29.0.cil",
+    stem: "29.0.cil",
     bottom_half: [":29.0.board.compat.map"],
-    // top_half: "30.0.cil",
+    // top_half: "plat_30.0.cil",
+}
+
+se_cil_compat_map {
+    name: "system_ext_26.0.cil",
+    stem: "26.0.cil",
+    bottom_half: [":26.0.board.compat.map"],
+    top_half: "system_ext_27.0.cil",
+    system_ext_specific: true,
+}
+
+se_cil_compat_map {
+    name: "system_ext_27.0.cil",
+    stem: "27.0.cil",
+    bottom_half: [":27.0.board.compat.map"],
+    top_half: "system_ext_28.0.cil",
+    system_ext_specific: true,
+}
+
+se_cil_compat_map {
+    name: "system_ext_28.0.cil",
+    stem: "28.0.cil",
+    bottom_half: [":28.0.board.compat.map"],
+    top_half: "system_ext_29.0.cil",
+    system_ext_specific: true,
+}
+
+se_cil_compat_map {
+    name: "system_ext_29.0.cil",
+    stem: "29.0.cil",
+    bottom_half: [":29.0.board.compat.map"],
+    // top_half: "system_ext_30.0.cil",
+    system_ext_specific: true,
+}
+
+se_cil_compat_map {
+    name: "product_26.0.cil",
+    stem: "26.0.cil",
+    bottom_half: [":26.0.board.compat.map"],
+    top_half: "product_27.0.cil",
+    product_specific: true,
+}
+
+se_cil_compat_map {
+    name: "product_27.0.cil",
+    stem: "27.0.cil",
+    bottom_half: [":27.0.board.compat.map"],
+    top_half: "product_28.0.cil",
+    product_specific: true,
+}
+
+se_cil_compat_map {
+    name: "product_28.0.cil",
+    stem: "28.0.cil",
+    bottom_half: [":28.0.board.compat.map"],
+    top_half: "product_29.0.cil",
+    product_specific: true,
+}
+
+se_cil_compat_map {
+    name: "product_29.0.cil",
+    stem: "29.0.cil",
+    bottom_half: [":29.0.board.compat.map"],
+    // top_half: "product_30.0.cil",
+    product_specific: true,
 }
 
 se_cil_compat_map {
diff --git a/Android.mk b/Android.mk
index b516fa1..5a99d6c 100644
--- a/Android.mk
+++ b/Android.mk
@@ -236,7 +236,7 @@
 # divergence between Treble and non-Treble devices.
 LOCAL_REQUIRED_MODULES += \
     plat_mapping_file \
-    $(addsuffix .cil,$(PLATFORM_SEPOLICY_COMPAT_VERSIONS)) \
+    $(addprefix plat_,$(addsuffix .cil,$(PLATFORM_SEPOLICY_COMPAT_VERSIONS))) \
     $(addsuffix .compat.cil,$(PLATFORM_SEPOLICY_COMPAT_VERSIONS)) \
     plat_sepolicy.cil \
     plat_sepolicy_and_mapping.sha256 \
@@ -342,7 +342,10 @@
 endif
 
 ifdef HAS_SYSTEM_EXT_PUBLIC_SEPOLICY
-LOCAL_REQUIRED_MODULES += system_ext_mapping_file
+LOCAL_REQUIRED_MODULES += \
+    system_ext_mapping_file \
+    $(addprefix system_ext_,$(addsuffix .cil,$(PLATFORM_SEPOLICY_COMPAT_VERSIONS))) \
+
 endif
 
 ifdef HAS_SYSTEM_EXT_SEPOLICY_DIR
@@ -365,7 +368,10 @@
 endif
 
 ifdef HAS_PRODUCT_PUBLIC_SEPOLICY
-LOCAL_REQUIRED_MODULES += product_mapping_file
+LOCAL_REQUIRED_MODULES += \
+    product_mapping_file \
+    $(addprefix product_,$(addsuffix .cil,$(PLATFORM_SEPOLICY_COMPAT_VERSIONS))) \
+
 endif
 
 ifdef HAS_PRODUCT_SEPOLICY_DIR
diff --git a/build/soong/cil_compat_map.go b/build/soong/cil_compat_map.go
index 6eef2f2..f304e62 100644
--- a/build/soong/cil_compat_map.go
+++ b/build/soong/cil_compat_map.go
@@ -51,7 +51,7 @@
 func cilCompatMapFactory() android.Module {
 	c := &cilCompatMap{}
 	c.AddProperties(&c.properties)
-	android.InitAndroidModule(c)
+	android.InitAndroidArchModule(c, android.DeviceSupported, android.MultilibCommon)
 	return c
 }
 
@@ -65,6 +65,8 @@
 	// other modules that produce source files like genrule or filegroup using
 	// the syntax ":module". srcs has to be non-empty.
 	Bottom_half []string
+	// name of the output
+	Stem *string
 }
 
 type cilCompatMap struct {
@@ -72,6 +74,7 @@
 	properties cilCompatMapProperties
 	// (.intermediate) module output path as installation source.
 	installSource android.Path
+	installPath   android.InstallPath
 }
 
 type CilCompatMapGenerator interface {
@@ -100,11 +103,13 @@
 				continue
 			}
 			if fg, ok := module.(*fileGroup); ok {
-				// Core compatibility mapping files are under system/sepolicy/private.
-				expandedSrcFiles = append(expandedSrcFiles, fg.SystemPrivateSrcs()...)
-				// Partner extensions to the compatibility mapping in must be located in
-				// BOARD_PLAT_PRIVATE_SEPOLICY_DIR
-				expandedSrcFiles = append(expandedSrcFiles, fg.SystemExtPrivateSrcs()...)
+				if ctx.ProductSpecific() {
+					expandedSrcFiles = append(expandedSrcFiles, fg.ProductPrivateSrcs()...)
+				} else if ctx.SystemExtSpecific() {
+					expandedSrcFiles = append(expandedSrcFiles, fg.SystemExtPrivateSrcs()...)
+				} else {
+					expandedSrcFiles = append(expandedSrcFiles, fg.SystemPrivateSrcs()...)
+				}
 			} else {
 				ctx.ModuleErrorf("srcs dependency %q is not an selinux filegroup", m)
 			}
@@ -117,6 +122,8 @@
 }
 
 func (c *cilCompatMap) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	c.installPath = android.PathForModuleInstall(ctx, "etc", "selinux", "mapping")
+
 	srcFiles := expandSeSources(ctx, c.properties.Bottom_half)
 
 	for _, src := range srcFiles {
@@ -166,7 +173,10 @@
 		Class:      "ETC",
 	}
 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
-		fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/selinux/mapping")
+		fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", c.installPath.ToMakePath().String())
+		if c.properties.Stem != nil {
+			fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", String(c.properties.Stem))
+		}
 	})
 	return ret
 }
diff --git a/treble_sepolicy_tests_for_release.mk b/treble_sepolicy_tests_for_release.mk
index 5e8e054..0195e5f 100644
--- a/treble_sepolicy_tests_for_release.mk
+++ b/treble_sepolicy_tests_for_release.mk
@@ -54,7 +54,7 @@
 # targeting the $(version) SELinux release.  This ensures that our policy will build
 # when used on a device that has non-platform policy targetting the $(version) release.
 $(version)_compat := $(intermediates)/$(version)_compat
-$(version)_mapping.cil := $(call intermediates-dir-for,ETC,$(version).cil)/$(version).cil
+$(version)_mapping.cil := $(call intermediates-dir-for,ETC,plat_$(version).cil)/plat_$(version).cil
 $(version)_mapping.ignore.cil := \
     $(call intermediates-dir-for,ETC,$(version).ignore.cil)/$(version).ignore.cil
 $(version)_prebuilts_dir := $(LOCAL_PATH)/prebuilts/api/$(version)