Merge "Build contexts files with Soong"
diff --git a/Android.bp b/Android.bp
index 256262b..eeca38d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -91,3 +91,143 @@
     bottom_half: [":28.0.board.ignore.map"],
     // top_half: "29.0.ignore.cil",
 }
+
+se_filegroup {
+    name: "file_contexts_files",
+    srcs: ["file_contexts"],
+}
+
+se_filegroup {
+    name: "file_contexts_asan_files",
+    srcs: ["file_contexts_asan"],
+}
+
+se_filegroup {
+    name: "file_contexts_overlayfs_files",
+    srcs: ["file_contexts_overlayfs"],
+}
+
+se_filegroup {
+    name: "hwservice_contexts_files",
+    srcs: ["hwservice_contexts"],
+}
+
+se_filegroup {
+    name: "property_contexts_files",
+    srcs: ["property_contexts"],
+}
+
+se_filegroup {
+    name: "service_contexts_files",
+    srcs: ["service_contexts"],
+}
+
+file_contexts {
+    name: "plat_file_contexts",
+    srcs: [":file_contexts_files"],
+    product_variables: {
+        address_sanitize: {
+            srcs: [":file_contexts_asan_files"],
+        },
+        debuggable: {
+            srcs: [":file_contexts_overlayfs_files"],
+        },
+    },
+
+    flatten_apex: {
+        srcs: ["apex/*-file_contexts"],
+    },
+
+    recovery_available: true,
+}
+
+file_contexts {
+    name: "vendor_file_contexts",
+    srcs: [":file_contexts_files"],
+    soc_specific: true,
+    recovery_available: true,
+}
+
+file_contexts {
+    name: "product_file_contexts",
+    srcs: [":file_contexts_files"],
+    product_specific: true,
+    recovery_available: true,
+}
+
+file_contexts {
+    name: "odm_file_contexts",
+    srcs: [":file_contexts_files"],
+    device_specific: true,
+    recovery_available: true,
+}
+
+hwservice_contexts {
+    name: "plat_hwservice_contexts",
+    srcs: [":hwservice_contexts_files"],
+}
+
+hwservice_contexts {
+    name: "product_hwservice_contexts",
+    srcs: [":hwservice_contexts_files"],
+    product_specific: true,
+}
+
+hwservice_contexts {
+    name: "vendor_hwservice_contexts",
+    srcs: [":hwservice_contexts_files"],
+    reqd_mask: true,
+    soc_specific: true,
+}
+
+hwservice_contexts {
+    name: "odm_hwservice_contexts",
+    srcs: [":hwservice_contexts_files"],
+    device_specific: true,
+}
+
+property_contexts {
+    name: "plat_property_contexts",
+    srcs: [":property_contexts_files"],
+    recovery_available: true,
+}
+
+property_contexts {
+    name: "product_property_contexts",
+    srcs: [":property_contexts_files"],
+    product_specific: true,
+    recovery_available: true,
+}
+
+property_contexts {
+    name: "vendor_property_contexts",
+    srcs: [":property_contexts_files"],
+    reqd_mask: true,
+    soc_specific: true,
+    recovery_available: true,
+}
+
+property_contexts {
+    name: "odm_property_contexts",
+    srcs: [":property_contexts_files"],
+    device_specific: true,
+    recovery_available: true,
+}
+
+service_contexts {
+    name: "plat_service_contexts",
+    srcs: [":service_contexts_files"],
+}
+
+service_contexts {
+    name: "product_service_contexts",
+    srcs: [":service_contexts_files"],
+    product_specific: true,
+}
+
+service_contexts {
+    name: "vendor_service_contexts",
+    srcs: [":service_contexts_files"],
+    reqd_mask: true,
+    soc_specific: true,
+}
diff --git a/Android.mk b/Android.mk
index c311213..4e4a641 100644
--- a/Android.mk
+++ b/Android.mk
@@ -123,13 +123,6 @@
 # Builds paths for all policy files found in BOARD_ODM_SEPOLICY_DIRS.
 build_odm_policy = $(call build_policy, $(1), $(BOARD_ODM_SEPOLICY_DIRS))
 
-# Add a file containing only a newline in-between each policy configuration
-# 'contexts' file. This will allow OEM policy configuration files without a
-# final newline (0x0A) to be built correctly by the m4(1) macro processor.
-# $(1): the set of contexts file names.
-# $(2): the file containing only 0x0A.
-add_nl = $(foreach entry, $(1), $(subst $(entry), $(entry) $(2), $(entry)))
-
 sepolicy_build_files := security_classes \
                         initial_sids \
                         access_vectors \
@@ -216,11 +209,15 @@
 LOCAL_REQUIRED_MODULES += \
     build_sepolicy \
     plat_file_contexts \
+    plat_file_contexts_test \
     plat_mac_permissions.xml \
     plat_property_contexts \
+    plat_property_contexts_test \
     plat_seapp_contexts \
     plat_service_contexts \
+    plat_service_contexts_test \
     plat_hwservice_contexts \
+    plat_hwservice_contexts_test \
     searchpolicy \
 
 # This conditional inclusion closely mimics the conditional logic
@@ -275,19 +272,25 @@
 
 LOCAL_REQUIRED_MODULES += \
     vendor_file_contexts \
+    vendor_file_contexts_test \
     vendor_mac_permissions.xml \
     vendor_property_contexts \
+    vendor_property_contexts_test \
     vendor_seapp_contexts \
     vendor_hwservice_contexts \
+    vendor_hwservice_contexts_test \
     vndservice_contexts \
 
 ifdef BOARD_ODM_SEPOLICY_DIRS
 LOCAL_REQUIRED_MODULES += \
     odm_sepolicy.cil \
     odm_file_contexts \
+    odm_file_contexts_test \
     odm_seapp_contexts \
     odm_property_contexts \
+    odm_property_contexts_test \
     odm_hwservice_contexts \
+    odm_hwservice_contexts_test \
     odm_mac_permissions.xml
 endif
 
@@ -295,10 +298,14 @@
 LOCAL_REQUIRED_MODULES += \
     product_sepolicy.cil \
     product_file_contexts \
+    product_file_contexts_test \
     product_hwservice_contexts \
+    product_hwservice_contexts_test \
     product_property_contexts \
+    product_property_contexts_test \
     product_seapp_contexts \
     product_service_contexts \
+    product_service_contexts_test \
     product_mac_permissions.xml \
     product_mapping_file \
 
@@ -468,21 +475,6 @@
 
 plat_pub_policy.conf :=
 
-##################################
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := sectxfile_nl
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-
-# Create a file containing newline only to add between context config files
-include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE):
-	@mkdir -p $(dir $@)
-	$(hide) echo > $@
-
-built_nl := $(LOCAL_BUILT_MODULE)
-
 #################################
 include $(CLEAR_VARS)
 
@@ -1099,10 +1091,9 @@
     $(eval $(call build_flattened_apex_file_contexts,$(_input),$(_apex_name),$(_output),local_fc_files))\
    )
 endif
-local_fcfiles_with_nl := $(call add_nl, $(local_fc_files), $(built_nl))
 
 file_contexts.local.tmp := $(intermediates)/file_contexts.local.tmp
