Jaewoong Jung | aa65e17 | 2019-02-22 16:28:40 -0800 | [diff] [blame^] | 1 | package android |
| 2 | |
| 3 | import ( |
| 4 | "github.com/google/blueprint/proptools" |
| 5 | "sync" |
| 6 | ) |
| 7 | |
| 8 | func init() { |
| 9 | RegisterModuleType("override_module", OverrideModuleFactory) |
| 10 | } |
| 11 | |
| 12 | type OverrideModule struct { |
| 13 | ModuleBase |
| 14 | properties OverrideModuleProperties |
| 15 | } |
| 16 | |
| 17 | type OverrideModuleProperties struct { |
| 18 | // base module to override |
| 19 | Base *string |
| 20 | |
| 21 | // file path or module name (in the form ":module") of a certificate to override with |
| 22 | Certificate *string |
| 23 | |
| 24 | // manifest package name to override with |
| 25 | Manifest_package_name *string |
| 26 | } |
| 27 | |
| 28 | // TODO(jungjw): Work with the mainline team to see if we can deprecate all PRODUCT_*_OVERRIDES vars |
| 29 | // and hand over overriding values directly to base module code. |
| 30 | func processOverrides(ctx LoadHookContext, p *OverrideModuleProperties) { |
| 31 | base := proptools.String(p.Base) |
| 32 | if base == "" { |
| 33 | ctx.PropertyErrorf("base", "base module name must be provided") |
| 34 | } |
| 35 | |
| 36 | config := ctx.DeviceConfig() |
| 37 | if other, loaded := config.moduleNameOverrides().LoadOrStore(base, ctx.ModuleName()); loaded { |
| 38 | ctx.ModuleErrorf("multiple overriding modules for %q, the other: %q", base, other.(string)) |
| 39 | } |
| 40 | |
| 41 | if p.Certificate != nil { |
| 42 | config.certificateOverrides().Store(base, *p.Certificate) |
| 43 | } |
| 44 | |
| 45 | if p.Manifest_package_name != nil { |
| 46 | config.manifestPackageNameOverrides().Store(base, *p.Manifest_package_name) |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | func (i *OverrideModule) DepsMutator(ctx BottomUpMutatorContext) { |
| 51 | base := *i.properties.Base |
| 52 | // Right now, we add a dependency only to check the base module exists, and so are not using a tag here. |
| 53 | // TODO(jungjw): Add a tag and check the base module type once we finalize supported base module types. |
| 54 | ctx.AddDependency(ctx.Module(), nil, base) |
| 55 | } |
| 56 | |
| 57 | func (i *OverrideModule) GenerateAndroidBuildActions(ctx ModuleContext) { |
| 58 | // All the overrides happen in the base module. |
| 59 | // TODO(jungjw): Check the base module type. |
| 60 | } |
| 61 | |
| 62 | // override_module overrides an existing module with the specified properties. |
| 63 | // |
| 64 | // Currently, only android_app is officially supported. |
| 65 | func OverrideModuleFactory() Module { |
| 66 | m := &OverrideModule{} |
| 67 | AddLoadHook(m, func(ctx LoadHookContext) { |
| 68 | processOverrides(ctx, &m.properties) |
| 69 | }) |
| 70 | m.AddProperties(&m.properties) |
| 71 | InitAndroidModule(m) |
| 72 | return m |
| 73 | } |
| 74 | |
| 75 | var moduleNameOverridesKey = NewOnceKey("moduleNameOverrides") |
| 76 | |
| 77 | func (c *deviceConfig) moduleNameOverrides() *sync.Map { |
| 78 | return c.Once(moduleNameOverridesKey, func() interface{} { |
| 79 | return &sync.Map{} |
| 80 | }).(*sync.Map) |
| 81 | } |
| 82 | |
| 83 | var certificateOverridesKey = NewOnceKey("certificateOverrides") |
| 84 | |
| 85 | func (c *deviceConfig) certificateOverrides() *sync.Map { |
| 86 | return c.Once(certificateOverridesKey, func() interface{} { |
| 87 | return &sync.Map{} |
| 88 | }).(*sync.Map) |
| 89 | } |
| 90 | |
| 91 | var manifestPackageNameOverridesKey = NewOnceKey("manifestPackageNameOverrides") |
| 92 | |
| 93 | func (c *deviceConfig) manifestPackageNameOverrides() *sync.Map { |
| 94 | return c.Once(manifestPackageNameOverridesKey, func() interface{} { |
| 95 | return &sync.Map{} |
| 96 | }).(*sync.Map) |
| 97 | } |