Add support for /product-services partition

This is an adaptation of Icc4f8c16bc389fe20db680849f311d02df1299c3, to
support modules that are installed on the /product-services partition.

Bug: 80741439
Test: m -j both with and without enabling the new partition
Change-Id: I72b335ad38baff5848cd3da7489343f8cf98ff16
diff --git a/android/module.go b/android/module.go
index b6220dc..b58dd4b 100644
--- a/android/module.go
+++ b/android/module.go
@@ -69,6 +69,7 @@
 	DeviceSpecific() bool
 	SocSpecific() bool
 	ProductSpecific() bool
+	ProductServicesSpecific() bool
 	AConfig() Config
 	DeviceConfig() DeviceConfig
 }
@@ -241,6 +242,11 @@
 	// /system/product if product partition does not exist).
 	Product_specific *bool
 
+	// whether this module provides services owned by the OS provider to the core platform. When set
+	// to true, it is installed into  /product-services (or /system/product-services if
+	// product-services partition does not exist).
+	ProductServices_specific *bool
+
 	// Whether this module is installed to recovery partition
 	Recovery *bool
 
@@ -303,6 +309,7 @@
 	deviceSpecificModule
 	socSpecificModule
 	productSpecificModule
+	productServicesSpecificModule
 )
 
 func (k moduleKind) String() string {
@@ -315,6 +322,8 @@
 		return "soc-specific"
 	case productSpecificModule:
 		return "product-specific"
+	case productServicesSpecificModule:
+		return "productservices-specific"
 	default:
 		panic(fmt.Errorf("unknown module kind %d", k))
 	}
@@ -507,7 +516,7 @@
 }
 
 func (a *ModuleBase) Platform() bool {
-	return !a.DeviceSpecific() && !a.SocSpecific() && !a.ProductSpecific()
+	return !a.DeviceSpecific() && !a.SocSpecific() && !a.ProductSpecific() && !a.ProductServicesSpecific()
 }
 
 func (a *ModuleBase) DeviceSpecific() bool {
@@ -522,6 +531,10 @@
 	return Bool(a.commonProperties.Product_specific)
 }
 
+func (a *ModuleBase) ProductServicesSpecific() bool {
+	return Bool(a.commonProperties.ProductServices_specific)
+}
+
 func (a *ModuleBase) Enabled() bool {
 	if a.commonProperties.Enabled == nil {
 		return !a.Os().DefaultDisabled
@@ -632,17 +645,11 @@
 	var socSpecific = Bool(a.commonProperties.Vendor) || Bool(a.commonProperties.Proprietary) || Bool(a.commonProperties.Soc_specific)
 	var deviceSpecific = Bool(a.commonProperties.Device_specific)
 	var productSpecific = Bool(a.commonProperties.Product_specific)
+	var productServicesSpecific = Bool(a.commonProperties.ProductServices_specific)
 
-	if ((socSpecific || deviceSpecific) && productSpecific) || (socSpecific && deviceSpecific) {
-		msg := "conflicting value set here"
-		if productSpecific {
-			ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
-			if deviceSpecific {
-				ctx.PropertyErrorf("device_specific", msg)
-			}
-		} else {
-			ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
-		}
+	msg := "conflicting value set here"
+	if socSpecific && deviceSpecific {
+		ctx.PropertyErrorf("device_specific", "a module cannot be specific to SoC and device at the same time.")
 		if Bool(a.commonProperties.Vendor) {
 			ctx.PropertyErrorf("vendor", msg)
 		}
@@ -654,8 +661,36 @@
 		}
 	}
 
+	if productSpecific && productServicesSpecific {
+		ctx.PropertyErrorf("product_specific", "a module cannot be specific to product and product_services at the same time.")
+		ctx.PropertyErrorf("product_services_specific", msg)
+	}
+
+	if (socSpecific || deviceSpecific) && (productSpecific || productServicesSpecific) {
+		if productSpecific {
+			ctx.PropertyErrorf("product_specific", "a module cannot be specific to SoC or device and product at the same time.")
+		} else {
+			ctx.PropertyErrorf("product_services_specific", "a module cannot be specific to SoC or device and product_services at the same time.")
+		}
+		if deviceSpecific {
+			ctx.PropertyErrorf("device_specific", msg)
+		} else {
+			if Bool(a.commonProperties.Vendor) {
+				ctx.PropertyErrorf("vendor", msg)
+			}
+			if Bool(a.commonProperties.Proprietary) {
+				ctx.PropertyErrorf("proprietary", msg)
+			}
+			if Bool(a.commonProperties.Soc_specific) {
+				ctx.PropertyErrorf("soc_specific", msg)
+			}
+		}
+	}
+
 	if productSpecific {
 		return productSpecificModule
+	} else if productServicesSpecific {
+		return productServicesSpecificModule
 	} else if deviceSpecific {
 		return deviceSpecificModule
 	} else if socSpecific {
@@ -1012,6 +1047,10 @@
 	return a.kind == productSpecificModule
 }
 
+func (a *androidBaseContextImpl) ProductServicesSpecific() bool {
+	return a.kind == productServicesSpecificModule
+}
+
 func (a *androidModuleContext) InstallInData() bool {
 	return a.module.InstallInData()
 }