Define odm_available property to install a vendor variant to odm

'vendor_available: true' creates a vendor variant from a system
module. The vendor variant of the module is installed to /vendor.
However, we may want to install the vendor variant to /odm, instead.

'device_specific: true' does not work for this purpose because
'vendor_available: true' is allowed only for the system or product
modules to create a vendor variant. But 'device_specific: true'
itself creates a vendor variant that may not work with
'vendor_available: true'.

To install the vendor variant to /odm, we define a new property
'odm_available'. 'odm_available' is exactly the same as the
'vendor_available' except the install path of the vendor variant.
By defining 'odm_available: true', the vendor variant of the module
will be installed to /odm or /vendor/odm instead of /vendor.

Bug: 176147321
Bug: 176079978
Test: check if a module with 'odm_available: true' is installed to
      /vendor/odm
Change-Id: I2d16bd2c515796597b2fbd1eb66f7c2736434697
This commit is contained in:
Justin Yun 2021-01-08 18:00:19 +09:00
parent f17b07fc52
commit ebcf0c5e15
6 changed files with 57 additions and 18 deletions

View file

@ -390,6 +390,17 @@ type VendorProperties struct {
// Nothing happens if BOARD_VNDK_VERSION isn't set in the BoardConfig.mk
Vendor_available *bool
// This is the same as the "vendor_available" except that the install path
// of the vendor variant is /odm or /vendor/odm.
// By replacing "vendor_available: true" with "odm_available: true", the
// module will install its vendor variant to the /odm partition or /vendor/odm.
// As the modules with "odm_available: true" still create the vendor variants,
// they can link to the other vendor modules as the vendor_available modules do.
// Also, the vendor modules can link to odm_available modules.
//
// It may not be used for VNDK modules.
Odm_available *bool
// whether this module should be allowed to be directly depended by other
// modules with `product_specific: true` or `product_available: true`.
// If set to true, an additional product variant will be built separately

View file

@ -25,6 +25,7 @@ func init() {
type GenruleExtraProperties struct {
Vendor_available *bool
Odm_available *bool
Product_available *bool
Ramdisk_available *bool
Vendor_ramdisk_available *bool
@ -63,7 +64,7 @@ func (g *GenruleExtraProperties) CoreVariantNeeded(ctx android.BaseModuleContext
return false
}
return Bool(g.Vendor_available) || Bool(g.Product_available) || !(ctx.SocSpecific() || ctx.DeviceSpecific())
return !(ctx.SocSpecific() || ctx.DeviceSpecific())
}
func (g *GenruleExtraProperties) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
@ -92,7 +93,7 @@ func (g *GenruleExtraProperties) ExtraImageVariations(ctx android.BaseModuleCont
}
var variants []string
if Bool(g.Vendor_available) || ctx.SocSpecific() || ctx.DeviceSpecific() {
if Bool(g.Vendor_available) || Bool(g.Odm_available) || ctx.SocSpecific() || ctx.DeviceSpecific() {
vndkVersion := ctx.DeviceConfig().VndkVersion()
// If vndkVersion is current, we can always use PlatformVndkVersion.
// If not, we assume modules under proprietary paths are compatible for

View file

@ -56,8 +56,14 @@ func (ctx *moduleContext) ProductSpecific() bool {
func (ctx *moduleContext) SocSpecific() bool {
// Additionally check if this module is inVendor() that means it is a "vendor" variant of a
// module. As well as SoC specific modules, vendor variants must be installed to /vendor.
return ctx.ModuleContext.SocSpecific() || ctx.mod.InVendor()
// module. As well as SoC specific modules, vendor variants must be installed to /vendor
// unless they have "odm_available: true".
return ctx.ModuleContext.SocSpecific() || (ctx.mod.InVendor() && !ctx.mod.VendorVariantToOdm())
}
func (ctx *moduleContext) DeviceSpecific() bool {
// Some vendor variants want to be installed to /odm by setting "odm_available: true".
return ctx.ModuleContext.DeviceSpecific() || (ctx.mod.InVendor() && ctx.mod.VendorVariantToOdm())
}
func (ctx *moduleContextImpl) inProduct() bool {
@ -82,7 +88,13 @@ func (ctx *moduleContextImpl) inRecovery() bool {
// Returns true when this module is configured to have core and vendor variants.
func (c *Module) HasVendorVariant() bool {
return Bool(c.VendorProperties.Vendor_available)
return Bool(c.VendorProperties.Vendor_available) || Bool(c.VendorProperties.Odm_available)
}
// Returns true when this module creates a vendor variant and wants to install the vendor variant
// to the odm partition.
func (c *Module) VendorVariantToOdm() bool {
return Bool(c.VendorProperties.Odm_available)
}
// Returns true when this module is configured to have core and product variants.
@ -183,7 +195,18 @@ func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
if Bool(m.VendorProperties.Vendor_available) {
if vendorSpecific {
mctx.PropertyErrorf("vendor_available",
"doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific:true`")
"doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`")
}
if Bool(m.VendorProperties.Odm_available) {
mctx.PropertyErrorf("vendor_available",
"doesn't make sense at the same time as `odm_available: true`")
}
}
if Bool(m.VendorProperties.Odm_available) {
if vendorSpecific {
mctx.PropertyErrorf("odm_available",
"doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`")
}
}

View file

@ -130,6 +130,10 @@ func (mt *librarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext,
pbm.AddProperty("vendor_available", true)
}
if proptools.Bool(ccModule.VendorProperties.Odm_available) {
pbm.AddProperty("odm_available", true)
}
if proptools.Bool(ccModule.VendorProperties.Product_available) {
pbm.AddProperty("product_available", true)
}

View file

@ -68,11 +68,7 @@ func (mod *Module) OnlyInVendorRamdisk() bool {
// Returns true when this module is configured to have core and vendor variants.
func (mod *Module) HasVendorVariant() bool {
return mod.IsVndk() || Bool(mod.VendorProperties.Vendor_available)
}
func (c *Module) VendorAvailable() bool {
return Bool(c.VendorProperties.Vendor_available)
return Bool(mod.VendorProperties.Vendor_available) || Bool(mod.VendorProperties.Odm_available)
}
func (c *Module) InProduct() bool {
@ -114,10 +110,15 @@ func (mod *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
coreVariantNeeded := true
var vendorVariants []string
if Bool(mod.VendorProperties.Vendor_available) {
if mod.HasVendorVariant() {
prop := "vendor_available"
if Bool(mod.VendorProperties.Odm_available) {
prop = "odm_available"
}
if vendorSpecific {
mctx.PropertyErrorf("vendor_available",
"doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific:true`")
mctx.PropertyErrorf(prop,
"doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`")
}
if lib, ok := mod.compiler.(libraryInterface); ok {
@ -128,9 +129,8 @@ func (mod *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
// We can't check shared() here because image mutator is called before the library mutator, so we need to
// check buildShared()
if lib.buildShared() {
mctx.PropertyErrorf("vendor_available",
"vendor_available can only be set for rust_ffi_static modules.")
} else if Bool(mod.VendorProperties.Vendor_available) == true {
mctx.PropertyErrorf(prop, "can only be set for rust_ffi_static modules.")
} else {
vendorVariants = append(vendorVariants, platformVndkVersion)
}
}

View file

@ -46,7 +46,7 @@ func TestVendorLinkage(t *testing.T) {
// Test that shared libraries cannot be made vendor available until proper support is added.
func TestForbiddenVendorLinkage(t *testing.T) {
testRustError(t, "vendor_available can only be set for rust_ffi_static modules", `
testRustError(t, "can only be set for rust_ffi_static modules", `
rust_ffi_shared {
name: "libfoo_vendor",
crate_name: "foo",