-$(file_contexts.local.tmp): $(local_fcfiles_with_nl)
+$(file_contexts.local.tmp): $(local_fc_files)
 	@mkdir -p $(dir $@)
 	$(hide) m4 --fatal-warnings -s $^ > $@
 
@@ -1112,11 +1103,9 @@
 device_fc_files += $(call build_odm_policy, file_contexts)
 endif
 
-device_fcfiles_with_nl := $(call add_nl, $(device_fc_files), $(built_nl))
-
 file_contexts.device.tmp := $(intermediates)/file_contexts.device.tmp
 $(file_contexts.device.tmp): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
-$(file_contexts.device.tmp): $(device_fcfiles_with_nl)
+$(file_contexts.device.tmp): $(device_fc_files)
 	@mkdir -p $(dir $@)
 	$(hide) m4 --fatal-warnings -s $(PRIVATE_ADDITIONAL_M4DEFS) $^ > $@
 
@@ -1169,19 +1158,10 @@
 endif
 
 ##################################
-include $(LOCAL_PATH)/file_contexts.mk
-
-##################################
 include $(LOCAL_PATH)/seapp_contexts.mk
 
 ##################################
-include $(LOCAL_PATH)/property_contexts.mk
-
-##################################
-include $(LOCAL_PATH)/service_contexts.mk
-
-##################################
-include $(LOCAL_PATH)/hwservice_contexts.mk
+include $(LOCAL_PATH)/contexts_tests.mk
 
 ##################################
 include $(CLEAR_VARS)
@@ -1222,12 +1202,13 @@
 
 include $(BUILD_SYSTEM)/base_rules.mk
 
-all_fc_files := $(built_plat_fc) $(built_vendor_fc)
+all_fc_files := $(TARGET_OUT)/etc/selinux/plat_file_contexts
+all_fc_files += $(TARGET_OUT_VENDOR)/etc/selinux/vendor_file_contexts
 ifdef HAS_PRODUCT_SEPOLICY
-all_fc_args += $(built_product_fc)
+all_fc_files += $(TARGET_OUT_PRODUCT)/etc/selinux/product_file_contexts
 endif
 ifdef BOARD_ODM_SEPOLICY_DIRS
-all_fc_files += $(built_odm_fc)
+all_fc_files += $(TARGET_OUT_ODM)/etc/selinux/odm_file_contexts
 endif
 all_fc_args := $(foreach file, $(all_fc_files), -f $(file))
 
@@ -1299,15 +1280,6 @@
 	$(hide) $(HOST_OUT_EXECUTABLES)/build_sepolicy -a $(HOST_OUT_EXECUTABLES) filter_out \
 		-f $(PRIVATE_REQD_MASK) -t $@
 
-all_fc_files := $(built_plat_fc) $(built_vendor_fc)
-ifdef HAS_PRODUCT_SEPOLICY
-all_fc_files += $(built_product_fc)
-endif
-ifdef BOARD_ODM_SEPOLICY_DIRS
-all_fc_files += $(built_odm_fc)
-endif
-all_fc_args := $(foreach file, $(all_fc_files), -f $(file))
-
 # Tests for Treble compatibility of current platform policy and vendor policy of
 # given release version.
 version_under_treble_tests := 26.0
@@ -1324,6 +1296,8 @@
 base_plat_policy.conf :=
 base_plat_pub_policy.conf :=
 plat_sepolicy :=
+all_fc_files :=
+all_fc_args :=
 
 #################################
 include $(CLEAR_VARS)
@@ -1363,28 +1337,15 @@
 #################################
 
 
-add_nl :=
 build_vendor_policy :=
 build_odm_policy :=
 build_policy :=
-built_plat_fc :=
-built_product_fc :=
-built_vendor_fc :=
-built_odm_fc :=
-built_nl :=
 built_plat_cil :=
 built_pub_vers_cil :=
 built_plat_mapping_cil :=
 built_product_mapping_cil :=
-built_plat_pc :=
-built_product_pc :=
 built_vendor_cil :=
-built_vendor_pc :=
-built_vendor_sc :=
 built_odm_cil :=
-built_odm_pc :=
-built_odm_sc :=
-built_plat_sc :=
 built_precompiled_sepolicy :=
 built_sepolicy :=
 built_sepolicy_neverallows :=
diff --git a/build/soong/Android.bp b/build/soong/Android.bp
index bcd33b3..ae2bdd6 100644
--- a/build/soong/Android.bp
+++ b/build/soong/Android.bp
@@ -23,7 +23,9 @@
     ],
     srcs: [
         "cil_compat_map.go",
-        "filegroup.go"
+        "filegroup.go",
+        "selinux.go",
+        "selinux_contexts.go",
     ],
     pluginFor: ["soong_build"],
 }
