Merge changes I13df3115,I825c6df0 am: 955ade6475
Change-Id: Iba825844a68e1bd42bfc1b6cffb072600573d60c
This commit is contained in:
@@ -35,6 +35,9 @@ type DefaultableModuleBase struct {
|
|||||||
defaultsProperties defaultsProperties
|
defaultsProperties defaultsProperties
|
||||||
defaultableProperties []interface{}
|
defaultableProperties []interface{}
|
||||||
defaultableVariableProperties interface{}
|
defaultableVariableProperties interface{}
|
||||||
|
|
||||||
|
// The optional hook to call after any defaults have been applied.
|
||||||
|
hook DefaultableHook
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DefaultableModuleBase) defaults() *defaultsProperties {
|
func (d *DefaultableModuleBase) defaults() *defaultsProperties {
|
||||||
@@ -46,6 +49,16 @@ func (d *DefaultableModuleBase) setProperties(props []interface{}, variablePrope
|
|||||||
d.defaultableVariableProperties = variableProperties
|
d.defaultableVariableProperties = variableProperties
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *DefaultableModuleBase) SetDefaultableHook(hook DefaultableHook) {
|
||||||
|
d.hook = hook
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DefaultableModuleBase) callHookIfAvailable(ctx DefaultableHookContext) {
|
||||||
|
if d.hook != nil {
|
||||||
|
d.hook(ctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Interface that must be supported by any module to which defaults can be applied.
|
// Interface that must be supported by any module to which defaults can be applied.
|
||||||
type Defaultable interface {
|
type Defaultable interface {
|
||||||
// Get a pointer to the struct containing the Defaults property.
|
// Get a pointer to the struct containing the Defaults property.
|
||||||
@@ -57,6 +70,15 @@ type Defaultable interface {
|
|||||||
// Apply defaults from the supplied Defaults to the property structures supplied to
|
// Apply defaults from the supplied Defaults to the property structures supplied to
|
||||||
// setProperties(...).
|
// setProperties(...).
|
||||||
applyDefaults(TopDownMutatorContext, []Defaults)
|
applyDefaults(TopDownMutatorContext, []Defaults)
|
||||||
|
|
||||||
|
// Set the hook to be called after any defaults have been applied.
|
||||||
|
//
|
||||||
|
// Should be used in preference to a AddLoadHook when the behavior of the load
|
||||||
|
// hook is dependent on properties supplied in the Android.bp file.
|
||||||
|
SetDefaultableHook(hook DefaultableHook)
|
||||||
|
|
||||||
|
// Call the hook if specified.
|
||||||
|
callHookIfAvailable(context DefaultableHookContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
type DefaultableModule interface {
|
type DefaultableModule interface {
|
||||||
@@ -75,6 +97,15 @@ func InitDefaultableModule(module DefaultableModule) {
|
|||||||
module.AddProperties(module.defaults())
|
module.AddProperties(module.defaults())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A restricted subset of context methods, similar to LoadHookContext.
|
||||||
|
type DefaultableHookContext interface {
|
||||||
|
EarlyModuleContext
|
||||||
|
|
||||||
|
CreateModule(ModuleFactory, ...interface{}) Module
|
||||||
|
}
|
||||||
|
|
||||||
|
type DefaultableHook func(ctx DefaultableHookContext)
|
||||||
|
|
||||||
// The Defaults_visibility property.
|
// The Defaults_visibility property.
|
||||||
type DefaultsVisibilityProperties struct {
|
type DefaultsVisibilityProperties struct {
|
||||||
|
|
||||||
@@ -268,25 +299,29 @@ func defaultsDepsMutator(ctx BottomUpMutatorContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func defaultsMutator(ctx TopDownMutatorContext) {
|
func defaultsMutator(ctx TopDownMutatorContext) {
|
||||||
if defaultable, ok := ctx.Module().(Defaultable); ok && len(defaultable.defaults().Defaults) > 0 {
|
if defaultable, ok := ctx.Module().(Defaultable); ok {
|
||||||
var defaultsList []Defaults
|
if len(defaultable.defaults().Defaults) > 0 {
|
||||||
seen := make(map[Defaults]bool)
|
var defaultsList []Defaults
|
||||||
|
seen := make(map[Defaults]bool)
|
||||||
|
|
||||||
ctx.WalkDeps(func(module, parent Module) bool {
|
ctx.WalkDeps(func(module, parent Module) bool {
|
||||||
if ctx.OtherModuleDependencyTag(module) == DefaultsDepTag {
|
if ctx.OtherModuleDependencyTag(module) == DefaultsDepTag {
|
||||||
if defaults, ok := module.(Defaults); ok {
|
if defaults, ok := module.(Defaults); ok {
|
||||||
if !seen[defaults] {
|
if !seen[defaults] {
|
||||||
seen[defaults] = true
|
seen[defaults] = true
|
||||||
defaultsList = append(defaultsList, defaults)
|
defaultsList = append(defaultsList, defaults)
|
||||||
return len(defaults.defaults().Defaults) > 0
|
return len(defaults.defaults().Defaults) > 0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ctx.PropertyErrorf("defaults", "module %s is not an defaults module",
|
||||||
|
ctx.OtherModuleName(module))
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
ctx.PropertyErrorf("defaults", "module %s is not an defaults module",
|
|
||||||
ctx.OtherModuleName(module))
|
|
||||||
}
|
}
|
||||||
}
|
return false
|
||||||
return false
|
})
|
||||||
})
|
defaultable.applyDefaults(ctx, defaultsList)
|
||||||
defaultable.applyDefaults(ctx, defaultsList)
|
}
|
||||||
|
|
||||||
|
defaultable.callHookIfAvailable(ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -39,6 +39,12 @@ type LoadHookContext interface {
|
|||||||
moduleFactories() map[string]blueprint.ModuleFactory
|
moduleFactories() map[string]blueprint.ModuleFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add a hook that will be called once the module has been loaded, i.e. its
|
||||||
|
// properties have been initialized from the Android.bp file.
|
||||||
|
//
|
||||||
|
// Consider using SetDefaultableHook to register a hook for any module that implements
|
||||||
|
// DefaultableModule as the hook is called after any defaults have been applied to the
|
||||||
|
// module which could reduce duplication and make it easier to use.
|
||||||
func AddLoadHook(m blueprint.Module, hook func(LoadHookContext)) {
|
func AddLoadHook(m blueprint.Module, hook func(LoadHookContext)) {
|
||||||
blueprint.AddLoadHook(m, func(ctx blueprint.LoadHookContext) {
|
blueprint.AddLoadHook(m, func(ctx blueprint.LoadHookContext) {
|
||||||
actx := &loadHookContext{
|
actx := &loadHookContext{
|
||||||
|
@@ -82,10 +82,6 @@ type RegisterMutatorFunc func(RegisterMutatorsContext)
|
|||||||
var preArch = []RegisterMutatorFunc{
|
var preArch = []RegisterMutatorFunc{
|
||||||
RegisterNamespaceMutator,
|
RegisterNamespaceMutator,
|
||||||
|
|
||||||
// Create an association between prebuilt modules and their corresponding source
|
|
||||||
// modules (if any).
|
|
||||||
RegisterPrebuiltsPreArchMutators,
|
|
||||||
|
|
||||||
// Check the visibility rules are valid.
|
// Check the visibility rules are valid.
|
||||||
//
|
//
|
||||||
// This must run after the package renamer mutators so that any issues found during
|
// This must run after the package renamer mutators so that any issues found during
|
||||||
@@ -114,8 +110,19 @@ var preArch = []RegisterMutatorFunc{
|
|||||||
RegisterVisibilityRuleChecker,
|
RegisterVisibilityRuleChecker,
|
||||||
|
|
||||||
// Apply properties from defaults modules to the referencing modules.
|
// Apply properties from defaults modules to the referencing modules.
|
||||||
|
//
|
||||||
|
// Any mutators that are added before this will not see any modules created by
|
||||||
|
// a DefaultableHook.
|
||||||
RegisterDefaultsPreArchMutators,
|
RegisterDefaultsPreArchMutators,
|
||||||
|
|
||||||
|
// Create an association between prebuilt modules and their corresponding source
|
||||||
|
// modules (if any).
|
||||||
|
//
|
||||||
|
// Must be run after defaults mutators to ensure that any modules created by
|
||||||
|
// a DefaultableHook can be either a prebuilt or a source module with a matching
|
||||||
|
// prebuilt.
|
||||||
|
RegisterPrebuiltsPreArchMutators,
|
||||||
|
|
||||||
// Gather the visibility rules for all modules for us during visibility enforcement.
|
// Gather the visibility rules for all modules for us during visibility enforcement.
|
||||||
//
|
//
|
||||||
// This must come after the defaults mutators to ensure that any visibility supplied
|
// This must come after the defaults mutators to ensure that any visibility supplied
|
||||||
|
@@ -903,6 +903,69 @@ var visibilityTests = []struct {
|
|||||||
}`),
|
}`),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "ensure visibility properties are checked for correctness",
|
||||||
|
fs: map[string][]byte{
|
||||||
|
"top/Blueprints": []byte(`
|
||||||
|
mock_parent {
|
||||||
|
name: "parent",
|
||||||
|
visibility: ["//top/nested"],
|
||||||
|
child: {
|
||||||
|
name: "libchild",
|
||||||
|
visibility: ["top/other"],
|
||||||
|
},
|
||||||
|
}`),
|
||||||
|
},
|
||||||
|
expectedErrors: []string{
|
||||||
|
`module "parent": child.visibility: invalid visibility pattern "top/other"`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid visibility added to child detected during gather phase",
|
||||||
|
fs: map[string][]byte{
|
||||||
|
"top/Blueprints": []byte(`
|
||||||
|
mock_parent {
|
||||||
|
name: "parent",
|
||||||
|
visibility: ["//top/nested"],
|
||||||
|
child: {
|
||||||
|
name: "libchild",
|
||||||
|
invalid_visibility: ["top/other"],
|
||||||
|
},
|
||||||
|
}`),
|
||||||
|
},
|
||||||
|
expectedErrors: []string{
|
||||||
|
// That this error is reported against the child not the parent shows it was
|
||||||
|
// not being detected in the parent which is correct as invalid_visibility is
|
||||||
|
// purposely not added to the list of visibility properties to check, and was
|
||||||
|
// in fact detected in the child in the gather phase. Contrast this error message
|
||||||
|
// with the preceding one.
|
||||||
|
`module "libchild" \(created by module "parent"\): visibility: invalid visibility pattern "top/other"`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "automatic visibility inheritance enabled",
|
||||||
|
fs: map[string][]byte{
|
||||||
|
"top/Blueprints": []byte(`
|
||||||
|
mock_parent {
|
||||||
|
name: "parent",
|
||||||
|
visibility: ["//top/nested"],
|
||||||
|
child: {
|
||||||
|
name: "libchild",
|
||||||
|
visibility: ["//top/other"],
|
||||||
|
},
|
||||||
|
}`),
|
||||||
|
"top/nested/Blueprints": []byte(`
|
||||||
|
mock_library {
|
||||||
|
name: "libnested",
|
||||||
|
deps: ["libchild"],
|
||||||
|
}`),
|
||||||
|
"top/other/Blueprints": []byte(`
|
||||||
|
mock_library {
|
||||||
|
name: "libother",
|
||||||
|
deps: ["libchild"],
|
||||||
|
}`),
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVisibility(t *testing.T) {
|
func TestVisibility(t *testing.T) {
|
||||||
@@ -936,6 +999,7 @@ func testVisibility(buildDir string, fs map[string][]byte) (*TestContext, []erro
|
|||||||
|
|
||||||
ctx := NewTestArchContext()
|
ctx := NewTestArchContext()
|
||||||
ctx.RegisterModuleType("mock_library", newMockLibraryModule)
|
ctx.RegisterModuleType("mock_library", newMockLibraryModule)
|
||||||
|
ctx.RegisterModuleType("mock_parent", newMockParentFactory)
|
||||||
ctx.RegisterModuleType("mock_defaults", defaultsFactory)
|
ctx.RegisterModuleType("mock_defaults", defaultsFactory)
|
||||||
|
|
||||||
// Order of the following method calls is significant.
|
// Order of the following method calls is significant.
|
||||||
@@ -996,3 +1060,42 @@ func defaultsFactory() Module {
|
|||||||
InitDefaultsModule(m)
|
InitDefaultsModule(m)
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type mockParentProperties struct {
|
||||||
|
Child struct {
|
||||||
|
Name *string
|
||||||
|
|
||||||
|
// Visibility to pass to the child module.
|
||||||
|
Visibility []string
|
||||||
|
|
||||||
|
// Purposely not validated visibility to pass to the child.
|
||||||
|
Invalid_visibility []string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type mockParent struct {
|
||||||
|
ModuleBase
|
||||||
|
DefaultableModuleBase
|
||||||
|
properties mockParentProperties
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *mockParent) GenerateAndroidBuildActions(ModuleContext) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func newMockParentFactory() Module {
|
||||||
|
m := &mockParent{}
|
||||||
|
m.AddProperties(&m.properties)
|
||||||
|
InitAndroidArchModule(m, HostAndDeviceSupported, MultilibCommon)
|
||||||
|
InitDefaultableModule(m)
|
||||||
|
AddVisibilityProperty(m, "child.visibility", &m.properties.Child.Visibility)
|
||||||
|
|
||||||
|
m.SetDefaultableHook(func(ctx DefaultableHookContext) {
|
||||||
|
visibility := m.properties.Child.Visibility
|
||||||
|
visibility = append(visibility, m.properties.Child.Invalid_visibility...)
|
||||||
|
ctx.CreateModule(newMockLibraryModule, &struct {
|
||||||
|
Name *string
|
||||||
|
Visibility []string
|
||||||
|
}{m.properties.Child.Name, visibility})
|
||||||
|
})
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
@@ -4530,12 +4530,12 @@ func testNoUpdatableJarsInBootImage(t *testing.T, errmsg, bp string, transformDe
|
|||||||
ctx.RegisterModuleType("apex", BundleFactory)
|
ctx.RegisterModuleType("apex", BundleFactory)
|
||||||
ctx.RegisterModuleType("apex_key", ApexKeyFactory)
|
ctx.RegisterModuleType("apex_key", ApexKeyFactory)
|
||||||
ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
|
ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
|
||||||
|
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
|
||||||
cc.RegisterRequiredBuildComponentsForTest(ctx)
|
cc.RegisterRequiredBuildComponentsForTest(ctx)
|
||||||
java.RegisterJavaBuildComponents(ctx)
|
java.RegisterJavaBuildComponents(ctx)
|
||||||
java.RegisterSystemModulesBuildComponents(ctx)
|
java.RegisterSystemModulesBuildComponents(ctx)
|
||||||
java.RegisterAppBuildComponents(ctx)
|
java.RegisterAppBuildComponents(ctx)
|
||||||
java.RegisterDexpreoptBootJarsComponents(ctx)
|
java.RegisterDexpreoptBootJarsComponents(ctx)
|
||||||
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
|
|
||||||
ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
|
ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
|
||||||
ctx.PreDepsMutators(RegisterPreDepsMutators)
|
ctx.PreDepsMutators(RegisterPreDepsMutators)
|
||||||
ctx.PostDepsMutators(RegisterPostDepsMutators)
|
ctx.PostDepsMutators(RegisterPostDepsMutators)
|
||||||
|
@@ -485,8 +485,8 @@ func CreateTestContext() *android.TestContext {
|
|||||||
ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
|
ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
|
||||||
ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory)
|
ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory)
|
||||||
ctx.RegisterModuleType("vndk_libraries_txt", VndkLibrariesTxtFactory)
|
ctx.RegisterModuleType("vndk_libraries_txt", VndkLibrariesTxtFactory)
|
||||||
RegisterRequiredBuildComponentsForTest(ctx)
|
|
||||||
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
|
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
|
||||||
|
RegisterRequiredBuildComponentsForTest(ctx)
|
||||||
ctx.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton)
|
ctx.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton)
|
||||||
ctx.RegisterSingletonType("vendor-snapshot", VendorSnapshotSingleton)
|
ctx.RegisterSingletonType("vendor-snapshot", VendorSnapshotSingleton)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user