xref: /aosp_15_r20/build/soong/fsgen/prebuilt_etc_modules_gen.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright (C) 2024 The Android Open Source Project
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage fsgen
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
19*333d2b36SAndroid Build Coastguard Worker	"android/soong/etc"
20*333d2b36SAndroid Build Coastguard Worker	"fmt"
21*333d2b36SAndroid Build Coastguard Worker	"path/filepath"
22*333d2b36SAndroid Build Coastguard Worker	"strings"
23*333d2b36SAndroid Build Coastguard Worker
24*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/proptools"
25*333d2b36SAndroid Build Coastguard Worker)
26*333d2b36SAndroid Build Coastguard Worker
27*333d2b36SAndroid Build Coastguard Workertype srcBaseFileInstallBaseFileTuple struct {
28*333d2b36SAndroid Build Coastguard Worker	srcBaseFile     string
29*333d2b36SAndroid Build Coastguard Worker	installBaseFile string
30*333d2b36SAndroid Build Coastguard Worker}
31*333d2b36SAndroid Build Coastguard Worker
32*333d2b36SAndroid Build Coastguard Worker// prebuilt src files grouped by the install partitions.
33*333d2b36SAndroid Build Coastguard Worker// Each groups are a mapping of the relative install path to the name of the files
34*333d2b36SAndroid Build Coastguard Workertype prebuiltSrcGroupByInstallPartition struct {
35*333d2b36SAndroid Build Coastguard Worker	system     map[string][]srcBaseFileInstallBaseFileTuple
36*333d2b36SAndroid Build Coastguard Worker	system_ext map[string][]srcBaseFileInstallBaseFileTuple
37*333d2b36SAndroid Build Coastguard Worker	product    map[string][]srcBaseFileInstallBaseFileTuple
38*333d2b36SAndroid Build Coastguard Worker	vendor     map[string][]srcBaseFileInstallBaseFileTuple
39*333d2b36SAndroid Build Coastguard Worker	recovery   map[string][]srcBaseFileInstallBaseFileTuple
40*333d2b36SAndroid Build Coastguard Worker}
41*333d2b36SAndroid Build Coastguard Worker
42*333d2b36SAndroid Build Coastguard Workerfunc newPrebuiltSrcGroupByInstallPartition() *prebuiltSrcGroupByInstallPartition {
43*333d2b36SAndroid Build Coastguard Worker	return &prebuiltSrcGroupByInstallPartition{
44*333d2b36SAndroid Build Coastguard Worker		system:     map[string][]srcBaseFileInstallBaseFileTuple{},
45*333d2b36SAndroid Build Coastguard Worker		system_ext: map[string][]srcBaseFileInstallBaseFileTuple{},
46*333d2b36SAndroid Build Coastguard Worker		product:    map[string][]srcBaseFileInstallBaseFileTuple{},
47*333d2b36SAndroid Build Coastguard Worker		vendor:     map[string][]srcBaseFileInstallBaseFileTuple{},
48*333d2b36SAndroid Build Coastguard Worker		recovery:   map[string][]srcBaseFileInstallBaseFileTuple{},
49*333d2b36SAndroid Build Coastguard Worker	}
50*333d2b36SAndroid Build Coastguard Worker}
51*333d2b36SAndroid Build Coastguard Worker
52*333d2b36SAndroid Build Coastguard Workerfunc isSubdirectory(parent, child string) bool {
53*333d2b36SAndroid Build Coastguard Worker	rel, err := filepath.Rel(parent, child)
54*333d2b36SAndroid Build Coastguard Worker	if err != nil {
55*333d2b36SAndroid Build Coastguard Worker		return false
56*333d2b36SAndroid Build Coastguard Worker	}
57*333d2b36SAndroid Build Coastguard Worker	return !strings.HasPrefix(rel, "..")
58*333d2b36SAndroid Build Coastguard Worker}
59*333d2b36SAndroid Build Coastguard Worker
60*333d2b36SAndroid Build Coastguard Workerfunc appendIfCorrectInstallPartition(partitionToInstallPathList []partitionToInstallPath, destPath, srcPath string, srcGroup *prebuiltSrcGroupByInstallPartition) {
61*333d2b36SAndroid Build Coastguard Worker	for _, part := range partitionToInstallPathList {
62*333d2b36SAndroid Build Coastguard Worker		partition := part.name
63*333d2b36SAndroid Build Coastguard Worker		installPath := part.installPath
64*333d2b36SAndroid Build Coastguard Worker
65*333d2b36SAndroid Build Coastguard Worker		if isSubdirectory(installPath, destPath) {
66*333d2b36SAndroid Build Coastguard Worker			relativeInstallPath, _ := filepath.Rel(installPath, destPath)
67*333d2b36SAndroid Build Coastguard Worker			relativeInstallDir := filepath.Dir(relativeInstallPath)
68*333d2b36SAndroid Build Coastguard Worker			var srcMap map[string][]srcBaseFileInstallBaseFileTuple
69*333d2b36SAndroid Build Coastguard Worker			switch partition {
70*333d2b36SAndroid Build Coastguard Worker			case "system":
71*333d2b36SAndroid Build Coastguard Worker				srcMap = srcGroup.system
72*333d2b36SAndroid Build Coastguard Worker			case "system_ext":
73*333d2b36SAndroid Build Coastguard Worker				srcMap = srcGroup.system_ext
74*333d2b36SAndroid Build Coastguard Worker			case "product":
75*333d2b36SAndroid Build Coastguard Worker				srcMap = srcGroup.product
76*333d2b36SAndroid Build Coastguard Worker			case "vendor":
77*333d2b36SAndroid Build Coastguard Worker				srcMap = srcGroup.vendor
78*333d2b36SAndroid Build Coastguard Worker			case "recovery":
79*333d2b36SAndroid Build Coastguard Worker				srcMap = srcGroup.recovery
80*333d2b36SAndroid Build Coastguard Worker			}
81*333d2b36SAndroid Build Coastguard Worker			if srcMap != nil {
82*333d2b36SAndroid Build Coastguard Worker				srcMap[relativeInstallDir] = append(srcMap[relativeInstallDir], srcBaseFileInstallBaseFileTuple{
83*333d2b36SAndroid Build Coastguard Worker					srcBaseFile:     filepath.Base(srcPath),
84*333d2b36SAndroid Build Coastguard Worker					installBaseFile: filepath.Base(destPath),
85*333d2b36SAndroid Build Coastguard Worker				})
86*333d2b36SAndroid Build Coastguard Worker			}
87*333d2b36SAndroid Build Coastguard Worker			return
88*333d2b36SAndroid Build Coastguard Worker		}
89*333d2b36SAndroid Build Coastguard Worker	}
90*333d2b36SAndroid Build Coastguard Worker}
91*333d2b36SAndroid Build Coastguard Worker
92*333d2b36SAndroid Build Coastguard Worker// Create a map of source files to the list of destination files from PRODUCT_COPY_FILES entries.
93*333d2b36SAndroid Build Coastguard Worker// Note that the value of the map is a list of string, given that a single source file can be
94*333d2b36SAndroid Build Coastguard Worker// copied to multiple files.
95*333d2b36SAndroid Build Coastguard Worker// This function also checks the existence of the source files, and validates that there is no
96*333d2b36SAndroid Build Coastguard Worker// multiple source files copying to the same dest file.
97*333d2b36SAndroid Build Coastguard Workerfunc uniqueExistingProductCopyFileMap(ctx android.LoadHookContext) map[string][]string {
98*333d2b36SAndroid Build Coastguard Worker	seen := make(map[string]bool)
99*333d2b36SAndroid Build Coastguard Worker	filtered := make(map[string][]string)
100*333d2b36SAndroid Build Coastguard Worker
101*333d2b36SAndroid Build Coastguard Worker	for _, copyFilePair := range ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.ProductCopyFiles {
102*333d2b36SAndroid Build Coastguard Worker		srcDestList := strings.Split(copyFilePair, ":")
103*333d2b36SAndroid Build Coastguard Worker		if len(srcDestList) < 2 {
104*333d2b36SAndroid Build Coastguard Worker			ctx.ModuleErrorf("PRODUCT_COPY_FILES must follow the format \"src:dest\", got: %s", copyFilePair)
105*333d2b36SAndroid Build Coastguard Worker		}
106*333d2b36SAndroid Build Coastguard Worker		src, dest := srcDestList[0], srcDestList[1]
107*333d2b36SAndroid Build Coastguard Worker
108*333d2b36SAndroid Build Coastguard Worker		// Some downstream branches use absolute path as entries in PRODUCT_COPY_FILES.
109*333d2b36SAndroid Build Coastguard Worker		// Convert them to relative path from top and check if they do not escape the tree root.
110*333d2b36SAndroid Build Coastguard Worker		relSrc := android.ToRelativeSourcePath(ctx, src)
111*333d2b36SAndroid Build Coastguard Worker
112*333d2b36SAndroid Build Coastguard Worker		if _, ok := seen[dest]; !ok {
113*333d2b36SAndroid Build Coastguard Worker			if optionalPath := android.ExistentPathForSource(ctx, relSrc); optionalPath.Valid() {
114*333d2b36SAndroid Build Coastguard Worker				seen[dest] = true
115*333d2b36SAndroid Build Coastguard Worker				filtered[relSrc] = append(filtered[relSrc], dest)
116*333d2b36SAndroid Build Coastguard Worker			}
117*333d2b36SAndroid Build Coastguard Worker		}
118*333d2b36SAndroid Build Coastguard Worker	}
119*333d2b36SAndroid Build Coastguard Worker
120*333d2b36SAndroid Build Coastguard Worker	return filtered
121*333d2b36SAndroid Build Coastguard Worker}
122*333d2b36SAndroid Build Coastguard Worker
123*333d2b36SAndroid Build Coastguard Workertype partitionToInstallPath struct {
124*333d2b36SAndroid Build Coastguard Worker	name        string
125*333d2b36SAndroid Build Coastguard Worker	installPath string
126*333d2b36SAndroid Build Coastguard Worker}
127*333d2b36SAndroid Build Coastguard Worker
128*333d2b36SAndroid Build Coastguard Workerfunc processProductCopyFiles(ctx android.LoadHookContext) map[string]*prebuiltSrcGroupByInstallPartition {
129*333d2b36SAndroid Build Coastguard Worker	// Filter out duplicate dest entries and non existing src entries
130*333d2b36SAndroid Build Coastguard Worker	productCopyFileMap := uniqueExistingProductCopyFileMap(ctx)
131*333d2b36SAndroid Build Coastguard Worker
132*333d2b36SAndroid Build Coastguard Worker	// System is intentionally added at the last to consider the scenarios where
133*333d2b36SAndroid Build Coastguard Worker	// non-system partitions are installed as part of the system partition
134*333d2b36SAndroid Build Coastguard Worker	partitionToInstallPathList := []partitionToInstallPath{
135*333d2b36SAndroid Build Coastguard Worker		{name: "recovery", installPath: "recovery/root"},
136*333d2b36SAndroid Build Coastguard Worker		{name: "vendor", installPath: ctx.DeviceConfig().VendorPath()},
137*333d2b36SAndroid Build Coastguard Worker		{name: "product", installPath: ctx.DeviceConfig().ProductPath()},
138*333d2b36SAndroid Build Coastguard Worker		{name: "system_ext", installPath: ctx.DeviceConfig().SystemExtPath()},
139*333d2b36SAndroid Build Coastguard Worker		{name: "system", installPath: "system"},
140*333d2b36SAndroid Build Coastguard Worker	}
141*333d2b36SAndroid Build Coastguard Worker
142*333d2b36SAndroid Build Coastguard Worker	groupedSources := map[string]*prebuiltSrcGroupByInstallPartition{}
143*333d2b36SAndroid Build Coastguard Worker	for _, src := range android.SortedKeys(productCopyFileMap) {
144*333d2b36SAndroid Build Coastguard Worker		destFiles := productCopyFileMap[src]
145*333d2b36SAndroid Build Coastguard Worker		srcFileDir := filepath.Dir(src)
146*333d2b36SAndroid Build Coastguard Worker		if _, ok := groupedSources[srcFileDir]; !ok {
147*333d2b36SAndroid Build Coastguard Worker			groupedSources[srcFileDir] = newPrebuiltSrcGroupByInstallPartition()
148*333d2b36SAndroid Build Coastguard Worker		}
149*333d2b36SAndroid Build Coastguard Worker		for _, dest := range destFiles {
150*333d2b36SAndroid Build Coastguard Worker			appendIfCorrectInstallPartition(partitionToInstallPathList, dest, filepath.Base(src), groupedSources[srcFileDir])
151*333d2b36SAndroid Build Coastguard Worker		}
152*333d2b36SAndroid Build Coastguard Worker	}
153*333d2b36SAndroid Build Coastguard Worker
154*333d2b36SAndroid Build Coastguard Worker	return groupedSources
155*333d2b36SAndroid Build Coastguard Worker}
156*333d2b36SAndroid Build Coastguard Worker
157*333d2b36SAndroid Build Coastguard Workertype prebuiltModuleProperties struct {
158*333d2b36SAndroid Build Coastguard Worker	Name *string
159*333d2b36SAndroid Build Coastguard Worker
160*333d2b36SAndroid Build Coastguard Worker	Soc_specific        *bool
161*333d2b36SAndroid Build Coastguard Worker	Product_specific    *bool
162*333d2b36SAndroid Build Coastguard Worker	System_ext_specific *bool
163*333d2b36SAndroid Build Coastguard Worker	Recovery            *bool
164*333d2b36SAndroid Build Coastguard Worker	Ramdisk             *bool
165*333d2b36SAndroid Build Coastguard Worker
166*333d2b36SAndroid Build Coastguard Worker	Srcs []string
167*333d2b36SAndroid Build Coastguard Worker	Dsts []string
168*333d2b36SAndroid Build Coastguard Worker
169*333d2b36SAndroid Build Coastguard Worker	No_full_install *bool
170*333d2b36SAndroid Build Coastguard Worker
171*333d2b36SAndroid Build Coastguard Worker	NamespaceExportedToMake bool
172*333d2b36SAndroid Build Coastguard Worker
173*333d2b36SAndroid Build Coastguard Worker	Visibility []string
174*333d2b36SAndroid Build Coastguard Worker}
175*333d2b36SAndroid Build Coastguard Worker
176*333d2b36SAndroid Build Coastguard Worker// Split relative_install_path to a separate struct, because it is not supported for every
177*333d2b36SAndroid Build Coastguard Worker// modules listed in [etcInstallPathToFactoryMap]
178*333d2b36SAndroid Build Coastguard Workertype prebuiltSubdirProperties struct {
179*333d2b36SAndroid Build Coastguard Worker	// If the base file name of the src and dst all match, dsts property does not need to be
180*333d2b36SAndroid Build Coastguard Worker	// set, and only relative_install_path can be set.
181*333d2b36SAndroid Build Coastguard Worker	Relative_install_path *string
182*333d2b36SAndroid Build Coastguard Worker}
183*333d2b36SAndroid Build Coastguard Worker
184*333d2b36SAndroid Build Coastguard Worker// Split install_in_root to a separate struct as it is part of rootProperties instead of
185*333d2b36SAndroid Build Coastguard Worker// properties
186*333d2b36SAndroid Build Coastguard Workertype prebuiltInstallInRootProperties struct {
187*333d2b36SAndroid Build Coastguard Worker	Install_in_root *bool
188*333d2b36SAndroid Build Coastguard Worker}
189*333d2b36SAndroid Build Coastguard Worker
190*333d2b36SAndroid Build Coastguard Workervar (
191*333d2b36SAndroid Build Coastguard Worker	etcInstallPathToFactoryList = map[string]android.ModuleFactory{
192*333d2b36SAndroid Build Coastguard Worker		"":                    etc.PrebuiltRootFactory,
193*333d2b36SAndroid Build Coastguard Worker		"avb":                 etc.PrebuiltAvbFactory,
194*333d2b36SAndroid Build Coastguard Worker		"bin":                 etc.PrebuiltBinaryFactory,
195*333d2b36SAndroid Build Coastguard Worker		"bt_firmware":         etc.PrebuiltBtFirmwareFactory,
196*333d2b36SAndroid Build Coastguard Worker		"cacerts":             etc.PrebuiltEtcCaCertsFactory,
197*333d2b36SAndroid Build Coastguard Worker		"dsp":                 etc.PrebuiltDSPFactory,
198*333d2b36SAndroid Build Coastguard Worker		"etc":                 etc.PrebuiltEtcFactory,
199*333d2b36SAndroid Build Coastguard Worker		"etc/dsp":             etc.PrebuiltDSPFactory,
200*333d2b36SAndroid Build Coastguard Worker		"etc/firmware":        etc.PrebuiltFirmwareFactory,
201*333d2b36SAndroid Build Coastguard Worker		"firmware":            etc.PrebuiltFirmwareFactory,
202*333d2b36SAndroid Build Coastguard Worker		"first_stage_ramdisk": etc.PrebuiltFirstStageRamdiskFactory,
203*333d2b36SAndroid Build Coastguard Worker		"fonts":               etc.PrebuiltFontFactory,
204*333d2b36SAndroid Build Coastguard Worker		"framework":           etc.PrebuiltFrameworkFactory,
205*333d2b36SAndroid Build Coastguard Worker		"lib":                 etc.PrebuiltRenderScriptBitcodeFactory,
206*333d2b36SAndroid Build Coastguard Worker		"lib64":               etc.PrebuiltRenderScriptBitcodeFactory,
207*333d2b36SAndroid Build Coastguard Worker		"lib/rfsa":            etc.PrebuiltRFSAFactory,
208*333d2b36SAndroid Build Coastguard Worker		"media":               etc.PrebuiltMediaFactory,
209*333d2b36SAndroid Build Coastguard Worker		"odm":                 etc.PrebuiltOdmFactory,
210*333d2b36SAndroid Build Coastguard Worker		"optee":               etc.PrebuiltOpteeFactory,
211*333d2b36SAndroid Build Coastguard Worker		"overlay":             etc.PrebuiltOverlayFactory,
212*333d2b36SAndroid Build Coastguard Worker		"priv-app":            etc.PrebuiltPrivAppFactory,
213*333d2b36SAndroid Build Coastguard Worker		"sbin":                etc.PrebuiltSbinFactory,
214*333d2b36SAndroid Build Coastguard Worker		"system":              etc.PrebuiltSystemFactory,
215*333d2b36SAndroid Build Coastguard Worker		"res":                 etc.PrebuiltResFactory,
216*333d2b36SAndroid Build Coastguard Worker		"rfs":                 etc.PrebuiltRfsFactory,
217*333d2b36SAndroid Build Coastguard Worker		"tts":                 etc.PrebuiltVoicepackFactory,
218*333d2b36SAndroid Build Coastguard Worker		"tvconfig":            etc.PrebuiltTvConfigFactory,
219*333d2b36SAndroid Build Coastguard Worker		"tvservice":           etc.PrebuiltTvServiceFactory,
220*333d2b36SAndroid Build Coastguard Worker		"usr/share":           etc.PrebuiltUserShareFactory,
221*333d2b36SAndroid Build Coastguard Worker		"usr/hyphen-data":     etc.PrebuiltUserHyphenDataFactory,
222*333d2b36SAndroid Build Coastguard Worker		"usr/keylayout":       etc.PrebuiltUserKeyLayoutFactory,
223*333d2b36SAndroid Build Coastguard Worker		"usr/keychars":        etc.PrebuiltUserKeyCharsFactory,
224*333d2b36SAndroid Build Coastguard Worker		"usr/srec":            etc.PrebuiltUserSrecFactory,
225*333d2b36SAndroid Build Coastguard Worker		"usr/idc":             etc.PrebuiltUserIdcFactory,
226*333d2b36SAndroid Build Coastguard Worker		"vendor":              etc.PrebuiltVendorFactory,
227*333d2b36SAndroid Build Coastguard Worker		"vendor_dlkm":         etc.PrebuiltVendorDlkmFactory,
228*333d2b36SAndroid Build Coastguard Worker		"wallpaper":           etc.PrebuiltWallpaperFactory,
229*333d2b36SAndroid Build Coastguard Worker		"wlc_upt":             etc.PrebuiltWlcUptFactory,
230*333d2b36SAndroid Build Coastguard Worker	}
231*333d2b36SAndroid Build Coastguard Worker)
232*333d2b36SAndroid Build Coastguard Worker
233*333d2b36SAndroid Build Coastguard Workerfunc generatedPrebuiltEtcModuleName(partition, srcDir, destDir string, count int) string {
234*333d2b36SAndroid Build Coastguard Worker	// generated module name follows the pattern:
235*333d2b36SAndroid Build Coastguard Worker	// <install partition>-<src file path>-<relative install path from partition root>-<number>
236*333d2b36SAndroid Build Coastguard Worker	// Note that all path separators are replaced with "_" in the name
237*333d2b36SAndroid Build Coastguard Worker	moduleName := partition
238*333d2b36SAndroid Build Coastguard Worker	if !android.InList(srcDir, []string{"", "."}) {
239*333d2b36SAndroid Build Coastguard Worker		moduleName += fmt.Sprintf("-%s", strings.ReplaceAll(srcDir, string(filepath.Separator), "_"))
240*333d2b36SAndroid Build Coastguard Worker	}
241*333d2b36SAndroid Build Coastguard Worker	if !android.InList(destDir, []string{"", "."}) {
242*333d2b36SAndroid Build Coastguard Worker		moduleName += fmt.Sprintf("-%s", strings.ReplaceAll(destDir, string(filepath.Separator), "_"))
243*333d2b36SAndroid Build Coastguard Worker	}
244*333d2b36SAndroid Build Coastguard Worker	moduleName += fmt.Sprintf("-%d", count)
245*333d2b36SAndroid Build Coastguard Worker
246*333d2b36SAndroid Build Coastguard Worker	return moduleName
247*333d2b36SAndroid Build Coastguard Worker}
248*333d2b36SAndroid Build Coastguard Worker
249*333d2b36SAndroid Build Coastguard Workerfunc groupDestFilesBySrc(destFiles []srcBaseFileInstallBaseFileTuple) (ret map[string][]srcBaseFileInstallBaseFileTuple, maxLen int) {
250*333d2b36SAndroid Build Coastguard Worker	ret = map[string][]srcBaseFileInstallBaseFileTuple{}
251*333d2b36SAndroid Build Coastguard Worker	maxLen = 0
252*333d2b36SAndroid Build Coastguard Worker	for _, tuple := range destFiles {
253*333d2b36SAndroid Build Coastguard Worker		if _, ok := ret[tuple.srcBaseFile]; !ok {
254*333d2b36SAndroid Build Coastguard Worker			ret[tuple.srcBaseFile] = []srcBaseFileInstallBaseFileTuple{}
255*333d2b36SAndroid Build Coastguard Worker		}
256*333d2b36SAndroid Build Coastguard Worker		ret[tuple.srcBaseFile] = append(ret[tuple.srcBaseFile], tuple)
257*333d2b36SAndroid Build Coastguard Worker		maxLen = max(maxLen, len(ret[tuple.srcBaseFile]))
258*333d2b36SAndroid Build Coastguard Worker	}
259*333d2b36SAndroid Build Coastguard Worker	return ret, maxLen
260*333d2b36SAndroid Build Coastguard Worker}
261*333d2b36SAndroid Build Coastguard Worker
262*333d2b36SAndroid Build Coastguard Workerfunc prebuiltEtcModuleProps(ctx android.LoadHookContext, moduleName, partition, destDir string) prebuiltModuleProperties {
263*333d2b36SAndroid Build Coastguard Worker	moduleProps := prebuiltModuleProperties{}
264*333d2b36SAndroid Build Coastguard Worker	moduleProps.Name = proptools.StringPtr(moduleName)
265*333d2b36SAndroid Build Coastguard Worker
266*333d2b36SAndroid Build Coastguard Worker	// Set partition specific properties
267*333d2b36SAndroid Build Coastguard Worker	switch partition {
268*333d2b36SAndroid Build Coastguard Worker	case "system_ext":
269*333d2b36SAndroid Build Coastguard Worker		moduleProps.System_ext_specific = proptools.BoolPtr(true)
270*333d2b36SAndroid Build Coastguard Worker	case "product":
271*333d2b36SAndroid Build Coastguard Worker		moduleProps.Product_specific = proptools.BoolPtr(true)
272*333d2b36SAndroid Build Coastguard Worker	case "vendor":
273*333d2b36SAndroid Build Coastguard Worker		moduleProps.Soc_specific = proptools.BoolPtr(true)
274*333d2b36SAndroid Build Coastguard Worker	case "recovery":
275*333d2b36SAndroid Build Coastguard Worker		// To match the logic in modulePartition() in android/paths.go
276*333d2b36SAndroid Build Coastguard Worker		if ctx.DeviceConfig().BoardUsesRecoveryAsBoot() && strings.HasPrefix(destDir, "first_stage_ramdisk") {
277*333d2b36SAndroid Build Coastguard Worker			moduleProps.Ramdisk = proptools.BoolPtr(true)
278*333d2b36SAndroid Build Coastguard Worker		} else {
279*333d2b36SAndroid Build Coastguard Worker			moduleProps.Recovery = proptools.BoolPtr(true)
280*333d2b36SAndroid Build Coastguard Worker		}
281*333d2b36SAndroid Build Coastguard Worker	}
282*333d2b36SAndroid Build Coastguard Worker
283*333d2b36SAndroid Build Coastguard Worker	moduleProps.No_full_install = proptools.BoolPtr(true)
284*333d2b36SAndroid Build Coastguard Worker	moduleProps.NamespaceExportedToMake = true
285*333d2b36SAndroid Build Coastguard Worker	moduleProps.Visibility = []string{"//visibility:public"}
286*333d2b36SAndroid Build Coastguard Worker
287*333d2b36SAndroid Build Coastguard Worker	return moduleProps
288*333d2b36SAndroid Build Coastguard Worker}
289*333d2b36SAndroid Build Coastguard Worker
290*333d2b36SAndroid Build Coastguard Workerfunc createPrebuiltEtcModulesInDirectory(ctx android.LoadHookContext, partition, srcDir, destDir string, destFiles []srcBaseFileInstallBaseFileTuple) (moduleNames []string) {
291*333d2b36SAndroid Build Coastguard Worker	groupedDestFiles, maxLen := groupDestFilesBySrc(destFiles)
292*333d2b36SAndroid Build Coastguard Worker
293*333d2b36SAndroid Build Coastguard Worker	// Find out the most appropriate module type to generate
294*333d2b36SAndroid Build Coastguard Worker	var etcInstallPathKey string
295*333d2b36SAndroid Build Coastguard Worker	for _, etcInstallPath := range android.SortedKeys(etcInstallPathToFactoryList) {
296*333d2b36SAndroid Build Coastguard Worker		// Do not break when found but iterate until the end to find a module with more
297*333d2b36SAndroid Build Coastguard Worker		// specific install path
298*333d2b36SAndroid Build Coastguard Worker		if strings.HasPrefix(destDir, etcInstallPath) {
299*333d2b36SAndroid Build Coastguard Worker			etcInstallPathKey = etcInstallPath
300*333d2b36SAndroid Build Coastguard Worker		}
301*333d2b36SAndroid Build Coastguard Worker	}
302*333d2b36SAndroid Build Coastguard Worker	relDestDirFromInstallDirBase, _ := filepath.Rel(etcInstallPathKey, destDir)
303*333d2b36SAndroid Build Coastguard Worker
304*333d2b36SAndroid Build Coastguard Worker	for fileIndex := range maxLen {
305*333d2b36SAndroid Build Coastguard Worker		srcTuple := []srcBaseFileInstallBaseFileTuple{}
306*333d2b36SAndroid Build Coastguard Worker		for _, srcFile := range android.SortedKeys(groupedDestFiles) {
307*333d2b36SAndroid Build Coastguard Worker			groupedDestFile := groupedDestFiles[srcFile]
308*333d2b36SAndroid Build Coastguard Worker			if len(groupedDestFile) > fileIndex {
309*333d2b36SAndroid Build Coastguard Worker				srcTuple = append(srcTuple, groupedDestFile[fileIndex])
310*333d2b36SAndroid Build Coastguard Worker			}
311*333d2b36SAndroid Build Coastguard Worker		}
312*333d2b36SAndroid Build Coastguard Worker
313*333d2b36SAndroid Build Coastguard Worker		moduleName := generatedPrebuiltEtcModuleName(partition, srcDir, destDir, fileIndex)
314*333d2b36SAndroid Build Coastguard Worker		moduleProps := prebuiltEtcModuleProps(ctx, moduleName, partition, destDir)
315*333d2b36SAndroid Build Coastguard Worker		modulePropsPtr := &moduleProps
316*333d2b36SAndroid Build Coastguard Worker		propsList := []interface{}{modulePropsPtr}
317*333d2b36SAndroid Build Coastguard Worker
318*333d2b36SAndroid Build Coastguard Worker		allCopyFileNamesUnchanged := true
319*333d2b36SAndroid Build Coastguard Worker		var srcBaseFiles, installBaseFiles []string
320*333d2b36SAndroid Build Coastguard Worker		for _, tuple := range srcTuple {
321*333d2b36SAndroid Build Coastguard Worker			if tuple.srcBaseFile != tuple.installBaseFile {
322*333d2b36SAndroid Build Coastguard Worker				allCopyFileNamesUnchanged = false
323*333d2b36SAndroid Build Coastguard Worker			}
324*333d2b36SAndroid Build Coastguard Worker			srcBaseFiles = append(srcBaseFiles, tuple.srcBaseFile)
325*333d2b36SAndroid Build Coastguard Worker			installBaseFiles = append(installBaseFiles, tuple.installBaseFile)
326*333d2b36SAndroid Build Coastguard Worker		}
327*333d2b36SAndroid Build Coastguard Worker
328*333d2b36SAndroid Build Coastguard Worker		// Recovery partition-installed modules are installed to `recovery/root/system` by
329*333d2b36SAndroid Build Coastguard Worker		// default (See modulePartition() in android/paths.go). If the destination file
330*333d2b36SAndroid Build Coastguard Worker		// directory is not `recovery/root/system/...`, it should set install_in_root to true
331*333d2b36SAndroid Build Coastguard Worker		// to prevent being installed in `recovery/root/system`.
332*333d2b36SAndroid Build Coastguard Worker		if partition == "recovery" && !strings.HasPrefix(destDir, "system") {
333*333d2b36SAndroid Build Coastguard Worker			propsList = append(propsList, &prebuiltInstallInRootProperties{
334*333d2b36SAndroid Build Coastguard Worker				Install_in_root: proptools.BoolPtr(true),
335*333d2b36SAndroid Build Coastguard Worker			})
336*333d2b36SAndroid Build Coastguard Worker		}
337*333d2b36SAndroid Build Coastguard Worker
338*333d2b36SAndroid Build Coastguard Worker		// Set appropriate srcs, dsts, and releative_install_path based on
339*333d2b36SAndroid Build Coastguard Worker		// the source and install file names
340*333d2b36SAndroid Build Coastguard Worker		if allCopyFileNamesUnchanged {
341*333d2b36SAndroid Build Coastguard Worker			modulePropsPtr.Srcs = srcBaseFiles
342*333d2b36SAndroid Build Coastguard Worker
343*333d2b36SAndroid Build Coastguard Worker			// Specify relative_install_path if it is not installed in the root directory of the
344*333d2b36SAndroid Build Coastguard Worker			// partition
345*333d2b36SAndroid Build Coastguard Worker			if !android.InList(relDestDirFromInstallDirBase, []string{"", "."}) {
346*333d2b36SAndroid Build Coastguard Worker				propsList = append(propsList, &prebuiltSubdirProperties{
347*333d2b36SAndroid Build Coastguard Worker					Relative_install_path: proptools.StringPtr(relDestDirFromInstallDirBase),
348*333d2b36SAndroid Build Coastguard Worker				})
349*333d2b36SAndroid Build Coastguard Worker			}
350*333d2b36SAndroid Build Coastguard Worker		} else {
351*333d2b36SAndroid Build Coastguard Worker			modulePropsPtr.Srcs = srcBaseFiles
352*333d2b36SAndroid Build Coastguard Worker			dsts := []string{}
353*333d2b36SAndroid Build Coastguard Worker			for _, installBaseFile := range installBaseFiles {
354*333d2b36SAndroid Build Coastguard Worker				dsts = append(dsts, filepath.Join(relDestDirFromInstallDirBase, installBaseFile))
355*333d2b36SAndroid Build Coastguard Worker			}
356*333d2b36SAndroid Build Coastguard Worker			modulePropsPtr.Dsts = dsts
357*333d2b36SAndroid Build Coastguard Worker		}
358*333d2b36SAndroid Build Coastguard Worker
359*333d2b36SAndroid Build Coastguard Worker		ctx.CreateModuleInDirectory(etcInstallPathToFactoryList[etcInstallPathKey], srcDir, propsList...)
360*333d2b36SAndroid Build Coastguard Worker		moduleNames = append(moduleNames, moduleName)
361*333d2b36SAndroid Build Coastguard Worker	}
362*333d2b36SAndroid Build Coastguard Worker
363*333d2b36SAndroid Build Coastguard Worker	return moduleNames
364*333d2b36SAndroid Build Coastguard Worker}
365*333d2b36SAndroid Build Coastguard Worker
366*333d2b36SAndroid Build Coastguard Workerfunc createPrebuiltEtcModulesForPartition(ctx android.LoadHookContext, partition, srcDir string, destDirFilesMap map[string][]srcBaseFileInstallBaseFileTuple) (ret []string) {
367*333d2b36SAndroid Build Coastguard Worker	for _, destDir := range android.SortedKeys(destDirFilesMap) {
368*333d2b36SAndroid Build Coastguard Worker		ret = append(ret, createPrebuiltEtcModulesInDirectory(ctx, partition, srcDir, destDir, destDirFilesMap[destDir])...)
369*333d2b36SAndroid Build Coastguard Worker	}
370*333d2b36SAndroid Build Coastguard Worker	return ret
371*333d2b36SAndroid Build Coastguard Worker}
372*333d2b36SAndroid Build Coastguard Worker
373*333d2b36SAndroid Build Coastguard Worker// Creates prebuilt_* modules based on the install paths and returns the list of generated
374*333d2b36SAndroid Build Coastguard Worker// module names
375*333d2b36SAndroid Build Coastguard Workerfunc createPrebuiltEtcModules(ctx android.LoadHookContext) (ret []string) {
376*333d2b36SAndroid Build Coastguard Worker	groupedSources := processProductCopyFiles(ctx)
377*333d2b36SAndroid Build Coastguard Worker	for _, srcDir := range android.SortedKeys(groupedSources) {
378*333d2b36SAndroid Build Coastguard Worker		groupedSource := groupedSources[srcDir]
379*333d2b36SAndroid Build Coastguard Worker		ret = append(ret, createPrebuiltEtcModulesForPartition(ctx, "system", srcDir, groupedSource.system)...)
380*333d2b36SAndroid Build Coastguard Worker		ret = append(ret, createPrebuiltEtcModulesForPartition(ctx, "system_ext", srcDir, groupedSource.system_ext)...)
381*333d2b36SAndroid Build Coastguard Worker		ret = append(ret, createPrebuiltEtcModulesForPartition(ctx, "product", srcDir, groupedSource.product)...)
382*333d2b36SAndroid Build Coastguard Worker		ret = append(ret, createPrebuiltEtcModulesForPartition(ctx, "vendor", srcDir, groupedSource.vendor)...)
383*333d2b36SAndroid Build Coastguard Worker		ret = append(ret, createPrebuiltEtcModulesForPartition(ctx, "recovery", srcDir, groupedSource.recovery)...)
384*333d2b36SAndroid Build Coastguard Worker	}
385*333d2b36SAndroid Build Coastguard Worker
386*333d2b36SAndroid Build Coastguard Worker	return ret
387*333d2b36SAndroid Build Coastguard Worker}
388*333d2b36SAndroid Build Coastguard Worker
389*333d2b36SAndroid Build Coastguard Workerfunc createAvbpubkeyModule(ctx android.LoadHookContext) bool {
390*333d2b36SAndroid Build Coastguard Worker	avbKeyPath := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.BoardAvbKeyPath
391*333d2b36SAndroid Build Coastguard Worker	if avbKeyPath == "" {
392*333d2b36SAndroid Build Coastguard Worker		return false
393*333d2b36SAndroid Build Coastguard Worker	}
394*333d2b36SAndroid Build Coastguard Worker	ctx.CreateModuleInDirectory(
395*333d2b36SAndroid Build Coastguard Worker		etc.AvbpubkeyModuleFactory,
396*333d2b36SAndroid Build Coastguard Worker		".",
397*333d2b36SAndroid Build Coastguard Worker		&struct {
398*333d2b36SAndroid Build Coastguard Worker			Name             *string
399*333d2b36SAndroid Build Coastguard Worker			Product_specific *bool
400*333d2b36SAndroid Build Coastguard Worker			Private_key      *string
401*333d2b36SAndroid Build Coastguard Worker			No_full_install  *bool
402*333d2b36SAndroid Build Coastguard Worker			Visibility       []string
403*333d2b36SAndroid Build Coastguard Worker		}{
404*333d2b36SAndroid Build Coastguard Worker			Name:             proptools.StringPtr("system_other_avbpubkey"),
405*333d2b36SAndroid Build Coastguard Worker			Product_specific: proptools.BoolPtr(true),
406*333d2b36SAndroid Build Coastguard Worker			Private_key:      proptools.StringPtr(avbKeyPath),
407*333d2b36SAndroid Build Coastguard Worker			No_full_install:  proptools.BoolPtr(true),
408*333d2b36SAndroid Build Coastguard Worker			Visibility:       []string{"//visibility:public"},
409*333d2b36SAndroid Build Coastguard Worker		},
410*333d2b36SAndroid Build Coastguard Worker	)
411*333d2b36SAndroid Build Coastguard Worker	return true
412*333d2b36SAndroid Build Coastguard Worker}
413