diff --git a/android/androidmk.go b/android/androidmk.go index a24d7bc23..9f711bf5d 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -242,6 +242,9 @@ func translateAndroidMkModule(ctx SingletonContext, w io.Writer, mod blueprint.M if Bool(amod.commonProperties.Product_specific) { fmt.Fprintln(&data.preamble, "LOCAL_PRODUCT_MODULE := true") } + if Bool(amod.commonProperties.ProductServices_specific) { + fmt.Fprintln(&data.preamble, "LOCAL_PRODUCT_SERVICES_MODULE := true") + } if amod.commonProperties.Owner != nil { fmt.Fprintln(&data.preamble, "LOCAL_MODULE_OWNER :=", *amod.commonProperties.Owner) } diff --git a/android/config.go b/android/config.go index 7ba05c1b6..0015c023b 100644 --- a/android/config.go +++ b/android/config.go @@ -763,6 +763,13 @@ func (c *deviceConfig) ProductPath() string { return "product" } +func (c *deviceConfig) ProductServicesPath() string { + if c.config.productVariables.ProductServicesPath != nil { + return *c.config.productVariables.ProductServicesPath + } + return "product-services" +} + func (c *deviceConfig) BtConfigIncludeDir() string { return String(c.config.productVariables.BtConfigIncludeDir) } diff --git a/android/module.go b/android/module.go index b6220dc31..b58dd4b5f 100644 --- a/android/module.go +++ b/android/module.go @@ -69,6 +69,7 @@ type androidBaseContext interface { DeviceSpecific() bool SocSpecific() bool ProductSpecific() bool + ProductServicesSpecific() bool AConfig() Config DeviceConfig() DeviceConfig } @@ -241,6 +242,11 @@ type commonProperties struct { // /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 @@ const ( deviceSpecificModule socSpecificModule productSpecificModule + productServicesSpecificModule ) func (k moduleKind) String() string { @@ -315,6 +322,8 @@ func (k moduleKind) String() string { 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) DeviceSupported() bool { } 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 @@ func (a *ModuleBase) ProductSpecific() bool { 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 @@ func determineModuleKind(a *ModuleBase, ctx blueprint.BaseModuleContext) moduleK 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 @@ func determineModuleKind(a *ModuleBase, ctx blueprint.BaseModuleContext) moduleK } } + 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 @@ func (a *androidBaseContextImpl) ProductSpecific() bool { return a.kind == productSpecificModule } +func (a *androidBaseContextImpl) ProductServicesSpecific() bool { + return a.kind == productServicesSpecificModule +} + func (a *androidModuleContext) InstallInData() bool { return a.module.InstallInData() } diff --git a/android/paths.go b/android/paths.go index 31c5977ee..c9e715031 100644 --- a/android/paths.go +++ b/android/paths.go @@ -961,6 +961,8 @@ func PathForModuleInstall(ctx ModuleInstallPathContext, pathComponents ...string partition = ctx.DeviceConfig().OdmPath() } else if ctx.ProductSpecific() { partition = ctx.DeviceConfig().ProductPath() + } else if ctx.ProductServicesSpecific() { + partition = ctx.DeviceConfig().ProductServicesPath() } else { partition = "system" } diff --git a/android/paths_test.go b/android/paths_test.go index b3dc9de28..ff0eeb33b 100644 --- a/android/paths_test.go +++ b/android/paths_test.go @@ -292,6 +292,17 @@ func TestPathForModuleInstall(t *testing.T) { in: []string{"bin", "my_test"}, out: "target/product/test_device/product/bin/my_test", }, + { + name: "product-services binary", + ctx: &moduleInstallPathContextImpl{ + androidBaseContextImpl: androidBaseContextImpl{ + target: deviceTarget, + kind: productServicesSpecificModule, + }, + }, + in: []string{"bin", "my_test"}, + out: "target/product/test_device/product-services/bin/my_test", + }, { name: "system native test binary", @@ -341,6 +352,19 @@ func TestPathForModuleInstall(t *testing.T) { out: "target/product/test_device/data/nativetest/my_test", }, + { + name: "product-services native test binary", + ctx: &moduleInstallPathContextImpl{ + androidBaseContextImpl: androidBaseContextImpl{ + target: deviceTarget, + kind: productServicesSpecificModule, + }, + inData: true, + }, + in: []string{"nativetest", "my_test"}, + out: "target/product/test_device/data/nativetest/my_test", + }, + { name: "sanitized system binary", ctx: &moduleInstallPathContextImpl{ @@ -389,6 +413,19 @@ func TestPathForModuleInstall(t *testing.T) { out: "target/product/test_device/data/asan/product/bin/my_test", }, + { + name: "sanitized product-services binary", + ctx: &moduleInstallPathContextImpl{ + androidBaseContextImpl: androidBaseContextImpl{ + target: deviceTarget, + kind: productServicesSpecificModule, + }, + inSanitizerDir: true, + }, + in: []string{"bin", "my_test"}, + out: "target/product/test_device/data/asan/product-services/bin/my_test", + }, + { name: "sanitized system native test binary", ctx: &moduleInstallPathContextImpl{ @@ -440,6 +477,19 @@ func TestPathForModuleInstall(t *testing.T) { in: []string{"nativetest", "my_test"}, out: "target/product/test_device/data/asan/data/nativetest/my_test", }, + { + name: "sanitized product-services native test binary", + ctx: &moduleInstallPathContextImpl{ + androidBaseContextImpl: androidBaseContextImpl{ + target: deviceTarget, + kind: productServicesSpecificModule, + }, + inData: true, + inSanitizerDir: true, + }, + in: []string{"nativetest", "my_test"}, + out: "target/product/test_device/data/asan/data/nativetest/my_test", + }, } for _, tc := range testCases { diff --git a/android/variable.go b/android/variable.go index 5edcdbc00..d97fc0b6d 100644 --- a/android/variable.go +++ b/android/variable.go @@ -182,9 +182,10 @@ type productVariables struct { CFIExcludePaths *[]string `json:",omitempty"` CFIIncludePaths *[]string `json:",omitempty"` - VendorPath *string `json:",omitempty"` - OdmPath *string `json:",omitempty"` - ProductPath *string `json:",omitempty"` + VendorPath *string `json:",omitempty"` + OdmPath *string `json:",omitempty"` + ProductPath *string `json:",omitempty"` + ProductServicesPath *string `json:",omitempty"` UseClangLld *bool `json:",omitempty"` diff --git a/androidmk/cmd/androidmk/android.go b/androidmk/cmd/androidmk/android.go index 29c7365ee..1d509805c 100644 --- a/androidmk/cmd/androidmk/android.go +++ b/androidmk/cmd/androidmk/android.go @@ -174,6 +174,7 @@ func init() { "LOCAL_VENDOR_MODULE": "vendor", "LOCAL_ODM_MODULE": "device_specific", "LOCAL_PRODUCT_MODULE": "product_specific", + "LOCAL_PRODUCT_SERVICES_MODULE": "product_services_specific", "LOCAL_EXPORT_PACKAGE_RESOURCES": "export_package_resources", "LOCAL_PRIVILEGED_MODULE": "privileged",