diff --git a/android/config.go b/android/config.go index bc1aa3a4d..614386f6f 100644 --- a/android/config.go +++ b/android/config.go @@ -1411,6 +1411,62 @@ func (c *deviceConfig) RecoverySnapshotModules() map[string]bool { return c.config.productVariables.RecoverySnapshotModules } +func createDirsMap(previous map[string]bool, dirs []string) (map[string]bool, error) { + var ret = make(map[string]bool) + for _, dir := range dirs { + clean := filepath.Clean(dir) + if previous[clean] || ret[clean] { + return nil, fmt.Errorf("Duplicate entry %s", dir) + } + ret[clean] = true + } + return ret, nil +} + +func (c *deviceConfig) createDirsMapOnce(onceKey OnceKey, previous map[string]bool, dirs []string) map[string]bool { + dirMap := c.Once(onceKey, func() interface{} { + ret, err := createDirsMap(previous, dirs) + if err != nil { + panic(fmt.Errorf("%s: %w", onceKey.key, err)) + } + return ret + }) + if dirMap == nil { + return nil + } + return dirMap.(map[string]bool) +} + +var vendorSnapshotDirsExcludedKey = NewOnceKey("VendorSnapshotDirsExcludedMap") + +func (c *deviceConfig) VendorSnapshotDirsExcludedMap() map[string]bool { + return c.createDirsMapOnce(vendorSnapshotDirsExcludedKey, nil, + c.config.productVariables.VendorSnapshotDirsExcluded) +} + +var vendorSnapshotDirsIncludedKey = NewOnceKey("VendorSnapshotDirsIncludedMap") + +func (c *deviceConfig) VendorSnapshotDirsIncludedMap() map[string]bool { + excludedMap := c.VendorSnapshotDirsExcludedMap() + return c.createDirsMapOnce(vendorSnapshotDirsIncludedKey, excludedMap, + c.config.productVariables.VendorSnapshotDirsIncluded) +} + +var recoverySnapshotDirsExcludedKey = NewOnceKey("RecoverySnapshotDirsExcludedMap") + +func (c *deviceConfig) RecoverySnapshotDirsExcludedMap() map[string]bool { + return c.createDirsMapOnce(recoverySnapshotDirsExcludedKey, nil, + c.config.productVariables.RecoverySnapshotDirsExcluded) +} + +var recoverySnapshotDirsIncludedKey = NewOnceKey("RecoverySnapshotDirsIncludedMap") + +func (c *deviceConfig) RecoverySnapshotDirsIncludedMap() map[string]bool { + excludedMap := c.RecoverySnapshotDirsExcludedMap() + return c.createDirsMapOnce(recoverySnapshotDirsIncludedKey, excludedMap, + c.config.productVariables.RecoverySnapshotDirsIncluded) +} + func (c *deviceConfig) ShippingApiLevel() ApiLevel { if c.config.productVariables.ShippingApiLevel == nil { return NoneApiLevel diff --git a/android/variable.go b/android/variable.go index d9c2ac237..ef95972c8 100644 --- a/android/variable.go +++ b/android/variable.go @@ -315,6 +315,11 @@ type productVariables struct { DirectedRecoverySnapshot bool `json:",omitempty"` RecoverySnapshotModules map[string]bool `json:",omitempty"` + VendorSnapshotDirsIncluded []string `json:",omitempty"` + VendorSnapshotDirsExcluded []string `json:",omitempty"` + RecoverySnapshotDirsExcluded []string `json:",omitempty"` + RecoverySnapshotDirsIncluded []string `json:",omitempty"` + BoardVendorSepolicyDirs []string `json:",omitempty"` BoardOdmSepolicyDirs []string `json:",omitempty"` BoardReqdMaskPolicy []string `json:",omitempty"` diff --git a/cc/snapshot_prebuilt.go b/cc/snapshot_prebuilt.go index f9aea0cfe..bbb889644 100644 --- a/cc/snapshot_prebuilt.go +++ b/cc/snapshot_prebuilt.go @@ -18,6 +18,7 @@ package cc // snapshot mutators and snapshot information maps which are also defined in this file. import ( + "path/filepath" "strings" "android/soong/android" @@ -45,9 +46,9 @@ type snapshotImage interface { // directory, such as device/, vendor/, etc. // // For a given snapshot (e.g., vendor, recovery, etc.) if - // isProprietaryPath(dir) returns true, then the module in dir will be - // built from sources. - isProprietaryPath(dir string) bool + // isProprietaryPath(dir, deviceConfig) returns true, then the module in dir + // will be built from sources. + isProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool // Whether to include VNDK in the snapshot for this image. includeVndk() bool @@ -82,6 +83,31 @@ type snapshotImage interface { type vendorSnapshotImage struct{} type recoverySnapshotImage struct{} +type directoryMap map[string]bool + +var ( + // Modules under following directories are ignored. They are OEM's and vendor's + // proprietary modules(device/, kernel/, vendor/, and hardware/). + defaultDirectoryExcludedMap = directoryMap{ + "device": true, + "hardware": true, + "kernel": true, + "vendor": true, + } + + // Modules under following directories are included as they are in AOSP, + // although hardware/ and kernel/ are normally for vendor's own. + defaultDirectoryIncludedMap = directoryMap{ + "kernel/configs": true, + "kernel/prebuilts": true, + "kernel/tests": true, + "hardware/interfaces": true, + "hardware/libhardware": true, + "hardware/libhardware_legacy": true, + "hardware/ril": true, + } +) + func (vendorSnapshotImage) init(ctx android.RegistrationContext) { ctx.RegisterSingletonType("vendor-snapshot", VendorSnapshotSingleton) ctx.RegisterModuleType("vendor_snapshot", vendorSnapshotFactory) @@ -107,8 +133,25 @@ func (vendorSnapshotImage) private(m *Module) bool { return m.IsVndkPrivate() } -func (vendorSnapshotImage) isProprietaryPath(dir string) bool { - return isVendorProprietaryPath(dir) +func isDirectoryExcluded(dir string, excludedMap directoryMap, includedMap directoryMap) bool { + if dir == "." || dir == "/" { + return false + } + if includedMap[dir] { + return false + } else if excludedMap[dir] { + return true + } else if defaultDirectoryIncludedMap[dir] { + return false + } else if defaultDirectoryExcludedMap[dir] { + return true + } else { + return isDirectoryExcluded(filepath.Dir(dir), excludedMap, includedMap) + } +} + +func (vendorSnapshotImage) isProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool { + return isDirectoryExcluded(dir, deviceConfig.VendorSnapshotDirsExcludedMap(), deviceConfig.VendorSnapshotDirsIncludedMap()) } // vendor snapshot includes static/header libraries with vndk: {enabled: true}. @@ -172,8 +215,8 @@ func (recoverySnapshotImage) private(m *Module) bool { return false } -func (recoverySnapshotImage) isProprietaryPath(dir string) bool { - return isRecoveryProprietaryPath(dir) +func (recoverySnapshotImage) isProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool { + return isDirectoryExcluded(dir, deviceConfig.RecoverySnapshotDirsExcludedMap(), deviceConfig.RecoverySnapshotDirsIncludedMap()) } // recovery snapshot does NOT treat vndk specially. diff --git a/cc/snapshot_utils.go b/cc/snapshot_utils.go index c50ef4535..c32fa364f 100644 --- a/cc/snapshot_utils.go +++ b/cc/snapshot_utils.go @@ -80,7 +80,7 @@ func shouldCollectHeadersForSnapshot(ctx android.ModuleContext, m *Module, apexI } for _, image := range []snapshotImage{vendorSnapshotImageSingleton, recoverySnapshotImageSingleton} { - if isSnapshotAware(ctx.DeviceConfig(), m, image.isProprietaryPath(ctx.ModuleDir()), apexInfo, image) { + if isSnapshotAware(ctx.DeviceConfig(), m, image.isProprietaryPath(ctx.ModuleDir(), ctx.DeviceConfig()), apexInfo, image) { return true } } diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go index 7077b7179..fdd1fec20 100644 --- a/cc/vendor_snapshot.go +++ b/cc/vendor_snapshot.go @@ -90,73 +90,24 @@ type snapshotSingleton struct { fake bool } -var ( - // Modules under following directories are ignored. They are OEM's and vendor's - // proprietary modules(device/, kernel/, vendor/, and hardware/). - vendorProprietaryDirs = []string{ - "device", - "kernel", - "vendor", - "hardware", - } - - // Modules under following directories are ignored. They are OEM's and vendor's - // proprietary modules(device/, kernel/, vendor/, and hardware/). - recoveryProprietaryDirs = []string{ - "device", - "hardware", - "kernel", - "vendor", - } - - // Modules under following directories are included as they are in AOSP, - // although hardware/ and kernel/ are normally for vendor's own. - aospDirsUnderProprietary = []string{ - "kernel/configs", - "kernel/prebuilts", - "kernel/tests", - "hardware/interfaces", - "hardware/libhardware", - "hardware/libhardware_legacy", - "hardware/ril", - } -) - -// Determine if a dir under source tree is an SoC-owned proprietary directory, such as -// device/, vendor/, etc. -func isVendorProprietaryPath(dir string) bool { - return isProprietaryPath(dir, vendorProprietaryDirs) +// Determine if a dir under source tree is an SoC-owned proprietary directory based +// on vendor snapshot configuration +// Examples: device/, vendor/ +func isVendorProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool { + return VendorSnapshotSingleton().(*snapshotSingleton).image.isProprietaryPath(dir, deviceConfig) } -func isRecoveryProprietaryPath(dir string) bool { - return isProprietaryPath(dir, recoveryProprietaryDirs) -} - -// Determine if a dir under source tree is an SoC-owned proprietary directory, such as -// device/, vendor/, etc. -func isProprietaryPath(dir string, proprietaryDirs []string) bool { - for _, p := range proprietaryDirs { - if strings.HasPrefix(dir, p) { - // filter out AOSP defined directories, e.g. hardware/interfaces/ - aosp := false - for _, p := range aospDirsUnderProprietary { - if strings.HasPrefix(dir, p) { - aosp = true - break - } - } - if !aosp { - return true - } - } - } - return false +// Determine if a dir under source tree is an SoC-owned proprietary directory based +// on recovery snapshot configuration +// Examples: device/, vendor/ +func isRecoveryProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool { + return RecoverySnapshotSingleton().(*snapshotSingleton).image.isProprietaryPath(dir, deviceConfig) } func isVendorProprietaryModule(ctx android.BaseModuleContext) bool { // Any module in a vendor proprietary path is a vendor proprietary // module. - if isVendorProprietaryPath(ctx.ModuleDir()) { + if isVendorProprietaryPath(ctx.ModuleDir(), ctx.DeviceConfig()) { return true } @@ -177,7 +128,7 @@ func isRecoveryProprietaryModule(ctx android.BaseModuleContext) bool { // Any module in a recovery proprietary path is a recovery proprietary // module. - if isRecoveryProprietaryPath(ctx.ModuleDir()) { + if isRecoveryProprietaryPath(ctx.ModuleDir(), ctx.DeviceConfig()) { return true } @@ -513,7 +464,7 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) { } moduleDir := ctx.ModuleDir(module) - inProprietaryPath := c.image.isProprietaryPath(moduleDir) + inProprietaryPath := c.image.isProprietaryPath(moduleDir, ctx.DeviceConfig()) apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo) if c.image.excludeFromSnapshot(m) {