diff --git a/build/soong/cil_compat_map.go b/build/soong/cil_compat_map.go
index 9d01d93..6eef2f2 100644
--- a/build/soong/cil_compat_map.go
+++ b/build/soong/cil_compat_map.go
@@ -27,8 +27,6 @@
 )
 
 var (
-	pctx = android.NewPackageContext("android/soong/selinux")
-
 	combine_maps    = pctx.HostBinToolVariable("combine_maps", "combine_maps")
 	combineMapsCmd  = "${combine_maps} -t ${topHalf} -b ${bottomHalf} -o $out"
 	combineMapsRule = pctx.StaticRule(
@@ -80,11 +78,6 @@
 	GeneratedMapFile() android.Path
 }
 
-type dependencyTag struct {
-	blueprint.BaseDependencyTag
-	name string
-}
-
 func expandTopHalf(ctx android.ModuleContext) android.OptionalPath {
 	var topHalf android.OptionalPath
 	ctx.VisitDirectDeps(func(dep android.Module) {
diff --git a/build/soong/filegroup.go b/build/soong/filegroup.go
index 7f75e48..a45b427 100644
--- a/build/soong/filegroup.go
+++ b/build/soong/filegroup.go
@@ -52,6 +52,9 @@
 	systemExtPublicSrcs  android.Paths
 	systemExtPrivateSrcs android.Paths
 
+	productPublicSrcs  android.Paths
+	productPrivateSrcs android.Paths
+
 	vendorSrcs android.Paths
 	odmSrcs    android.Paths
 }
@@ -86,7 +89,17 @@
 	return fg.systemExtPrivateSrcs
 }
 
-// Source files from BOARD_SEPOLICY_DIRS
+// Source files from PRODUCT_PUBLIC_SEPOLICY_DIRS
+func (fg *fileGroup) ProductPublicSrcs() android.Paths {
+	return fg.productPublicSrcs
+}
+
+// Source files from PRODUCT_PRIVATE_SEPOLICY_DIRS
+func (fg *fileGroup) ProductPrivateSrcs() android.Paths {
+	return fg.productPrivateSrcs
+}
+
+// Source files from BOARD_VENDOR_SEPOLICY_DIRS
 func (fg *fileGroup) VendorSrcs() android.Paths {
 	return fg.vendorSrcs
 }
@@ -125,6 +138,9 @@
 	fg.systemExtPublicSrcs = fg.findSrcsInDirs(ctx, ctx.DeviceConfig().PlatPublicSepolicyDirs())
 	fg.systemExtPrivateSrcs = fg.findSrcsInDirs(ctx, ctx.DeviceConfig().PlatPrivateSepolicyDirs())
 
+	fg.productPublicSrcs = fg.findSrcsInDirs(ctx, ctx.Config().ProductPublicSepolicyDirs())
+	fg.productPrivateSrcs = fg.findSrcsInDirs(ctx, ctx.Config().ProductPrivateSepolicyDirs())
+
 	fg.vendorSrcs = fg.findSrcsInDirs(ctx, ctx.DeviceConfig().VendorSepolicyDirs())
 	fg.odmSrcs = fg.findSrcsInDirs(ctx, ctx.DeviceConfig().OdmSepolicyDirs())
 }
diff --git a/build/soong/selinux.go b/build/soong/selinux.go
new file mode 100644
index 0000000..7ad4776
--- /dev/null
+++ b/build/soong/selinux.go
@@ -0,0 +1,30 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package selinux
+
+import (
+	"github.com/google/blueprint"
+
+	"android/soong/android"
+)
+
+type dependencyTag struct {
+	blueprint.BaseDependencyTag
+	name string
+}
+
+var (
+	pctx = android.NewPackageContext("android/soong/selinux")
+)
diff --git a/build/soong/selinux_contexts.go b/build/soong/selinux_contexts.go
new file mode 100644
index 0000000..632237c
--- /dev/null
+++ b/build/soong/selinux_contexts.go
@@ -0,0 +1,369 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package selinux
+
+import (
+	"fmt"
+	"io"
+	"strings"
+
+	"github.com/google/blueprint/proptools"
+
+	"android/soong/android"
+)
+
+const (
+	coreMode     = "core"
+	recoveryMode = "recovery"
+)
+
+type selinuxContextsProperties struct {
+	// Filenames under sepolicy directories, which will be used to generate contexts file.
+	Srcs []string `android:"path"`
+
+	Product_variables struct {
+		Debuggable struct {
+			Srcs []string
+		}
+
+		Address_sanitize struct {
+			Srcs []string
+		}
+	}
+
+	// Whether reqd_mask directory is included to sepolicy directories or not.
+	Reqd_mask *bool
+
+	// Whether the comments in generated contexts file will be removed or not.
+	Remove_comment *bool
+
+	// Whether the result context file is sorted with fc_sort or not.
+	Fc_sort *bool
+
+	// Make this module available when building for recovery
+	Recovery_available *bool
+
+	InRecovery bool `blueprint:"mutated"`
+}
+
+type fileContextsProperties struct {
+	// flatten_apex can be used to specify additional sources of file_contexts.
+	// Apex paths, /system/apex/{apex_name}, will be amended to the paths of file_contexts
+	// entries.
+	Flatten_apex struct {
+		Srcs []string
+	}
+}
+
+type selinuxContextsModule struct {
+	android.ModuleBase
+
+	properties             selinuxContextsProperties
+	fileContextsProperties fileContextsProperties
+	build                  func(ctx android.ModuleContext, inputs android.Paths)
+	outputPath             android.ModuleGenPath
+	installPath            android.OutputPath
+}
+
+var (
+	reuseContextsDepTag = dependencyTag{name: "reuseContexts"}
+)
+
+func init() {
+	pctx.HostBinToolVariable("fc_sort", "fc_sort")
+
+	android.RegisterModuleType("file_contexts", fileFactory)
+	android.RegisterModuleType("hwservice_contexts", hwServiceFactory)
+	android.RegisterModuleType("property_contexts", propertyFactory)
+	android.RegisterModuleType("service_contexts", serviceFactory)
+
+	android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
+		ctx.BottomUp("selinux_contexts", selinuxContextsMutator).Parallel()
+	})
+}
+
+func (m *selinuxContextsModule) inRecovery() bool {
+	return m.properties.InRecovery || m.ModuleBase.InstallInRecovery()
+}
+
+func (m *selinuxContextsModule) onlyInRecovery() bool {
+	return m.ModuleBase.InstallInRecovery()
+}
+
+func (m *selinuxContextsModule) InstallInRecovery() bool {
+	return m.inRecovery()
+}
+
+func (m *selinuxContextsModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	if m.InstallInRecovery() {
+		// Workaround for installing context files at the root of the recovery partition
+		m.installPath = android.PathForOutput(ctx,
+			"target", "product", ctx.Config().DeviceName(), "recovery", "root")
+	} else {
+		m.installPath = android.PathForModuleInstall(ctx, "etc", "selinux")
+	}
+
+	if m.inRecovery() && !m.onlyInRecovery() {
+		dep := ctx.GetDirectDepWithTag(m.Name(), reuseContextsDepTag)
+
+		if reuseDeps, ok := dep.(*selinuxContextsModule); ok {
+			m.outputPath = reuseDeps.outputPath
+			ctx.InstallFile(m.installPath, m.Name(), m.outputPath)
+			return
+		}
+	}
+
+	var inputs android.Paths
+
+	ctx.VisitDirectDepsWithTag(android.SourceDepTag, func(dep android.Module) {
+		segroup, ok := dep.(*fileGroup)
+		if !ok {
+			ctx.ModuleErrorf("srcs dependency %q is not an selinux filegroup",
+				ctx.OtherModuleName(dep))
+			return
+		}
+
+		if ctx.ProductSpecific() {
+			inputs = append(inputs, segroup.ProductPrivateSrcs()...)
+		} else if ctx.SocSpecific() {
+			inputs = append(inputs, segroup.SystemVendorSrcs()...)
+			inputs = append(inputs, segroup.VendorSrcs()...)
+		} else if ctx.DeviceSpecific() {
+			inputs = append(inputs, segroup.OdmSrcs()...)
+		} else {
+			inputs = append(inputs, segroup.SystemPrivateSrcs()...)
+			inputs = append(inputs, segroup.SystemExtPrivateSrcs()...)
+
+			if ctx.Config().ProductCompatibleProperty() {
+				inputs = append(inputs, segroup.SystemPublicSrcs()...)
+			}
+		}
+
+		if proptools.Bool(m.properties.Reqd_mask) {
+			inputs = append(inputs, segroup.SystemReqdMaskSrcs()...)
+		}
+	})
+
+	for _, src := range m.properties.Srcs {
+		// Module sources are handled above with VisitDirectDepsWithTag
+		if android.SrcIsModule(src) == "" {
+			inputs = append(inputs, android.PathForModuleSrc(ctx, src))
+		}
+	}
+
+	m.build(ctx, inputs)
+}
+
+func newModule() *selinuxContextsModule {
+	m := &selinuxContextsModule{}
+	m.AddProperties(
+		&m.properties,
+	)
+	android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
+	android.AddLoadHook(m, func(ctx android.LoadHookContext) {
+		m.selinuxContextsHook(ctx)
+	})
+	return m
+}
+
+func (m *selinuxContextsModule) selinuxContextsHook(ctx android.LoadHookContext) {
+	// TODO: clean this up to use build/soong/android/variable.go after b/79249983
+	var srcs []string
+
+	if ctx.Config().Debuggable() {
+		srcs = append(srcs, m.properties.Product_variables.Debuggable.Srcs...)
+	}
+
+	for _, sanitize := range ctx.Config().SanitizeDevice() {
+		if sanitize == "address" {
+			srcs = append(srcs, m.properties.Product_variables.Address_sanitize.Srcs...)
+			break
+		}
+	}
+
+	m.properties.Srcs = append(m.properties.Srcs, srcs...)
+}
+
+func (m *selinuxContextsModule) AndroidMk() android.AndroidMkData {
+	return android.AndroidMkData{
+		Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
+			nameSuffix := ""
+			if m.inRecovery() && !m.onlyInRecovery() {
+				nameSuffix = ".recovery"
+			}
+			fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
+			fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
+			fmt.Fprintln(w, "LOCAL_MODULE :=", name+nameSuffix)
+			fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC")
+			if m.Owner() != "" {
+				fmt.Fprintln(w, "LOCAL_MODULE_OWNER :=", m.Owner())
+			}
+			fmt.Fprintln(w, "LOCAL_MODULE_TAGS := optional")
+			fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", m.outputPath.String())
+			fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", "$(OUT_DIR)/"+m.installPath.RelPathString())
+			fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", name)
+			fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
+		},
+	}
+}
+
+func selinuxContextsMutator(ctx android.BottomUpMutatorContext) {
+	m, ok := ctx.Module().(*selinuxContextsModule)
+	if !ok {
+		return
+	}
+
+	var coreVariantNeeded bool = true
+	var recoveryVariantNeeded bool = false
+	if proptools.Bool(m.properties.Recovery_available) {
+		recoveryVariantNeeded = true
+	}
+
+	if m.ModuleBase.InstallInRecovery() {
+		recoveryVariantNeeded = true
+		coreVariantNeeded = false
+	}
+
+	var variants []string
+	if coreVariantNeeded {
+		variants = append(variants, coreMode)
+	}
+	if recoveryVariantNeeded {
+		variants = append(variants, recoveryMode)
+	}
+	mod := ctx.CreateVariations(variants...)
+
+	for i, v := range variants {
+		if v == recoveryMode {
+			m := mod[i].(*selinuxContextsModule)
+			m.properties.InRecovery = true
+
+			if coreVariantNeeded {
+				ctx.AddInterVariantDependency(reuseContextsDepTag, m, mod[i-1])
+			}
+		}
+	}
+}
+
+func (m *selinuxContextsModule) buildGeneralContexts(ctx android.ModuleContext, inputs android.Paths) {
+	m.outputPath = android.PathForModuleGen(ctx, ctx.ModuleName()+"_m4out")
+
+	rule := android.NewRuleBuilder()
+
+	rule.Command().
+		Text("m4 --fatal-warnings -s").
+		FlagForEachArg("-D", ctx.DeviceConfig().SepolicyM4Defs()).
+		Inputs(inputs).
+		FlagWithOutput("> ", m.outputPath)
+
+	if proptools.Bool(m.properties.Remove_comment) {
+		rule.Temporary(m.outputPath)
+
+		remove_comment_output := android.PathForModuleGen(ctx, ctx.ModuleName()+"_remove_comment")
+
+		rule.Command().
+			Text("sed -e 's/#.*$//' -e '/^$/d'").
+			Input(m.outputPath).
+			FlagWithOutput("> ", remove_comment_output)
+
+		m.outputPath = remove_comment_output
+	}
+
+	if proptools.Bool(m.properties.Fc_sort) {
+		rule.Temporary(m.outputPath)
+
+		sorted_output := android.PathForModuleGen(ctx, ctx.ModuleName()+"_sorted")
+
+		rule.Command().
+			Tool(ctx.Config().HostToolPath(ctx, "fc_sort")).
+			FlagWithInput("-i ", m.outputPath).
+			FlagWithOutput("-o ", sorted_output)
+
+		m.outputPath = sorted_output
+	}
+
+	rule.Build(pctx, ctx, "selinux_contexts", m.Name())
+
+	rule.DeleteTemporaryFiles()
+
+	ctx.InstallFile(m.installPath, ctx.ModuleName(), m.outputPath)
+}
+
+func (m *selinuxContextsModule) buildFileContexts(ctx android.ModuleContext, inputs android.Paths) {
+	if m.properties.Fc_sort == nil {
+		m.properties.Fc_sort = proptools.BoolPtr(true)
+	}
+
+	rule := android.NewRuleBuilder()
+
+	if ctx.Config().FlattenApex() {
+		for _, src := range m.fileContextsProperties.Flatten_apex.Srcs {
+			if m := android.SrcIsModule(src); m != "" {
+				ctx.ModuleErrorf(
+					"Module srcs dependency %q is not supported for flatten_apex.srcs", m)
+				return
+			}
+			for _, path := range android.PathsForModuleSrcExcludes(ctx, []string{src}, nil) {
+				out := android.PathForModuleGen(ctx, "flattened_apex", path.Rel())
+				apex_path := "/system/apex/" + strings.Replace(
+					strings.TrimSuffix(path.Base(), "-file_contexts"),
+					".", "\\\\.", -1)
+
+				rule.Command().
+					Text("awk '/object_r/{printf(\""+apex_path+"%s\\n\",$0)}'").
+					Input(path).
+					FlagWithOutput("> ", out)
+
+				inputs = append(inputs, out)
+			}
+		}
+	}
+
+	rule.Build(pctx, ctx, m.Name(), "flattened_apex_file_contexts")
+	m.buildGeneralContexts(ctx, inputs)
+}
+
+func fileFactory() android.Module {
+	m := newModule()
+	m.AddProperties(&m.fileContextsProperties)
+	m.build = m.buildFileContexts
+	return m
+}
+
+func (m *selinuxContextsModule) buildHwServiceContexts(ctx android.ModuleContext, inputs android.Paths) {
+	if m.properties.Remove_comment == nil {
+		m.properties.Remove_comment = proptools.BoolPtr(true)
+	}
+
+	m.buildGeneralContexts(ctx, inputs)
+}
+
+func hwServiceFactory() android.Module {
+	m := newModule()
+	m.build = m.buildHwServiceContexts
+	return m
+}
+
+func propertyFactory() android.Module {
+	m := newModule()
+	m.build = m.buildGeneralContexts
+	return m
+}
+
+func serviceFactory() android.Module {
+	m := newModule()
+	m.build = m.buildGeneralContexts
+	return m
+}
diff --git a/contexts_tests.mk b/contexts_tests.mk
new file mode 100644
index 0000000..b229c50
--- /dev/null
+++ b/contexts_tests.mk
@@ -0,0 +1,250 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+include $(CLEAR_VARS)
+
+# TODO: move tests into Soong after refactoring sepolicy module (b/130693869)
+
+# Run host-side test with contexts files and the sepolicy file.
+# $(1): paths to contexts files
+# $(2): path to the host tool
+# $(3): additional argument to be passed to the tool
+define run_contexts_test
+test_out := $$(intermediates)/$$(LOCAL_MODULE)
+$$(test_out): PRIVATE_CONTEXTS := $(1)
+$$(test_out): PRIVATE_SEPOLICY := $$(built_sepolicy)
+$$(test_out): $(2) $(1) $$(built_sepolicy)
+	$$(hide) $$< $(3) $$(PRIVATE_SEPOLICY) $$(PRIVATE_CONTEXTS)
+	$$(hide) mkdir -p $$(dir $$@)
+	$$(hide) touch $$@
+test_out :=
+endef
+
+system_out := $(TARGET_OUT)/etc/selinux
+product_out := $(TARGET_OUT_PRODUCT)/etc/selinux
+vendor_out := $(TARGET_OUT_VENDOR)/etc/selinux
+odm_out := $(TARGET_OUT_ODM)/etc/selinux
+
+checkfc := $(HOST_OUT_EXECUTABLES)/checkfc
+property_info_checker := $(HOST_OUT_EXECUTABLES)/property_info_checker
+
+##################################
+LOCAL_MODULE := plat_file_contexts_test
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(eval $(call run_contexts_test, $(system_out)/plat_file_contexts, $(checkfc),))
+
+##################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := product_file_contexts_test
+LOCAL_MODULE_CLASS := ETC
+LOCAL_PRODUCT_MODULE := true
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(eval $(call run_contexts_test, $(product_out)/product_file_contexts, $(checkfc),))
+
+##################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := vendor_file_contexts_test
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(eval $(call run_contexts_test, $(vendor_out)/vendor_file_contexts, $(checkfc),))
+
+##################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := odm_file_contexts_test
+LOCAL_MODULE_CLASS := ETC
+LOCAL_ODM_MODULE := true
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(eval $(call run_contexts_test, $(odm_out)/odm_file_contexts, $(checkfc),))
+
+##################################
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := plat_hwservice_contexts_test
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(eval $(call run_contexts_test, $(system_out)/plat_hwservice_contexts, $(checkfc), -e -l))
+
+##################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := product_hwservice_contexts_test
+LOCAL_MODULE_CLASS := ETC
+LOCAL_PRODUCT_MODULE := true
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(eval $(call run_contexts_test, $(product_out)/product_hwservice_contexts, $(checkfc), -e -l))
+
+##################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := vendor_hwservice_contexts_test
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(eval $(call run_contexts_test, $(vendor_out)/vendor_hwservice_contexts, $(checkfc), -e -l))
+
+##################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := odm_hwservice_contexts_test
+LOCAL_MODULE_CLASS := ETC
+LOCAL_ODM_MODULE := true
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(eval $(call run_contexts_test, $(odm_out)/odm_hwservice_contexts, $(checkfc), -e -l))
+
+##################################
+
+pc_files := $(system_out)/plat_property_contexts
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := plat_property_contexts_test
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(eval $(call run_contexts_test, $(pc_files), $(property_info_checker),))
+
+##################################
+
+pc_files += $(vendor_out)/vendor_property_contexts
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := vendor_property_contexts_test
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(eval $(call run_contexts_test, $(pc_files), $(property_info_checker),))
+
+##################################
+
+ifdef BOARD_ODM_SEPOLICY_DIRS
+
+pc_files += $(odm_out)/odm_property_contexts
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := odm_property_contexts_test
+LOCAL_MODULE_CLASS := ETC
+LOCAL_ODM_MODULE := true
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(eval $(call run_contexts_test, $(pc_files), $(property_info_checker),))
+
+endif
+
+##################################
+
+ifdef HAS_PRODUCT_SEPOLICY
+
+pc_files += $(product_out)/product_property_contexts
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := product_property_contexts_test
+LOCAL_MODULE_CLASS := ETC
+LOCAL_PRODUCT_MODULE := true
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(eval $(call run_contexts_test, $(pc_files), $(property_info_checker),))
+
+endif
+
+pc_files :=
+
+##################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := plat_service_contexts_test
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(eval $(call run_contexts_test, $(system_out)/plat_service_contexts, $(checkfc), -s))
+
+##################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := product_service_contexts_test
+LOCAL_MODULE_CLASS := ETC
+LOCAL_PRODUCT_MODULE := true
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(eval $(call run_contexts_test, $(product_out)/product_service_contexts, $(checkfc), -s))
+
+##################################
+# nonplat_service_contexts is only allowed on non-full-treble devices
+ifneq ($(PRODUCT_SEPOLICY_SPLIT),true)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := vendor_service_contexts_test
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(eval $(call run_contexts_test, $(vendor_out)/vendor_service_contexts, $(checkfc), -s))
+
+endif
+
+system_out :=
+product_out :=
+vendor_out :=
+odm_out :=
+checkfc :=
+property_info_checker :=
+run_contexts_test :=
diff --git a/file_contexts.mk b/file_contexts.mk
deleted file mode 100644
index ec8d4ea..0000000
--- a/file_contexts.mk
+++ /dev/null
@@ -1,177 +0,0 @@
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := plat_file_contexts
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/selinux
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-local_fc_files := $(call build_policy, file_contexts, $(PLAT_PRIVATE_POLICY))
-ifneq ($(filter address,$(SANITIZE_TARGET)),)
-  local_fc_files += $(wildcard $(addsuffix /file_contexts_asan, $(PLAT_PRIVATE_POLICY)))
-endif
-ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
-  local_fc_files += $(wildcard $(addsuffix /file_contexts_overlayfs, $(PLAT_PRIVATE_POLICY)))
-endif
-ifeq ($(TARGET_FLATTEN_APEX),true)
-  apex_fc_files := $(wildcard $(LOCAL_PATH)/apex/*-file_contexts)
-  $(foreach _input,$(apex_fc_files),\
-    $(eval _output := $(intermediates)/$(notdir $(_input))-flattened)\
-    $(eval _apex_name := $(patsubst %-file_contexts,%,$(notdir $(_input))))\
-    $(eval $(call build_flattened_apex_file_contexts,$(_input),$(_apex_name),$(_output),local_fc_files))\
-   )
-endif
-local_fcfiles_with_nl := $(call add_nl, $(local_fc_files), $(built_nl))
-
-$(LOCAL_BUILT_MODULE): PRIVATE_FC_FILES := $(local_fcfiles_with_nl)
-$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
-$(LOCAL_BUILT_MODULE): PRIVATE_FC_SORT := $(HOST_OUT_EXECUTABLES)/fc_sort
-$(LOCAL_BUILT_MODULE): $(HOST_OUT_EXECUTABLES)/checkfc $(HOST_OUT_EXECUTABLES)/fc_sort \
-$(local_fcfiles_with_nl) $(built_sepolicy)
-	@mkdir -p $(dir $@)
-	$(hide) m4 --fatal-warnings -s $(PRIVATE_FC_FILES) > $@.tmp
-	$(hide) $< $(PRIVATE_SEPOLICY) $@.tmp
-	$(hide) $(PRIVATE_FC_SORT) -i $@.tmp -o $@
-
-built_plat_fc := $(LOCAL_BUILT_MODULE)
-local_fc_files :=
-local_fcfiles_with_nl :=
-
-##################################
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := product_file_contexts
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_PRODUCT)/etc/selinux
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-product_fc_files := $(call build_policy, file_contexts, $(PRODUCT_PRIVATE_POLICY))
-product_fcfiles_with_nl := $(call add_nl, $(product_fc_files), $(built_nl))
-
-$(LOCAL_BUILT_MODULE): PRIVATE_FC_FILES := $(product_fcfiles_with_nl)
-$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
-$(LOCAL_BUILT_MODULE): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
-$(LOCAL_BUILT_MODULE): PRIVATE_FC_SORT := $(HOST_OUT_EXECUTABLES)/fc_sort
-$(LOCAL_BUILT_MODULE): $(HOST_OUT_EXECUTABLES)/checkfc $(HOST_OUT_EXECUTABLES)/fc_sort \
-$(product_fcfiles_with_nl) $(built_sepolicy)
-	@mkdir -p $(dir $@)
-	$(hide) m4 --fatal-warnings -s $(PRIVATE_ADDITIONAL_M4DEFS) $(PRIVATE_FC_FILES) > $@.tmp
-	$(hide) $< $(PRIVATE_SEPOLICY) $@.tmp
-	$(hide) $(PRIVATE_FC_SORT) -i $@.tmp -o $@
-
-built_product_fc := $(LOCAL_BUILT_MODULE)
-product_fc_files :=
-product_fcfiles_with_nl :=
-
-##################################
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := vendor_file_contexts
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/selinux
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-vendor_fc_files := $(call build_vendor_policy, file_contexts)
-vendor_fcfiles_with_nl := $(call add_nl, $(vendor_fc_files), $(built_nl))
-
-$(LOCAL_BUILT_MODULE): PRIVATE_FC_FILES := $(vendor_fcfiles_with_nl)
-$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
-$(LOCAL_BUILT_MODULE): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
-$(LOCAL_BUILT_MODULE): PRIVATE_FC_SORT := $(HOST_OUT_EXECUTABLES)/fc_sort
-$(LOCAL_BUILT_MODULE): $(HOST_OUT_EXECUTABLES)/checkfc $(HOST_OUT_EXECUTABLES)/fc_sort \
-$(vendor_fcfiles_with_nl) $(built_sepolicy)
-	@mkdir -p $(dir $@)
-	$(hide) m4 --fatal-warnings -s $(PRIVATE_ADDITIONAL_M4DEFS) $(PRIVATE_FC_FILES) > $@.tmp
-	$(hide) $< $(PRIVATE_SEPOLICY) $@.tmp
-	$(hide) $(PRIVATE_FC_SORT) -i $@.tmp -o $@
-
-built_vendor_fc := $(LOCAL_BUILT_MODULE)
-vendor_fc_files :=
-vendor_fcfiles_with_nl :=
-
-##################################
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := odm_file_contexts
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_ODM)/etc/selinux
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-odm_fc_files := $(call build_odm_policy, file_contexts)
-odm_fcfiles_with_nl := $(call add_nl, $(odm_fc_files), $(built_nl))
-
-$(LOCAL_BUILT_MODULE): PRIVATE_FC_FILES := $(odm_fcfiles_with_nl)
-$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
-$(LOCAL_BUILT_MODULE): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
-$(LOCAL_BUILT_MODULE): PRIVATE_FC_SORT := $(HOST_OUT_EXECUTABLES)/fc_sort
-$(LOCAL_BUILT_MODULE): $(HOST_OUT_EXECUTABLES)/checkfc $(HOST_OUT_EXECUTABLES)/fc_sort \
-$(odm_fcfiles_with_nl) $(built_sepolicy)
-	@mkdir -p $(dir $@)
-	$(hide) m4 --fatal-warnings -s $(PRIVATE_ADDITIONAL_M4DEFS) $(PRIVATE_FC_FILES) > $@.tmp
-	$(hide) $< $(PRIVATE_SEPOLICY) $@.tmp
-	$(hide) $(PRIVATE_FC_SORT) -i $@.tmp -o $@
-
-built_odm_fc := $(LOCAL_BUILT_MODULE)
-odm_fc_files :=
-odm_fcfiles_with_nl :=
-
-##################################
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := plat_file_contexts.recovery
-LOCAL_MODULE_STEM := plat_file_contexts
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-$(LOCAL_BUILT_MODULE): $(built_plat_fc)
-	$(hide) cp -f $< $@
-
-##################################
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := product_file_contexts.recovery
-LOCAL_MODULE_STEM := product_file_contexts
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-$(LOCAL_BUILT_MODULE): $(built_product_fc)
-	$(hide) cp -f $< $@
-
-##################################
-include $(CLEAR_VARS)
-LOCAL_MODULE := vendor_file_contexts.recovery
-LOCAL_MODULE_STEM := vendor_file_contexts
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-$(LOCAL_BUILT_MODULE): $(built_vendor_fc)
-	$(hide) cp -f $< $@
-
-##################################
-include $(CLEAR_VARS)
-LOCAL_MODULE := odm_file_contexts.recovery
-LOCAL_MODULE_STEM := odm_file_contexts
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-$(LOCAL_BUILT_MODULE): $(built_odm_fc)
-	$(hide) cp -f $< $@
diff --git a/hwservice_contexts.mk b/hwservice_contexts.mk
deleted file mode 100644
index 15f404d..0000000
--- a/hwservice_contexts.mk
+++ /dev/null
@@ -1,110 +0,0 @@
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := plat_hwservice_contexts
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/selinux
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-plat_hwsvcfiles := $(call build_policy, hwservice_contexts, $(PLAT_PRIVATE_POLICY))
-
-plat_hwservice_contexts.tmp := $(intermediates)/plat_hwservice_contexts.tmp
-$(plat_hwservice_contexts.tmp): PRIVATE_SVC_FILES := $(plat_hwsvcfiles)
-$(plat_hwservice_contexts.tmp): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
-$(plat_hwservice_contexts.tmp): $(plat_hwsvcfiles)
-	@mkdir -p $(dir $@)
-	$(hide) m4 --fatal-warnings -s $(PRIVATE_ADDITIONAL_M4DEFS) $(PRIVATE_SVC_FILES) > $@
-
-$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
-$(LOCAL_BUILT_MODULE): $(plat_hwservice_contexts.tmp) $(built_sepolicy) $(HOST_OUT_EXECUTABLES)/checkfc $(ACP)
-	@mkdir -p $(dir $@)
-	sed -e 's/#.*$$//' -e '/^$$/d' $< > $@
-	$(HOST_OUT_EXECUTABLES)/checkfc -e -l $(PRIVATE_SEPOLICY) $@
-
-plat_hwsvcfiles :=
-plat_hwservice_contexts.tmp :=
-
-##################################
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := product_hwservice_contexts
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_PRODUCT)/etc/selinux
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-product_hwsvcfiles := $(call build_policy, hwservice_contexts, $(PRODUCT_PRIVATE_POLICY))
-
-product_hwservice_contexts.tmp := $(intermediates)/product_hwservice_contexts.tmp
-$(product_hwservice_contexts.tmp): PRIVATE_SVC_FILES := $(product_hwsvcfiles)
-$(product_hwservice_contexts.tmp): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
-$(product_hwservice_contexts.tmp): $(product_hwsvcfiles)
-	@mkdir -p $(dir $@)
-	$(hide) m4 --fatal-warnings -s $(PRIVATE_ADDITIONAL_M4DEFS) $(PRIVATE_SVC_FILES) > $@
-
-$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
-$(LOCAL_BUILT_MODULE): $(product_hwservice_contexts.tmp) $(built_sepolicy) $(HOST_OUT_EXECUTABLES)/checkfc
-	@mkdir -p $(dir $@)
-	sed -e 's/#.*$$//' -e '/^$$/d' $< > $@
-	$(hide) $(HOST_OUT_EXECUTABLES)/checkfc -e -l $(PRIVATE_SEPOLICY) $@
-
-product_hwsvcfiles :=
-product_hwservice_contexts.tmp :=
-
-##################################
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := vendor_hwservice_contexts
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/selinux
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-vendor_hwsvcfiles := $(call build_policy, hwservice_contexts, $(PLAT_VENDOR_POLICY) $(BOARD_VENDOR_SEPOLICY_DIRS) $(REQD_MASK_POLICY))
-
-vendor_hwservice_contexts.tmp := $(intermediates)/vendor_hwservice_contexts.tmp
-$(vendor_hwservice_contexts.tmp): PRIVATE_SVC_FILES := $(vendor_hwsvcfiles)
-$(vendor_hwservice_contexts.tmp): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
-$(vendor_hwservice_contexts.tmp): $(vendor_hwsvcfiles)
-	@mkdir -p $(dir $@)
-	$(hide) m4 --fatal-warnings -s $(PRIVATE_ADDITIONAL_M4DEFS) $(PRIVATE_SVC_FILES) > $@
-
-$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
-$(LOCAL_BUILT_MODULE): $(vendor_hwservice_contexts.tmp) $(built_sepolicy) $(HOST_OUT_EXECUTABLES)/checkfc $(ACP)
-	@mkdir -p $(dir $@)
-	sed -e 's/#.*$$//' -e '/^$$/d' $< > $@
-	$(hide) $(HOST_OUT_EXECUTABLES)/checkfc -e -l $(PRIVATE_SEPOLICY) $@
-
-vendor_hwsvcfiles :=
-vendor_hwservice_contexts.tmp :=
-
-##################################
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := odm_hwservice_contexts
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_ODM)/etc/selinux
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-odm_hwsvcfiles := $(call build_policy, hwservice_contexts, $(BOARD_ODM_SEPOLICY_DIRS))
-
-odm_hwservice_contexts.tmp := $(intermediates)/odm_hwservice_contexts.tmp
-$(odm_hwservice_contexts.tmp): PRIVATE_SVC_FILES := $(odm_hwsvcfiles)
-$(odm_hwservice_contexts.tmp): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
-$(odm_hwservice_contexts.tmp): $(odm_hwsvcfiles)
-	@mkdir -p $(dir $@)
-	$(hide) m4 --fatal-warnings -s $(PRIVATE_ADDITIONAL_M4DEFS) $(PRIVATE_SVC_FILES) > $@
-
-$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
-$(LOCAL_BUILT_MODULE): $(odm_hwservice_contexts.tmp) $(built_sepolicy) $(HOST_OUT_EXECUTABLES)/checkfc $(ACP)
-	@mkdir -p $(dir $@)
-	sed -e 's/#.*$$//' -e '/^$$/d' $< > $@
-	$(hide) $(HOST_OUT_EXECUTABLES)/checkfc -e -l $(PRIVATE_SEPOLICY) $@
-
-odm_hwsvcfiles :=
-odm_hwservice_contexts.tmp :=
diff --git a/property_contexts.mk b/property_contexts.mk
deleted file mode 100644
index eb19d20..0000000
--- a/property_contexts.mk
+++ /dev/null
@@ -1,170 +0,0 @@
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := plat_property_contexts
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/selinux
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-plat_pcfiles := $(call build_policy, property_contexts, $(PLAT_PRIVATE_POLICY))
-ifeq ($(PRODUCT_COMPATIBLE_PROPERTY),true)
-plat_pcfiles += $(LOCAL_PATH)/public/property_contexts
-endif
-
-plat_property_contexts.tmp := $(intermediates)/plat_property_contexts.tmp
-$(plat_property_contexts.tmp): PRIVATE_PC_FILES := $(plat_pcfiles)
-$(plat_property_contexts.tmp): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
-$(plat_property_contexts.tmp): $(plat_pcfiles)
-	@mkdir -p $(dir $@)
-	$(hide) m4 --fatal-warnings -s $(PRIVATE_ADDITIONAL_M4DEFS) $(PRIVATE_PC_FILES) > $@
-$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
-$(LOCAL_BUILT_MODULE): $(plat_property_contexts.tmp) $(built_sepolicy) $(HOST_OUT_EXECUTABLES)/property_info_checker
-	@mkdir -p $(dir $@)
-	$(hide) cp -f $< $@
-	$(hide) $(HOST_OUT_EXECUTABLES)/property_info_checker $(PRIVATE_SEPOLICY) $@
-
-built_plat_pc := $(LOCAL_BUILT_MODULE)
-plat_pcfiles :=
-plat_property_contexts.tmp :=
-
-##################################
-include $(CLEAR_VARS)
-LOCAL_MODULE := product_property_contexts
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_PRODUCT)/etc/selinux
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-product_pcfiles := $(call build_policy, property_contexts, $(PRODUCT_PRIVATE_POLICY))
-
-product_property_contexts.tmp := $(intermediates)/product_property_contexts.tmp
-$(product_property_contexts.tmp): PRIVATE_PC_FILES := $(product_pcfiles)
-$(product_property_contexts.tmp): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
-$(product_property_contexts.tmp): $(product_pcfiles)
-	@mkdir -p $(dir $@)
-	$(hide) m4 --fatal-warnings -s $(PRIVATE_ADDITIONAL_M4DEFS) $(PRIVATE_PC_FILES) > $@
-
-$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
-$(LOCAL_BUILT_MODULE): $(product_property_contexts.tmp) $(built_sepolicy) $(HOST_OUT_EXECUTABLES)/property_info_checker
-	@mkdir -p $(dir $@)
-	$(hide) cp -f $< $@
-	$(hide) $(HOST_OUT_EXECUTABLES)/property_info_checker $(PRIVATE_SEPOLICY) $@
-
-built_product_pc := $(LOCAL_BUILT_MODULE)
-product_pcfiles :=
-product_property_contexts.tmp :=
-
-##################################
-include $(CLEAR_VARS)
-LOCAL_MODULE := vendor_property_contexts
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/selinux
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-vendor_pcfiles := $(call build_policy, property_contexts, $(PLAT_VENDOR_POLICY) $(BOARD_VENDOR_SEPOLICY_DIRS) $(REQD_MASK_POLICY))
-
-vendor_property_contexts.tmp := $(intermediates)/vendor_property_contexts.tmp
-$(vendor_property_contexts.tmp): PRIVATE_PC_FILES := $(vendor_pcfiles)
-$(vendor_property_contexts.tmp): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
-$(vendor_property_contexts.tmp): $(vendor_pcfiles)
-	@mkdir -p $(dir $@)
-	$(hide) m4 --fatal-warnings -s $(PRIVATE_ADDITIONAL_M4DEFS) $(PRIVATE_PC_FILES) > $@
-
-$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
-$(LOCAL_BUILT_MODULE): PRIVATE_BUILT_PLAT_PC := $(built_plat_pc)
-$(LOCAL_BUILT_MODULE): $(vendor_property_contexts.tmp) $(built_sepolicy) $(built_plat_pc) $(HOST_OUT_EXECUTABLES)/property_info_checker
-	@mkdir -p $(dir $@)
-	$(hide) cp -f $< $@
-	$(hide) $(HOST_OUT_EXECUTABLES)/property_info_checker $(PRIVATE_SEPOLICY) $(PRIVATE_BUILT_PLAT_PC) $@
-
-built_vendor_pc := $(LOCAL_BUILT_MODULE)
-vendor_pcfiles :=
-vendor_property_contexts.tmp :=
-
-##################################
-include $(CLEAR_VARS)
-LOCAL_MODULE := odm_property_contexts
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_ODM)/etc/selinux
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-odm_pcfiles := $(call build_policy, property_contexts, $(BOARD_ODM_SEPOLICY_DIRS))
-
-odm_property_contexts.tmp := $(intermediates)/odm_property_contexts.tmp
-$(odm_property_contexts.tmp): PRIVATE_PC_FILES := $(odm_pcfiles)
-$(odm_property_contexts.tmp): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
-$(odm_property_contexts.tmp): $(odm_pcfiles)
-	@mkdir -p $(dir $@)
-	$(hide) m4 --fatal-warnings -s $(PRIVATE_ADDITIONAL_M4DEFS) $(PRIVATE_PC_FILES) > $@
-
-
-$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
-$(LOCAL_BUILT_MODULE): PRIVATE_BUILT_PLAT_PC := $(built_plat_pc)
-$(LOCAL_BUILT_MODULE): PRIVATE_BUILT_VENDOR_PC := $(built_vendor_pc)
-$(LOCAL_BUILT_MODULE): $(odm_property_contexts.tmp) $(built_sepolicy) $(built_plat_pc) $(built_vendor_pc) $(HOST_OUT_EXECUTABLES)/property_info_checker
-	@mkdir -p $(dir $@)
-	$(hide) cp -f $< $@
-	$(hide) $(HOST_OUT_EXECUTABLES)/property_info_checker $(PRIVATE_SEPOLICY) $(PRIVATE_BUILT_PLAT_PC) $(PRIVATE_BUILT_VENDOR_PC) $@
-
-built_odm_pc := $(LOCAL_BUILT_MODULE)
-odm_pcfiles :=
-odm_property_contexts.tmp :=
-
-##################################
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := plat_property_contexts.recovery
-LOCAL_MODULE_STEM := plat_property_contexts
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-$(LOCAL_BUILT_MODULE): $(built_plat_pc)
-	$(hide) cp -f $< $@
-
-##################################
-include $(CLEAR_VARS)
-LOCAL_MODULE := product_property_contexts.recovery
-LOCAL_MODULE_STEM := product_property_contexts
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-$(LOCAL_BUILT_MODULE): $(built_product_pc)
-	$(hide) cp -f $< $@
-
-##################################
-include $(CLEAR_VARS)
-LOCAL_MODULE := vendor_property_contexts.recovery
-LOCAL_MODULE_STEM := vendor_property_contexts
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-$(LOCAL_BUILT_MODULE): $(built_vendor_pc)
-	$(hide) cp -f $< $@
-
-##################################
-include $(CLEAR_VARS)
-LOCAL_MODULE := odm_property_contexts.recovery
-LOCAL_MODULE_STEM := odm_property_contexts
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-$(LOCAL_BUILT_MODULE): $(built_odm_pc)
-	$(hide) cp -f $< $@
diff --git a/service_contexts.mk b/service_contexts.mk
deleted file mode 100644
index da2bc23..0000000
--- a/service_contexts.mk
+++ /dev/null
@@ -1,89 +0,0 @@
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := plat_service_contexts
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/selinux
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-plat_svcfiles := $(call build_policy, service_contexts, $(PLAT_PRIVATE_POLICY))
-
-plat_service_contexts.tmp := $(intermediates)/plat_service_contexts.tmp
-$(plat_service_contexts.tmp): PRIVATE_SVC_FILES := $(plat_svcfiles)
-$(plat_service_contexts.tmp): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
-$(plat_service_contexts.tmp): $(plat_svcfiles)
-	@mkdir -p $(dir $@)
-	$(hide) m4 --fatal-warnings -s $(PRIVATE_ADDITIONAL_M4DEFS) $(PRIVATE_SVC_FILES) > $@
-
-$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
-$(LOCAL_BUILT_MODULE): $(plat_service_contexts.tmp) $(built_sepolicy) $(HOST_OUT_EXECUTABLES)/checkfc $(ACP)
-	@mkdir -p $(dir $@)
-	sed -e 's/#.*$$//' -e '/^$$/d' $< > $@
-	$(HOST_OUT_EXECUTABLES)/checkfc -s $(PRIVATE_SEPOLICY) $@
-
-built_plat_svc := $(LOCAL_BUILT_MODULE)
-plat_svcfiles :=
-plat_service_contexts.tmp :=
-
-##################################
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := product_service_contexts
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_PRODUCT)/etc/selinux
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-product_svcfiles := $(call build_policy, service_contexts, $(PRODUCT_PRIVATE_POLICY))
-
-product_service_contexts.tmp := $(intermediates)/product_service_contexts.tmp
-$(product_service_contexts.tmp): PRIVATE_SVC_FILES := $(product_svcfiles)
-$(product_service_contexts.tmp): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
-$(product_service_contexts.tmp): $(product_svcfiles)
-	@mkdir -p $(dir $@)
-	$(hide) m4 --fatal-warnings -s $(PRIVATE_ADDITIONAL_M4DEFS) $(PRIVATE_SVC_FILES) > $@
-
-$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
-$(LOCAL_BUILT_MODULE): $(product_service_contexts.tmp) $(built_sepolicy) $(HOST_OUT_EXECUTABLES)/checkfc
-	@mkdir -p $(dir $@)
-	sed -e 's/#.*$$//' -e '/^$$/d' $< > $@
-	$(HOST_OUT_EXECUTABLES)/checkfc -s $(PRIVATE_SEPOLICY) $@
-
-product_svcfiles :=
-product_service_contexts.tmp :=
-
-##################################
-# nonplat_service_contexts is only allowed on non-full-treble devices
-ifneq ($(PRODUCT_SEPOLICY_SPLIT),true)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := vendor_service_contexts
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-vendor_svcfiles := $(call build_policy, service_contexts, $(PLAT_VENDOR_POLICY) $(BOARD_VENDOR_SEPOLICY_DIRS) $(REQD_MASK_POLICY))
-
-vendor_service_contexts.tmp := $(intermediates)/vendor_service_contexts.tmp
-$(vendor_service_contexts.tmp): PRIVATE_SVC_FILES := $(vendor_svcfiles)
-$(vendor_service_contexts.tmp): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
-$(vendor_service_contexts.tmp): $(vendor_svcfiles)
-	@mkdir -p $(dir $@)
-	$(hide) m4 --fatal-warnings -s $(PRIVATE_ADDITIONAL_M4DEFS) $(PRIVATE_SVC_FILES) > $@
-
-$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
-$(LOCAL_BUILT_MODULE): $(vendor_service_contexts.tmp) $(built_sepolicy) $(HOST_OUT_EXECUTABLES)/checkfc $(ACP)
-	@mkdir -p $(dir $@)
-	sed -e 's/#.*$$//' -e '/^$$/d' $< > $@
-	$(hide) $(HOST_OUT_EXECUTABLES)/checkfc -s $(PRIVATE_SEPOLICY) $@
-
-built_vendor_svc := $(LOCAL_BUILT_MODULE)
-vendor_svcfiles :=
-vendor_service_contexts.tmp :=
-
-endif