• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package android
16
17// This is the primary location to write and read all configuration values and
18// product variables necessary for soong_build's operation.
19
20import (
21	"encoding/json"
22	"fmt"
23	"os"
24	"path/filepath"
25	"reflect"
26	"runtime"
27	"strconv"
28	"strings"
29	"sync"
30	"unicode"
31
32	"android/soong/shared"
33
34	"github.com/google/blueprint"
35	"github.com/google/blueprint/bootstrap"
36	"github.com/google/blueprint/pathtools"
37	"github.com/google/blueprint/proptools"
38
39	"android/soong/android/soongconfig"
40	"android/soong/remoteexec"
41)
42
43// Bool re-exports proptools.Bool for the android package.
44var Bool = proptools.Bool
45
46// String re-exports proptools.String for the android package.
47var String = proptools.String
48
49// StringDefault re-exports proptools.StringDefault for the android package.
50var StringDefault = proptools.StringDefault
51
52// FutureApiLevelInt is a placeholder constant for unreleased API levels.
53const FutureApiLevelInt = 10000
54
55// PrivateApiLevel represents the api level of SdkSpecPrivate (sdk_version: "")
56// This api_level exists to differentiate user-provided "" from "current" sdk_version
57// The differentiation is necessary to enable different validation rules for these two possible values.
58var PrivateApiLevel = ApiLevel{
59	value:     "current",             // The value is current since aidl expects `current` as the default (TestAidlFlagsWithMinSdkVersion)
60	number:    FutureApiLevelInt + 1, // This is used to differentiate it from FutureApiLevel
61	isPreview: true,
62}
63
64// FutureApiLevel represents unreleased API levels.
65var FutureApiLevel = ApiLevel{
66	value:     "current",
67	number:    FutureApiLevelInt,
68	isPreview: true,
69}
70
71// The product variables file name, containing product config from Kati.
72const productVariablesFileName = "soong.variables"
73
74// A Config object represents the entire build configuration for Android.
75type Config struct {
76	*config
77}
78
79type SoongBuildMode int
80
81type CmdArgs struct {
82	bootstrap.Args
83	RunGoTests     bool
84	OutDir         string
85	SoongOutDir    string
86	SoongVariables string
87	KatiSuffix     string
88
89	ModuleGraphFile   string
90	ModuleActionsFile string
91	DocFile           string
92
93	BuildFromSourceStub bool
94
95	EnsureAllowlistIntegrity bool
96}
97
98// Build modes that soong_build can run as.
99const (
100	// Don't use bazel at all during module analysis.
101	AnalysisNoBazel SoongBuildMode = iota
102
103	// Create a JSON representation of the module graph and exit.
104	GenerateModuleGraph
105
106	// Generate a documentation file for module type definitions and exit.
107	GenerateDocFile
108)
109
110const testKeyDir = "build/make/target/product/security"
111
112func (c Config) genericConfig() Config {
113	return Config{c.config.genericConfig}
114}
115
116// SoongOutDir returns the build output directory for the configuration.
117func (c Config) SoongOutDir() string {
118	return c.soongOutDir
119}
120
121// tempDir returns the path to out/soong/.temp, which is cleared at the beginning of every build.
122func (c Config) tempDir() string {
123	return shared.TempDirForOutDir(c.soongOutDir)
124}
125
126func (c Config) OutDir() string {
127	return c.outDir
128}
129
130func (c Config) RunGoTests() bool {
131	return c.runGoTests
132}
133
134func (c Config) DebugCompilation() bool {
135	return false // Never compile Go code in the main build for debugging
136}
137
138func (c Config) Subninjas() []string {
139	return []string{}
140}
141
142func (c Config) PrimaryBuilderInvocations() []bootstrap.PrimaryBuilderInvocation {
143	return []bootstrap.PrimaryBuilderInvocation{}
144}
145
146// RunningInsideUnitTest returns true if this code is being run as part of a Soong unit test.
147func (c Config) RunningInsideUnitTest() bool {
148	return c.config.TestProductVariables != nil
149}
150
151// DisableHiddenApiChecks returns true if hiddenapi checks have been disabled.
152// For 'eng' target variant hiddenapi checks are disabled by default for performance optimisation,
153// but can be enabled by setting environment variable ENABLE_HIDDENAPI_FLAGS=true.
154// For other target variants hiddenapi check are enabled by default but can be disabled by
155// setting environment variable UNSAFE_DISABLE_HIDDENAPI_FLAGS=true.
156// If both ENABLE_HIDDENAPI_FLAGS=true and UNSAFE_DISABLE_HIDDENAPI_FLAGS=true, then
157// ENABLE_HIDDENAPI_FLAGS=true will be triggered and hiddenapi checks will be considered enabled.
158func (c Config) DisableHiddenApiChecks() bool {
159	return !c.IsEnvTrue("ENABLE_HIDDENAPI_FLAGS") &&
160		(c.IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") ||
161			Bool(c.productVariables.Eng))
162}
163
164// DisableVerifyOverlaps returns true if verify_overlaps is skipped.
165// Mismatch in version of apexes and module SDK is required for mainline prebuilts to work in
166// trunk stable.
167// Thus, verify_overlaps is disabled when RELEASE_DEFAULT_MODULE_BUILD_FROM_SOURCE is set to false.
168// TODO(b/308174018): Re-enable verify_overlaps for both builr from source/mainline prebuilts.
169func (c Config) DisableVerifyOverlaps() bool {
170	if c.IsEnvFalse("DISABLE_VERIFY_OVERLAPS") && c.ReleaseDisableVerifyOverlaps() {
171		panic("The current release configuration does not support verify_overlaps. DISABLE_VERIFY_OVERLAPS cannot be set to false")
172	}
173	return c.IsEnvTrue("DISABLE_VERIFY_OVERLAPS") || c.ReleaseDisableVerifyOverlaps() || !c.ReleaseDefaultModuleBuildFromSource()
174}
175
176func (c Config) CoverageSuffix() string {
177	if v := c.IsEnvTrue("EMMA_INSTRUMENT"); v {
178		return "coverage."
179	}
180	return ""
181}
182
183// MaxPageSizeSupported returns the max page size supported by the device. This
184// value will define the ELF segment alignment for binaries (executables and
185// shared libraries).
186func (c Config) MaxPageSizeSupported() string {
187	return String(c.config.productVariables.DeviceMaxPageSizeSupported)
188}
189
190// NoBionicPageSizeMacro returns true when AOSP is page size agnostic.
191// This means that the bionic's macro PAGE_SIZE won't be defined.
192// Returns false when AOSP is NOT page size agnostic.
193// This means that bionic's macro PAGE_SIZE is defined.
194func (c Config) NoBionicPageSizeMacro() bool {
195	return Bool(c.config.productVariables.DeviceNoBionicPageSizeMacro)
196}
197
198// The release version passed to aconfig, derived from RELEASE_VERSION
199func (c Config) ReleaseVersion() string {
200	return c.config.productVariables.ReleaseVersion
201}
202
203// The aconfig value set passed to aconfig, derived from RELEASE_VERSION
204func (c Config) ReleaseAconfigValueSets() []string {
205	return c.config.productVariables.ReleaseAconfigValueSets
206}
207
208// If native modules should have symbols stripped by default. Default false, enabled for build tools
209func (c Config) StripByDefault() bool {
210	return proptools.Bool(c.config.productVariables.StripByDefault)
211}
212
213func (c Config) ReleaseAconfigExtraReleaseConfigs() []string {
214	result := []string{}
215	if val, ok := c.config.productVariables.BuildFlags["RELEASE_ACONFIG_EXTRA_RELEASE_CONFIGS"]; ok {
216		if len(val) > 0 {
217			// Remove any duplicates from the list.
218			found := make(map[string]bool)
219			for _, k := range strings.Split(val, " ") {
220				if !found[k] {
221					found[k] = true
222					result = append(result, k)
223				}
224			}
225		}
226	}
227	return result
228}
229
230func (c Config) ReleaseAconfigExtraReleaseConfigsValueSets() map[string][]string {
231	result := make(map[string][]string)
232	for _, rcName := range c.ReleaseAconfigExtraReleaseConfigs() {
233		if value, ok := c.config.productVariables.BuildFlags["RELEASE_ACONFIG_VALUE_SETS_"+rcName]; ok {
234			result[rcName] = strings.Split(value, " ")
235		}
236	}
237	return result
238}
239
240// The flag default permission value passed to aconfig
241// derived from RELEASE_ACONFIG_FLAG_DEFAULT_PERMISSION
242func (c Config) ReleaseAconfigFlagDefaultPermission() string {
243	return c.config.productVariables.ReleaseAconfigFlagDefaultPermission
244}
245
246// The flag indicating behavior for the tree wrt building modules or using prebuilts
247// derived from RELEASE_DEFAULT_MODULE_BUILD_FROM_SOURCE
248func (c Config) ReleaseDefaultModuleBuildFromSource() bool {
249	return c.config.productVariables.ReleaseDefaultModuleBuildFromSource == nil ||
250		Bool(c.config.productVariables.ReleaseDefaultModuleBuildFromSource)
251}
252
253func (c Config) ReleaseDefaultUpdatableModuleVersion() string {
254	if val, exists := c.GetBuildFlag("RELEASE_DEFAULT_UPDATABLE_MODULE_VERSION"); exists {
255		return val
256	}
257	panic("RELEASE_DEFAULT_UPDATABLE_MODULE_VERSION is missing from build flags.")
258}
259
260func (c Config) ReleaseDisableVerifyOverlaps() bool {
261	return c.config.productVariables.GetBuildFlagBool("RELEASE_DISABLE_VERIFY_OVERLAPS_CHECK")
262}
263
264// Enables flagged apis annotated with READ_WRITE aconfig flags to be included in the stubs
265// and hiddenapi flags so that they are accessible at runtime
266func (c Config) ReleaseExportRuntimeApis() bool {
267	return Bool(c.config.productVariables.ExportRuntimeApis)
268}
269
270// Enables ABI monitoring of NDK libraries
271func (c Config) ReleaseNdkAbiMonitored() bool {
272	return c.config.productVariables.GetBuildFlagBool("RELEASE_NDK_ABI_MONITORED")
273}
274
275// Enable read flag from new storage, for C/C++
276func (c Config) ReleaseReadFromNewStorageCc() bool {
277	return c.config.productVariables.GetBuildFlagBool("RELEASE_READ_FROM_NEW_STORAGE_CC")
278}
279
280func (c Config) ReleaseHiddenApiExportableStubs() bool {
281	return c.config.productVariables.GetBuildFlagBool("RELEASE_HIDDEN_API_EXPORTABLE_STUBS") ||
282		Bool(c.config.productVariables.HiddenapiExportableStubs)
283}
284
285// Enable read flag from new storage
286func (c Config) ReleaseReadFromNewStorage() bool {
287	return c.config.productVariables.GetBuildFlagBool("RELEASE_READ_FROM_NEW_STORAGE")
288}
289
290func (c Config) ReleaseCreateAconfigStorageFile() bool {
291	return c.config.productVariables.GetBuildFlagBool("RELEASE_CREATE_ACONFIG_STORAGE_FILE")
292}
293
294func (c Config) ReleaseUseSystemFeatureBuildFlags() bool {
295	return c.config.productVariables.GetBuildFlagBool("RELEASE_USE_SYSTEM_FEATURE_BUILD_FLAGS")
296}
297
298func (c Config) ReleaseFingerprintAconfigPackages() bool {
299	return c.config.productVariables.GetBuildFlagBool("RELEASE_FINGERPRINT_ACONFIG_PACKAGES")
300}
301
302func (c Config) ReleaseAconfigCheckApiLevel() bool {
303	return c.config.productVariables.GetBuildFlagBool("RELEASE_ACONFIG_CHECK_API_LEVEL")
304}
305
306// A DeviceConfig object represents the configuration for a particular device
307// being built. For now there will only be one of these, but in the future there
308// may be multiple devices being built.
309type DeviceConfig struct {
310	*deviceConfig
311}
312
313// VendorConfig represents the configuration for vendor-specific behavior.
314type VendorConfig soongconfig.SoongConfig
315
316// Definition of general build configuration for soong_build. Some of these
317// product configuration values are read from Kati-generated soong.variables.
318type config struct {
319	// Options configurable with soong.variables
320	productVariables ProductVariables
321
322	// Only available on configs created by TestConfig
323	TestProductVariables *ProductVariables
324
325	ProductVariablesFileName string
326
327	// BuildOS stores the OsType for the OS that the build is running on.
328	BuildOS OsType
329
330	// BuildArch stores the ArchType for the CPU that the build is running on.
331	BuildArch ArchType
332
333	Targets                  map[OsType][]Target
334	BuildOSTarget            Target // the Target for tools run on the build machine
335	BuildOSCommonTarget      Target // the Target for common (java) tools run on the build machine
336	AndroidCommonTarget      Target // the Target for common modules for the Android device
337	AndroidFirstDeviceTarget Target // the first Target for modules for the Android device
338
339	// Flags for Partial Compile, derived from SOONG_PARTIAL_COMPILE.
340	partialCompileFlags partialCompileFlags
341
342	// multilibConflicts for an ArchType is true if there is earlier configured
343	// device architecture with the same multilib value.
344	multilibConflicts map[ArchType]bool
345
346	deviceConfig *deviceConfig
347
348	outDir         string // The output directory (usually out/)
349	soongOutDir    string
350	moduleListFile string // the path to the file which lists blueprint files to parse.
351
352	runGoTests bool
353
354	env       map[string]string
355	envLock   sync.Mutex
356	envDeps   map[string]string
357	envFrozen bool
358
359	// Changes behavior based on whether Kati runs after soong_build, or if soong_build
360	// runs standalone.
361	katiEnabled bool
362	katiSuffix  string
363
364	captureBuild      bool // true for tests, saves build parameters for each module
365	ignoreEnvironment bool // true for tests, returns empty from all Getenv calls
366
367	fs         pathtools.FileSystem
368	mockBpList string
369
370	BuildMode SoongBuildMode
371
372	// If testAllowNonExistentPaths is true then PathForSource and PathForModuleSrc won't error
373	// in tests when a path doesn't exist.
374	TestAllowNonExistentPaths bool
375
376	// The list of files that when changed, must invalidate soong_build to
377	// regenerate build.ninja.
378	ninjaFileDepsSet sync.Map
379
380	*OncePer
381
382	// If buildFromSourceStub is true then the Java API stubs are
383	// built from the source Java files, not the signature text files.
384	buildFromSourceStub bool
385
386	// If ensureAllowlistIntegrity is true, then the presence of any allowlisted
387	// modules that aren't mixed-built for at least one variant will cause a build
388	// failure
389	ensureAllowlistIntegrity bool
390
391	// If isGeneric is true, this config is the generic config.
392	isGeneric bool
393
394	// InstallPath requires the device name.
395	// This is only for the installPath.
396	deviceNameToInstall *string
397
398	// Copy of this config struct but some product-specific variables are
399	// replaced with the generic configuration values.
400	genericConfig *config
401}
402
403type partialCompileFlags struct {
404	// Whether to use d8 instead of r8
405	Use_d8 bool
406
407	// Whether to disable stub validation.  This is slightly more surgical
408	// than DISABLE_STUB_VALIDATION, in that it only applies to partial
409	// compile builds.
410	Disable_stub_validation bool
411
412	// Whether to disable api lint.
413	Disable_api_lint bool
414
415	// Add others as needed.
416}
417
418// These are the flags when `SOONG_PARTIAL_COMPILE` is empty or not set.
419var defaultPartialCompileFlags = partialCompileFlags{}
420
421// These are the flags when `SOONG_PARTIAL_COMPILE=true`.
422var enabledPartialCompileFlags = partialCompileFlags{
423	Use_d8:                  true,
424	Disable_stub_validation: false,
425	Disable_api_lint:        false,
426}
427
428type deviceConfig struct {
429	config *config
430	OncePer
431}
432
433type jsonConfigurable interface {
434	SetDefaultConfig()
435}
436
437// Parse SOONG_PARTIAL_COMPILE.
438//
439// SOONG_PARTIAL_COMPILE determines which features are enabled or disabled in
440// rule generation.  Changing this environment variable causes reanalysis.
441//
442// SOONG_USE_PARTIAL_COMPILE determines whether or not we **use** PARTIAL_COMPILE.
443// Rule generation must support both cases, since changing it does not cause
444// reanalysis.
445//
446// The user-facing documentation shows:
447//
448// - empty or not set: "The current default state"
449// - "true" or "on": enable all stable partial compile features.
450// - "false" or "off": disable partial compile completely.
451//
452// What we actually allow is a comma separated list of tokens, whose first
453// character may be "+" (enable) or "-" (disable).  If neither is present, "+"
454// is assumed.  For example, "on,+use_d8" will enable partial compilation, and
455// additionally set the use_d8 flag (regardless of whether it is opt-in or
456// opt-out).
457//
458// To add a new feature to the list, add the field in the struct
459// `partialCompileFlags` above, and then add the name of the field in the
460// switch statement below.
461func (c *config) parsePartialCompileFlags(isEngBuild bool) (partialCompileFlags, error) {
462	if !isEngBuild {
463		return partialCompileFlags{}, nil
464	}
465	value := c.Getenv("SOONG_PARTIAL_COMPILE")
466	if value == "" {
467		return defaultPartialCompileFlags, nil
468	}
469
470	ret := defaultPartialCompileFlags
471	tokens := strings.Split(strings.ToLower(value), ",")
472	makeVal := func(state string, defaultValue bool) bool {
473		switch state {
474		case "":
475			return defaultValue
476		case "-":
477			return false
478		case "+":
479			return true
480		}
481		return false
482	}
483	for _, tok := range tokens {
484		var state string
485		if len(tok) == 0 {
486			continue
487		}
488		switch tok[0:1] {
489		case "":
490			// Ignore empty tokens.
491			continue
492		case "-", "+":
493			state = tok[0:1]
494			tok = tok[1:]
495		default:
496			// Treat `feature` as `+feature`.
497			state = "+"
498		}
499		switch tok {
500		case "all":
501			// Turn on **all** of the flags.
502			ret = partialCompileFlags{
503				Use_d8:                  true,
504				Disable_stub_validation: true,
505				Disable_api_lint:        true,
506			}
507		case "true":
508			ret = enabledPartialCompileFlags
509		case "false":
510			// Set everything to false.
511			ret = partialCompileFlags{}
512
513		case "api_lint", "enable_api_lint":
514			ret.Disable_api_lint = !makeVal(state, !defaultPartialCompileFlags.Disable_api_lint)
515		case "disable_api_lint":
516			ret.Disable_api_lint = makeVal(state, defaultPartialCompileFlags.Disable_api_lint)
517
518		case "stub_validation", "enable_stub_validation":
519			ret.Disable_stub_validation = !makeVal(state, !defaultPartialCompileFlags.Disable_stub_validation)
520		case "disable_stub_validation":
521			ret.Disable_stub_validation = makeVal(state, defaultPartialCompileFlags.Disable_stub_validation)
522
523		case "use_d8":
524			ret.Use_d8 = makeVal(state, defaultPartialCompileFlags.Use_d8)
525		default:
526			return partialCompileFlags{}, fmt.Errorf("Unknown SOONG_PARTIAL_COMPILE value: %v", tok)
527		}
528	}
529	return ret, nil
530}
531
532func loadConfig(config *config) error {
533	return loadFromConfigFile(&config.productVariables, absolutePath(config.ProductVariablesFileName))
534}
535
536// Checks if the string is a valid go identifier. This is equivalent to blueprint's definition
537// of an identifier, so it will match the same identifiers as those that can be used in bp files.
538func isGoIdentifier(ident string) bool {
539	for i, r := range ident {
540		valid := r == '_' || unicode.IsLetter(r) || unicode.IsDigit(r) && i > 0
541		if !valid {
542			return false
543		}
544	}
545	return len(ident) > 0
546}
547
548// loadFromConfigFile loads and decodes configuration options from a JSON file
549// in the current working directory.
550func loadFromConfigFile(configurable *ProductVariables, filename string) error {
551	// Try to open the file
552	configFileReader, err := os.Open(filename)
553	defer configFileReader.Close()
554	if os.IsNotExist(err) {
555		// Need to create a file, so that blueprint & ninja don't get in
556		// a dependency tracking loop.
557		// Make a file-configurable-options with defaults, write it out using
558		// a json writer.
559		configurable.SetDefaultConfig()
560		err = saveToConfigFile(configurable, filename)
561		if err != nil {
562			return err
563		}
564	} else if err != nil {
565		return fmt.Errorf("config file: could not open %s: %s", filename, err.Error())
566	} else {
567		// Make a decoder for it
568		jsonDecoder := json.NewDecoder(configFileReader)
569		jsonDecoder.DisallowUnknownFields()
570		err = jsonDecoder.Decode(configurable)
571		if err != nil {
572			return fmt.Errorf("config file: %s did not parse correctly: %s", filename, err.Error())
573		}
574	}
575
576	if Bool(configurable.GcovCoverage) && Bool(configurable.ClangCoverage) {
577		return fmt.Errorf("GcovCoverage and ClangCoverage cannot both be set")
578	}
579
580	configurable.Native_coverage = proptools.BoolPtr(
581		Bool(configurable.GcovCoverage) ||
582			Bool(configurable.ClangCoverage))
583
584	// The go scanner's definition of identifiers is c-style identifiers, but allowing unicode's
585	// definition of letters and digits. This is the same scanner that blueprint uses, so it
586	// will allow the same identifiers as are valid in bp files.
587	for namespace := range configurable.VendorVars {
588		if !isGoIdentifier(namespace) {
589			return fmt.Errorf("soong config namespaces must be valid identifiers: %q", namespace)
590		}
591		for variable := range configurable.VendorVars[namespace] {
592			if !isGoIdentifier(variable) {
593				return fmt.Errorf("soong config variables must be valid identifiers: %q", variable)
594			}
595		}
596	}
597
598	// when Platform_sdk_final is true (or PLATFORM_VERSION_CODENAME is REL), use Platform_sdk_version;
599	// if false (pre-released version, for example), use Platform_sdk_codename.
600	if Bool(configurable.Platform_sdk_final) {
601		if configurable.Platform_sdk_version != nil {
602			configurable.Platform_sdk_version_or_codename =
603				proptools.StringPtr(strconv.Itoa(*(configurable.Platform_sdk_version)))
604		} else {
605			return fmt.Errorf("Platform_sdk_version cannot be pointed by a NULL pointer")
606		}
607	} else {
608		configurable.Platform_sdk_version_or_codename =
609			proptools.StringPtr(String(configurable.Platform_sdk_codename))
610	}
611
612	return nil
613}
614
615// atomically writes the config file in case two copies of soong_build are running simultaneously
616// (for example, docs generation and ninja manifest generation)
617func saveToConfigFile(config *ProductVariables, filename string) error {
618	data, err := json.MarshalIndent(&config, "", "    ")
619	if err != nil {
620		return fmt.Errorf("cannot marshal config data: %s", err.Error())
621	}
622
623	f, err := os.CreateTemp(filepath.Dir(filename), "config")
624	if err != nil {
625		return fmt.Errorf("cannot create empty config file %s: %s", filename, err.Error())
626	}
627	defer os.Remove(f.Name())
628	defer f.Close()
629
630	_, err = f.Write(data)
631	if err != nil {
632		return fmt.Errorf("default config file: %s could not be written: %s", filename, err.Error())
633	}
634
635	_, err = f.WriteString("\n")
636	if err != nil {
637		return fmt.Errorf("default config file: %s could not be written: %s", filename, err.Error())
638	}
639
640	f.Close()
641	os.Rename(f.Name(), filename)
642
643	return nil
644}
645
646// NullConfig returns a mostly empty Config for use by standalone tools like dexpreopt_gen that
647// use the android package.
648func NullConfig(outDir, soongOutDir string) Config {
649	return Config{
650		config: &config{
651			outDir:      outDir,
652			soongOutDir: soongOutDir,
653			fs:          pathtools.OsFs,
654		},
655	}
656}
657
658func initConfig(cmdArgs CmdArgs, availableEnv map[string]string) (*config, error) {
659	// Make a config with default options.
660	newConfig := &config{
661		ProductVariablesFileName: cmdArgs.SoongVariables,
662
663		env: availableEnv,
664
665		outDir:            cmdArgs.OutDir,
666		soongOutDir:       cmdArgs.SoongOutDir,
667		runGoTests:        cmdArgs.RunGoTests,
668		katiSuffix:        cmdArgs.KatiSuffix,
669		multilibConflicts: make(map[ArchType]bool),
670
671		moduleListFile: cmdArgs.ModuleListFile,
672		fs:             pathtools.NewOsFs(absSrcDir),
673
674		OncePer: &OncePer{},
675
676		buildFromSourceStub: cmdArgs.BuildFromSourceStub,
677	}
678	variant, ok := os.LookupEnv("TARGET_BUILD_VARIANT")
679	isEngBuild := !ok || variant == "eng"
680
681	newConfig.deviceConfig = &deviceConfig{
682		config: newConfig,
683	}
684
685	// Soundness check of the build and source directories. This won't catch strange
686	// configurations with symlinks, but at least checks the obvious case.
687	absBuildDir, err := filepath.Abs(cmdArgs.SoongOutDir)
688	if err != nil {
689		return &config{}, err
690	}
691
692	absSrcDir, err := filepath.Abs(".")
693	if err != nil {
694		return &config{}, err
695	}
696
697	if strings.HasPrefix(absSrcDir, absBuildDir) {
698		return &config{}, fmt.Errorf("Build dir must not contain source directory")
699	}
700
701	// Load any configurable options from the configuration file
702	err = loadConfig(newConfig)
703	if err != nil {
704		return &config{}, err
705	}
706
707	KatiEnabledMarkerFile := filepath.Join(cmdArgs.SoongOutDir, ".soong.kati_enabled")
708	if _, err := os.Stat(absolutePath(KatiEnabledMarkerFile)); err == nil {
709		newConfig.katiEnabled = true
710	}
711
712	determineBuildOS(newConfig)
713
714	// Sets up the map of target OSes to the finer grained compilation targets
715	// that are configured from the product variables.
716	targets, err := decodeTargetProductVariables(newConfig)
717	if err != nil {
718		return &config{}, err
719	}
720
721	newConfig.partialCompileFlags, err = newConfig.parsePartialCompileFlags(isEngBuild)
722	if err != nil {
723		return &config{}, err
724	}
725
726	// Make the CommonOS OsType available for all products.
727	targets[CommonOS] = []Target{commonTargetMap[CommonOS.Name]}
728
729	var archConfig []archConfig
730	if newConfig.NdkAbis() {
731		archConfig = getNdkAbisConfig()
732	} else if newConfig.AmlAbis() {
733		archConfig = getAmlAbisConfig()
734	}
735
736	if archConfig != nil {
737		androidTargets, err := decodeAndroidArchSettings(archConfig)
738		if err != nil {
739			return &config{}, err
740		}
741		targets[Android] = androidTargets
742	}
743
744	multilib := make(map[string]bool)
745	for _, target := range targets[Android] {
746		if seen := multilib[target.Arch.ArchType.Multilib]; seen {
747			newConfig.multilibConflicts[target.Arch.ArchType] = true
748		}
749		multilib[target.Arch.ArchType.Multilib] = true
750	}
751
752	// Map of OS to compilation targets.
753	newConfig.Targets = targets
754
755	// Compilation targets for host tools.
756	newConfig.BuildOSTarget = newConfig.Targets[newConfig.BuildOS][0]
757	newConfig.BuildOSCommonTarget = getCommonTargets(newConfig.Targets[newConfig.BuildOS])[0]
758
759	// Compilation targets for Android.
760	if len(newConfig.Targets[Android]) > 0 {
761		newConfig.AndroidCommonTarget = getCommonTargets(newConfig.Targets[Android])[0]
762		newConfig.AndroidFirstDeviceTarget = FirstTarget(newConfig.Targets[Android], "lib64", "lib32")[0]
763	}
764
765	setBuildMode := func(arg string, mode SoongBuildMode) {
766		if arg != "" {
767			if newConfig.BuildMode != AnalysisNoBazel {
768				fmt.Fprintf(os.Stderr, "buildMode is already set, illegal argument: %s", arg)
769				os.Exit(1)
770			}
771			newConfig.BuildMode = mode
772		}
773	}
774	setBuildMode(cmdArgs.ModuleGraphFile, GenerateModuleGraph)
775	setBuildMode(cmdArgs.DocFile, GenerateDocFile)
776
777	newConfig.productVariables.Build_from_text_stub = boolPtr(newConfig.BuildFromTextStub())
778
779	newConfig.deviceNameToInstall = newConfig.productVariables.DeviceName
780
781	return newConfig, err
782}
783
784// Replace variables in config.productVariables that have tags with "generic" key.
785// A generic tag may have a string or an int value for the generic configuration.
786// If the value is "unset", generic configuration will unset the variable.
787func overrideGenericConfig(config *config) {
788	config.genericConfig.isGeneric = true
789	type_pv := reflect.TypeOf(config.genericConfig.productVariables)
790	value_pv := reflect.ValueOf(&config.genericConfig.productVariables)
791	for i := range type_pv.NumField() {
792		type_pv_field := type_pv.Field(i)
793		generic_value := type_pv_field.Tag.Get("generic")
794		// If a product variable has an annotation of "generic" tag, use the
795		// value of the tag to set the generic variable.
796		if generic_value != "" {
797			value_pv_field := value_pv.Elem().Field(i)
798
799			if generic_value == "unset" {
800				// unset the product variable
801				value_pv_field.SetZero()
802				continue
803			}
804
805			kind_of_type_pv := type_pv_field.Type.Kind()
806			is_pointer := false
807			if kind_of_type_pv == reflect.Pointer {
808				is_pointer = true
809				kind_of_type_pv = type_pv_field.Type.Elem().Kind()
810			}
811
812			switch kind_of_type_pv {
813			case reflect.String:
814				if is_pointer {
815					value_pv_field.Set(reflect.ValueOf(stringPtr(generic_value)))
816				} else {
817					value_pv_field.Set(reflect.ValueOf(generic_value))
818				}
819			case reflect.Int:
820				generic_int, err := strconv.Atoi(generic_value)
821				if err != nil {
822					panic(fmt.Errorf("Only an int value can be assigned to int variable: %s", err))
823				}
824				if is_pointer {
825					value_pv_field.Set(reflect.ValueOf(intPtr(generic_int)))
826				} else {
827					value_pv_field.Set(reflect.ValueOf(generic_int))
828				}
829			default:
830				panic(fmt.Errorf("Unknown type to replace for generic variable: %s", &kind_of_type_pv))
831			}
832		}
833	}
834
835	// OncePer must be a singleton.
836	config.genericConfig.OncePer = config.OncePer
837	// keep the device name to get the install path.
838	config.genericConfig.deviceNameToInstall = config.deviceNameToInstall
839}
840
841// NewConfig creates a new Config object. It also loads the config file, if
842// found. The Config object includes a duplicated Config object in it for the
843// generic configuration that does not provide any product specific information.
844func NewConfig(cmdArgs CmdArgs, availableEnv map[string]string) (Config, error) {
845	config, err := initConfig(cmdArgs, availableEnv)
846	if err != nil {
847		return Config{}, err
848	}
849
850	// Initialize generic configuration.
851	config.genericConfig, err = initConfig(cmdArgs, availableEnv)
852	// Update product specific variables with the generic configuration.
853	overrideGenericConfig(config)
854
855	return Config{config}, err
856}
857
858// mockFileSystem replaces all reads with accesses to the provided map of
859// filenames to contents stored as a byte slice.
860func (c *config) mockFileSystem(bp string, fs map[string][]byte) {
861	mockFS := map[string][]byte{}
862
863	if _, exists := mockFS["Android.bp"]; !exists {
864		mockFS["Android.bp"] = []byte(bp)
865	}
866
867	for k, v := range fs {
868		mockFS[k] = v
869	}
870
871	// no module list file specified; find every file named Blueprints or Android.bp
872	pathsToParse := []string{}
873	for candidate := range mockFS {
874		base := filepath.Base(candidate)
875		if base == "Android.bp" {
876			pathsToParse = append(pathsToParse, candidate)
877		}
878	}
879	if len(pathsToParse) < 1 {
880		panic(fmt.Sprintf("No Blueprint or Android.bp files found in mock filesystem: %v\n", mockFS))
881	}
882	mockFS[blueprint.MockModuleListFile] = []byte(strings.Join(pathsToParse, "\n"))
883
884	c.fs = pathtools.MockFs(mockFS)
885	c.mockBpList = blueprint.MockModuleListFile
886}
887
888func (c *config) SetAllowMissingDependencies() {
889	c.productVariables.Allow_missing_dependencies = proptools.BoolPtr(true)
890}
891
892// BlueprintToolLocation returns the directory containing build system tools
893// from Blueprint, like soong_zip and merge_zips.
894func (c *config) HostToolDir() string {
895	return filepath.Join(c.outDir, "host", c.PrebuiltOS(), "bin")
896}
897
898func (c *config) HostToolPath(ctx PathContext, tool string) Path {
899	path := pathForInstall(ctx, ctx.Config().BuildOS, ctx.Config().BuildArch, "bin", tool)
900	return path
901}
902
903func (c *config) HostJNIToolPath(ctx PathContext, lib string) Path {
904	ext := ".so"
905	if runtime.GOOS == "darwin" {
906		ext = ".dylib"
907	}
908	path := pathForInstall(ctx, ctx.Config().BuildOS, ctx.Config().BuildArch, "lib64", lib+ext)
909	return path
910}
911
912func (c *config) HostJavaToolPath(ctx PathContext, tool string) Path {
913	path := pathForInstall(ctx, ctx.Config().BuildOS, ctx.Config().BuildArch, "framework", tool)
914	return path
915}
916
917func (c *config) HostCcSharedLibPath(ctx PathContext, lib string) Path {
918	libDir := "lib"
919	if ctx.Config().BuildArch.Multilib == "lib64" {
920		libDir = "lib64"
921	}
922	return pathForInstall(ctx, ctx.Config().BuildOS, ctx.Config().BuildArch, libDir, lib+".so")
923}
924
925// PrebuiltOS returns the name of the host OS used in prebuilts directories.
926func (c *config) PrebuiltOS() string {
927	switch runtime.GOOS {
928	case "linux":
929		switch runtime.GOARCH {
930		case "amd64":
931			return "linux-x86"
932		case "arm64":
933			return "linux-arm64"
934		default:
935			panic(fmt.Errorf("Unknown GOARCH %s", runtime.GOARCH))
936		}
937	case "darwin":
938		return "darwin-x86"
939	default:
940		panic(fmt.Errorf("Unknown GOOS %s", runtime.GOOS))
941	}
942}
943
944// GoRoot returns the path to the root directory of the Go toolchain.
945func (c *config) GoRoot() string {
946	return fmt.Sprintf("prebuilts/go/%s", c.PrebuiltOS())
947}
948
949// PrebuiltBuildTool returns the path to a tool in the prebuilts directory containing
950// checked-in tools, like Kati, Ninja or Toybox, for the current host OS.
951func (c *config) PrebuiltBuildTool(ctx PathContext, tool string) Path {
952	return PathForSource(ctx, "prebuilts/build-tools", c.PrebuiltOS(), "bin", tool)
953}
954
955// CpPreserveSymlinksFlags returns the host-specific flag for the cp(1) command
956// to preserve symlinks.
957func (c *config) CpPreserveSymlinksFlags() string {
958	switch runtime.GOOS {
959	case "darwin":
960		return "-R"
961	case "linux":
962		return "-d"
963	default:
964		return ""
965	}
966}
967
968func (c *config) Getenv(key string) string {
969	var val string
970	var exists bool
971	c.envLock.Lock()
972	defer c.envLock.Unlock()
973	if c.envDeps == nil {
974		c.envDeps = make(map[string]string)
975	}
976	if val, exists = c.envDeps[key]; !exists {
977		if c.envFrozen {
978			panic("Cannot access new environment variables after envdeps are frozen")
979		}
980		val, _ = c.env[key]
981		c.envDeps[key] = val
982	}
983	return val
984}
985
986func (c *config) GetenvWithDefault(key string, defaultValue string) string {
987	ret := c.Getenv(key)
988	if ret == "" {
989		return defaultValue
990	}
991	return ret
992}
993
994func (c *config) IsEnvTrue(key string) bool {
995	value := strings.ToLower(c.Getenv(key))
996	return value == "1" || value == "y" || value == "yes" || value == "on" || value == "true"
997}
998
999func (c *config) IsEnvFalse(key string) bool {
1000	value := strings.ToLower(c.Getenv(key))
1001	return value == "0" || value == "n" || value == "no" || value == "off" || value == "false"
1002}
1003
1004func (c *config) TargetsJava21() bool {
1005	return c.productVariables.GetBuildFlagBool("RELEASE_TARGET_JAVA_21")
1006}
1007
1008// EnvDeps returns the environment variables this build depends on. The first
1009// call to this function blocks future reads from the environment.
1010func (c *config) EnvDeps() map[string]string {
1011	c.envLock.Lock()
1012	defer c.envLock.Unlock()
1013	c.envFrozen = true
1014	return c.envDeps
1015}
1016
1017func (c *config) KatiEnabled() bool {
1018	return c.katiEnabled
1019}
1020
1021func (c *config) ProductVariables() ProductVariables {
1022	return c.productVariables
1023}
1024
1025func (c *config) BuildId() string {
1026	return String(c.productVariables.BuildId)
1027}
1028
1029func (c *config) DisplayBuildNumber() bool {
1030	return Bool(c.productVariables.DisplayBuildNumber)
1031}
1032
1033// BuildFingerprintFile returns the path to a text file containing metadata
1034// representing the current build's fingerprint.
1035//
1036// Rules that want to reference the build fingerprint should read from this file
1037// without depending on it. They will run whenever their other dependencies
1038// require them to run and get the current build fingerprint. This ensures they
1039// don't rebuild on every incremental build when the build number changes.
1040func (c *config) BuildFingerprintFile(ctx PathContext) Path {
1041	return PathForArbitraryOutput(ctx, "target", "product", *c.deviceNameToInstall, String(c.productVariables.BuildFingerprintFile))
1042}
1043
1044// BuildNumberFile returns the path to a text file containing metadata
1045// representing the current build's number.
1046//
1047// Rules that want to reference the build number should read from this file
1048// without depending on it. They will run whenever their other dependencies
1049// require them to run and get the current build number. This ensures they don't
1050// rebuild on every incremental build when the build number changes.
1051func (c *config) BuildNumberFile(ctx PathContext) Path {
1052	return PathForOutput(ctx, String(c.productVariables.BuildNumberFile))
1053}
1054
1055// BuildHostnameFile returns the path to a text file containing metadata
1056// representing the current build's host name.
1057func (c *config) BuildHostnameFile(ctx PathContext) Path {
1058	return PathForOutput(ctx, String(c.productVariables.BuildHostnameFile))
1059}
1060
1061// BuildThumbprintFile returns the path to a text file containing metadata
1062// representing the current build's thumbprint.
1063//
1064// Rules that want to reference the build thumbprint should read from this file
1065// without depending on it. They will run whenever their other dependencies
1066// require them to run and get the current build thumbprint. This ensures they
1067// don't rebuild on every incremental build when the build thumbprint changes.
1068func (c *config) BuildThumbprintFile(ctx PathContext) Path {
1069	return PathForArbitraryOutput(ctx, "target", "product", *c.deviceNameToInstall, String(c.productVariables.BuildThumbprintFile))
1070}
1071
1072// DeviceName returns the name of the current device target.
1073// TODO: take an AndroidModuleContext to select the device name for multi-device builds
1074func (c *config) DeviceName() string {
1075	return *c.productVariables.DeviceName
1076}
1077
1078// DeviceProduct returns the current product target. There could be multiple of
1079// these per device type.
1080//
1081// NOTE: Do not base conditional logic on this value. It may break product inheritance.
1082func (c *config) DeviceProduct() string {
1083	return *c.productVariables.DeviceProduct
1084}
1085
1086// HasDeviceProduct returns if the build has a product. A build will not
1087// necessarily have a product when --skip-config is passed to soong, like it is
1088// in prebuilts/build-tools/build-prebuilts.sh
1089func (c *config) HasDeviceProduct() bool {
1090	return c.productVariables.DeviceProduct != nil
1091}
1092
1093func (c *config) DeviceAbi() []string {
1094	return c.productVariables.DeviceAbi
1095}
1096
1097func (c *config) DeviceResourceOverlays() []string {
1098	return c.productVariables.DeviceResourceOverlays
1099}
1100
1101func (c *config) ProductResourceOverlays() []string {
1102	return c.productVariables.ProductResourceOverlays
1103}
1104
1105func (c *config) PlatformDisplayVersionName() string {
1106	return String(c.productVariables.Platform_display_version_name)
1107}
1108
1109func (c *config) PlatformVersionName() string {
1110	return String(c.productVariables.Platform_version_name)
1111}
1112
1113func (c *config) PlatformSdkVersion() ApiLevel {
1114	return uncheckedFinalApiLevel(*c.productVariables.Platform_sdk_version)
1115}
1116
1117func (c *config) PlatformSdkVersionFull() string {
1118	return proptools.StringDefault(c.productVariables.Platform_sdk_version_full, "")
1119}
1120
1121func (c *config) RawPlatformSdkVersion() *int {
1122	return c.productVariables.Platform_sdk_version
1123}
1124
1125func (c *config) PlatformSdkFinal() bool {
1126	return Bool(c.productVariables.Platform_sdk_final)
1127}
1128
1129func (c *config) PlatformSdkCodename() string {
1130	return String(c.productVariables.Platform_sdk_codename)
1131}
1132
1133func (c *config) PlatformSdkExtensionVersion() int {
1134	return *c.productVariables.Platform_sdk_extension_version
1135}
1136
1137func (c *config) PlatformBaseSdkExtensionVersion() int {
1138	return *c.productVariables.Platform_base_sdk_extension_version
1139}
1140
1141func (c *config) PlatformSecurityPatch() string {
1142	return String(c.productVariables.Platform_security_patch)
1143}
1144
1145func (c *config) PlatformPreviewSdkVersion() string {
1146	return String(c.productVariables.Platform_preview_sdk_version)
1147}
1148
1149func (c *config) PlatformMinSupportedTargetSdkVersion() string {
1150	var val, ok = c.productVariables.BuildFlags["RELEASE_PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION"]
1151	if !ok {
1152		return ""
1153	}
1154	return val
1155}
1156
1157func (c *config) PlatformBaseOS() string {
1158	return String(c.productVariables.Platform_base_os)
1159}
1160
1161func (c *config) PlatformVersionLastStable() string {
1162	return String(c.productVariables.Platform_version_last_stable)
1163}
1164
1165func (c *config) PlatformVersionKnownCodenames() string {
1166	return String(c.productVariables.Platform_version_known_codenames)
1167}
1168
1169func (c *config) MinSupportedSdkVersion() ApiLevel {
1170	return uncheckedFinalApiLevel(21)
1171}
1172
1173func (c *config) FinalApiLevels() []ApiLevel {
1174	var levels []ApiLevel
1175	for i := 1; i <= c.PlatformSdkVersion().FinalOrFutureInt(); i++ {
1176		levels = append(levels, uncheckedFinalApiLevel(i))
1177	}
1178	return levels
1179}
1180
1181func (c *config) PreviewApiLevels() []ApiLevel {
1182	var levels []ApiLevel
1183	i := 0
1184	for _, codename := range c.PlatformVersionActiveCodenames() {
1185		if codename == "REL" {
1186			continue
1187		}
1188
1189		levels = append(levels, ApiLevel{
1190			value:     codename,
1191			number:    i,
1192			isPreview: true,
1193		})
1194		i++
1195	}
1196	return levels
1197}
1198
1199func (c *config) LatestPreviewApiLevel() ApiLevel {
1200	level := NoneApiLevel
1201	for _, l := range c.PreviewApiLevels() {
1202		if l.GreaterThan(level) {
1203			level = l
1204		}
1205	}
1206	return level
1207}
1208
1209func (c *config) AllSupportedApiLevels() []ApiLevel {
1210	var levels []ApiLevel
1211	levels = append(levels, c.FinalApiLevels()...)
1212	return append(levels, c.PreviewApiLevels()...)
1213}
1214
1215// DefaultAppTargetSdk returns the API level that platform apps are targeting.
1216// This converts a codename to the exact ApiLevel it represents.
1217func (c *config) DefaultAppTargetSdk(ctx EarlyModuleContext) ApiLevel {
1218	if Bool(c.productVariables.Platform_sdk_final) {
1219		return c.PlatformSdkVersion()
1220	}
1221	codename := c.PlatformSdkCodename()
1222	hostOnlyBuild := c.productVariables.DeviceArch == nil
1223	if codename == "" {
1224		// There are some host-only builds (those are invoked by build-prebuilts.sh) which
1225		// don't set platform sdk codename. Platform sdk codename makes sense only when we
1226		// are building the platform. So we don't enforce the below panic for the host-only
1227		// builds.
1228		if hostOnlyBuild {
1229			return NoneApiLevel
1230		}
1231		panic("Platform_sdk_codename must be set")
1232	}
1233	if codename == "REL" {
1234		panic("Platform_sdk_codename should not be REL when Platform_sdk_final is true")
1235	}
1236	return ApiLevelOrPanic(ctx, codename)
1237}
1238
1239func (c *config) PartialCompileFlags() partialCompileFlags {
1240	return c.partialCompileFlags
1241}
1242
1243func (c *config) AppsDefaultVersionName() string {
1244	return String(c.productVariables.AppsDefaultVersionName)
1245}
1246
1247// Codenames that are active in the current lunch target.
1248func (c *config) PlatformVersionActiveCodenames() []string {
1249	return c.productVariables.Platform_version_active_codenames
1250}
1251
1252// All unreleased codenames.
1253func (c *config) PlatformVersionAllPreviewCodenames() []string {
1254	return c.productVariables.Platform_version_all_preview_codenames
1255}
1256
1257func (c *config) ProductAAPTConfig() []string {
1258	return c.productVariables.AAPTConfig
1259}
1260
1261func (c *config) ProductAAPTPreferredConfig() string {
1262	return String(c.productVariables.AAPTPreferredConfig)
1263}
1264
1265func (c *config) ProductAAPTCharacteristics() string {
1266	return String(c.productVariables.AAPTCharacteristics)
1267}
1268
1269func (c *config) ProductAAPTPrebuiltDPI() []string {
1270	return c.productVariables.AAPTPrebuiltDPI
1271}
1272
1273func (c *config) DefaultAppCertificateDir(ctx PathContext) SourcePath {
1274	defaultCert := String(c.productVariables.DefaultAppCertificate)
1275	if defaultCert != "" {
1276		return PathForSource(ctx, filepath.Dir(defaultCert))
1277	}
1278	return PathForSource(ctx, testKeyDir)
1279}
1280
1281func (c *config) DefaultAppCertificate(ctx PathContext) (pem, key SourcePath) {
1282	defaultCert := String(c.productVariables.DefaultAppCertificate)
1283	if defaultCert != "" {
1284		return PathForSource(ctx, defaultCert+".x509.pem"), PathForSource(ctx, defaultCert+".pk8")
1285	}
1286	defaultDir := c.DefaultAppCertificateDir(ctx)
1287	return defaultDir.Join(ctx, "testkey.x509.pem"), defaultDir.Join(ctx, "testkey.pk8")
1288}
1289
1290func (c *config) ExtraOtaKeys(ctx PathContext, recovery bool) []SourcePath {
1291	var otaKeys []string
1292	if recovery {
1293		otaKeys = c.productVariables.ExtraOtaRecoveryKeys
1294	} else {
1295		otaKeys = c.productVariables.ExtraOtaKeys
1296	}
1297
1298	otaPaths := make([]SourcePath, len(otaKeys))
1299	for i, key := range otaKeys {
1300		otaPaths[i] = PathForSource(ctx, key+".x509.pem")
1301	}
1302
1303	return otaPaths
1304}
1305
1306func (c *config) ExtraOtaRecoveryKeys() []string {
1307	return c.productVariables.ExtraOtaRecoveryKeys
1308}
1309
1310func (c *config) BuildKeys() string {
1311	defaultCert := String(c.productVariables.DefaultAppCertificate)
1312	if defaultCert == "" || defaultCert == filepath.Join(testKeyDir, "testkey") {
1313		return "test-keys"
1314	}
1315	return "dev-keys"
1316}
1317
1318func (c *config) ApexKeyDir(ctx ModuleContext) SourcePath {
1319	// TODO(b/121224311): define another variable such as TARGET_APEX_KEY_OVERRIDE
1320	defaultCert := String(c.productVariables.DefaultAppCertificate)
1321	if defaultCert == "" || filepath.Dir(defaultCert) == testKeyDir {
1322		// When defaultCert is unset or is set to the testkeys path, use the APEX keys
1323		// that is under the module dir
1324		return pathForModuleSrc(ctx)
1325	}
1326	// If not, APEX keys are under the specified directory
1327	return PathForSource(ctx, filepath.Dir(defaultCert))
1328}
1329
1330// Certificate for the NetworkStack sepolicy context
1331func (c *config) MainlineSepolicyDevCertificatesDir(ctx ModuleContext) SourcePath {
1332	cert := String(c.productVariables.MainlineSepolicyDevCertificates)
1333	if cert != "" {
1334		return PathForSource(ctx, cert)
1335	}
1336	return c.DefaultAppCertificateDir(ctx)
1337}
1338
1339// AllowMissingDependencies configures Blueprint/Soong to not fail when modules
1340// are configured to depend on non-existent modules. Note that this does not
1341// affect missing input dependencies at the Ninja level.
1342func (c *config) AllowMissingDependencies() bool {
1343	return Bool(c.productVariables.Allow_missing_dependencies)
1344}
1345
1346// Returns true if a full platform source tree cannot be assumed.
1347func (c *config) UnbundledBuild() bool {
1348	return Bool(c.productVariables.Unbundled_build)
1349}
1350
1351// Returns true if building apps that aren't bundled with the platform.
1352// UnbundledBuild() is always true when this is true.
1353func (c *config) UnbundledBuildApps() bool {
1354	return len(c.productVariables.Unbundled_build_apps) > 0
1355}
1356
1357// Returns true if building image that aren't bundled with the platform.
1358// UnbundledBuild() is always true when this is true.
1359func (c *config) UnbundledBuildImage() bool {
1360	return Bool(c.productVariables.Unbundled_build_image)
1361}
1362
1363// Returns true if building modules against prebuilt SDKs.
1364func (c *config) AlwaysUsePrebuiltSdks() bool {
1365	return Bool(c.productVariables.Always_use_prebuilt_sdks)
1366}
1367
1368func (c *config) MinimizeJavaDebugInfo() bool {
1369	return Bool(c.productVariables.MinimizeJavaDebugInfo) && !Bool(c.productVariables.Eng)
1370}
1371
1372func (c *config) Debuggable() bool {
1373	return Bool(c.productVariables.Debuggable)
1374}
1375
1376func (c *config) Eng() bool {
1377	return Bool(c.productVariables.Eng)
1378}
1379
1380func (c *config) BuildType() string {
1381	return String(c.productVariables.BuildType)
1382}
1383
1384// DevicePrimaryArchType returns the ArchType for the first configured device architecture, or
1385// Common if there are no device architectures.
1386func (c *config) DevicePrimaryArchType() ArchType {
1387	if androidTargets := c.Targets[Android]; len(androidTargets) > 0 {
1388		return androidTargets[0].Arch.ArchType
1389	}
1390	return Common
1391}
1392
1393func (c *config) SanitizeHost() []string {
1394	return append([]string(nil), c.productVariables.SanitizeHost...)
1395}
1396
1397func (c *config) SanitizeDevice() []string {
1398	return append([]string(nil), c.productVariables.SanitizeDevice...)
1399}
1400
1401func (c *config) SanitizeDeviceDiag() []string {
1402	return append([]string(nil), c.productVariables.SanitizeDeviceDiag...)
1403}
1404
1405func (c *config) SanitizeDeviceArch() []string {
1406	return append([]string(nil), c.productVariables.SanitizeDeviceArch...)
1407}
1408
1409func (c *config) EnableCFI() bool {
1410	if c.productVariables.EnableCFI == nil {
1411		return true
1412	}
1413	return *c.productVariables.EnableCFI
1414}
1415
1416func (c *config) DisableScudo() bool {
1417	return Bool(c.productVariables.DisableScudo)
1418}
1419
1420func (c *config) Android64() bool {
1421	for _, t := range c.Targets[Android] {
1422		if t.Arch.ArchType.Multilib == "lib64" {
1423			return true
1424		}
1425	}
1426
1427	return false
1428}
1429
1430func (c *config) UseGoma() bool {
1431	return Bool(c.productVariables.UseGoma)
1432}
1433
1434func (c *config) UseABFS() bool {
1435	return Bool(c.productVariables.UseABFS)
1436}
1437
1438func (c *config) UseRBE() bool {
1439	return Bool(c.productVariables.UseRBE)
1440}
1441
1442func (c *config) UseRBEJAVAC() bool {
1443	return Bool(c.productVariables.UseRBEJAVAC)
1444}
1445
1446func (c *config) UseRBER8() bool {
1447	return Bool(c.productVariables.UseRBER8)
1448}
1449
1450func (c *config) UseRBED8() bool {
1451	return Bool(c.productVariables.UseRBED8)
1452}
1453
1454func (c *config) UseRemoteBuild() bool {
1455	return c.UseGoma() || c.UseRBE()
1456}
1457
1458func (c *config) RunErrorProne() bool {
1459	return c.IsEnvTrue("RUN_ERROR_PRONE") || c.RunErrorProneInline()
1460}
1461
1462// Returns if the errorprone build should be run "inline", that is, using errorprone as part
1463// of the main javac compilation instead of its own separate compilation. This is good for CI
1464// but bad for local development, because if you toggle errorprone+inline on/off it will repeatedly
1465// clobber java files from the old configuration.
1466func (c *config) RunErrorProneInline() bool {
1467	value := strings.ToLower(c.Getenv("RUN_ERROR_PRONE"))
1468	return c.IsEnvTrue("RUN_ERROR_PRONE_INLINE") || value == "inline"
1469}
1470
1471// XrefCorpusName returns the Kythe cross-reference corpus name.
1472func (c *config) XrefCorpusName() string {
1473	return c.Getenv("XREF_CORPUS")
1474}
1475
1476// XrefCuEncoding returns the compilation unit encoding to use for Kythe code
1477// xrefs. Can be 'json' (default), 'proto' or 'all'.
1478func (c *config) XrefCuEncoding() string {
1479	if enc := c.Getenv("KYTHE_KZIP_ENCODING"); enc != "" {
1480		return enc
1481	}
1482	return "json"
1483}
1484
1485// XrefCuJavaSourceMax returns the maximum number of the Java source files
1486// in a single compilation unit
1487const xrefJavaSourceFileMaxDefault = "1000"
1488
1489func (c Config) XrefCuJavaSourceMax() string {
1490	v := c.Getenv("KYTHE_JAVA_SOURCE_BATCH_SIZE")
1491	if v == "" {
1492		return xrefJavaSourceFileMaxDefault
1493	}
1494	if _, err := strconv.ParseUint(v, 0, 0); err != nil {
1495		fmt.Fprintf(os.Stderr,
1496			"bad KYTHE_JAVA_SOURCE_BATCH_SIZE value: %s, will use %s",
1497			err, xrefJavaSourceFileMaxDefault)
1498		return xrefJavaSourceFileMaxDefault
1499	}
1500	return v
1501
1502}
1503
1504func (c *config) EmitXrefRules() bool {
1505	return c.XrefCorpusName() != ""
1506}
1507
1508func (c *config) ClangTidy() bool {
1509	return Bool(c.productVariables.ClangTidy)
1510}
1511
1512func (c *config) TidyChecks() string {
1513	if c.productVariables.TidyChecks == nil {
1514		return ""
1515	}
1516	return *c.productVariables.TidyChecks
1517}
1518
1519func (c *config) LibartImgHostBaseAddress() string {
1520	return "0x70000000"
1521}
1522
1523func (c *config) LibartImgDeviceBaseAddress() string {
1524	return "0x70000000"
1525}
1526
1527func (c *config) ArtUseReadBarrier() bool {
1528	return Bool(c.productVariables.ArtUseReadBarrier)
1529}
1530
1531// Enforce Runtime Resource Overlays for a module. RROs supersede static RROs,
1532// but some modules still depend on it.
1533//
1534// More info: https://source.android.com/devices/architecture/rros
1535func (c *config) EnforceRROForModule(name string) bool {
1536	enforceList := c.productVariables.EnforceRROTargets
1537
1538	if len(enforceList) > 0 {
1539		if InList("*", enforceList) {
1540			return true
1541		}
1542		return InList(name, enforceList)
1543	}
1544	return false
1545}
1546
1547func (c *config) EnforceRROExcludedOverlay(path string) bool {
1548	excluded := c.productVariables.EnforceRROExcludedOverlays
1549	if len(excluded) > 0 {
1550		return HasAnyPrefix(path, excluded)
1551	}
1552	return false
1553}
1554
1555func (c *config) EnforceRROGlobally() bool {
1556	enforceList := c.productVariables.EnforceRROTargets
1557	return InList("*", enforceList)
1558}
1559
1560func (c *config) ExportedNamespaces() []string {
1561	return append([]string(nil), c.productVariables.NamespacesToExport...)
1562}
1563
1564func (c *config) SourceRootDirs() []string {
1565	return c.productVariables.SourceRootDirs
1566}
1567
1568func (c *config) HostStaticBinaries() bool {
1569	return Bool(c.productVariables.HostStaticBinaries)
1570}
1571
1572func (c *config) UncompressPrivAppDex() bool {
1573	return Bool(c.productVariables.UncompressPrivAppDex)
1574}
1575
1576func (c *config) ModulesLoadedByPrivilegedModules() []string {
1577	return c.productVariables.ModulesLoadedByPrivilegedModules
1578}
1579
1580// DexpreoptGlobalConfigPath returns the path to the dexpreopt.config file in
1581// the output directory, if it was created during the product configuration
1582// phase by Kati.
1583func (c *config) DexpreoptGlobalConfigPath(ctx PathContext) OptionalPath {
1584	if c.productVariables.DexpreoptGlobalConfig == nil {
1585		return OptionalPathForPath(nil)
1586	}
1587	return OptionalPathForPath(
1588		pathForBuildToolDep(ctx, *c.productVariables.DexpreoptGlobalConfig))
1589}
1590
1591// DexpreoptGlobalConfig returns the raw byte contents of the dexpreopt global
1592// configuration. Since the configuration file was created by Kati during
1593// product configuration (externally of soong_build), it's not tracked, so we
1594// also manually add a Ninja file dependency on the configuration file to the
1595// rule that creates the main build.ninja file. This ensures that build.ninja is
1596// regenerated correctly if dexpreopt.config changes.
1597func (c *config) DexpreoptGlobalConfig(ctx PathContext) ([]byte, error) {
1598	path := c.DexpreoptGlobalConfigPath(ctx)
1599	if !path.Valid() {
1600		return nil, nil
1601	}
1602	ctx.AddNinjaFileDeps(path.String())
1603	return os.ReadFile(absolutePath(path.String()))
1604}
1605
1606func (c *deviceConfig) WithDexpreopt() bool {
1607	return c.config.productVariables.WithDexpreopt
1608}
1609
1610func (c *config) FrameworksBaseDirExists(ctx PathGlobContext) bool {
1611	return ExistentPathForSource(ctx, "frameworks", "base", "Android.bp").Valid()
1612}
1613
1614func (c *config) HasMultilibConflict(arch ArchType) bool {
1615	return c.multilibConflicts[arch]
1616}
1617
1618func (c *config) PrebuiltHiddenApiDir(_ PathContext) string {
1619	return String(c.productVariables.PrebuiltHiddenApiDir)
1620}
1621
1622func (c *config) VendorApiLevel() string {
1623	return String(c.productVariables.VendorApiLevel)
1624}
1625
1626func (c *config) PrevVendorApiLevel() string {
1627	vendorApiLevel, err := strconv.Atoi(c.VendorApiLevel())
1628	if err != nil {
1629		panic(fmt.Errorf("Cannot parse vendor API level %s to an integer: %s",
1630			c.VendorApiLevel(), err))
1631	}
1632	// The version before trunk stable is 34.
1633	if vendorApiLevel == 202404 {
1634		return "34"
1635	}
1636	if vendorApiLevel >= 1 && vendorApiLevel <= 34 {
1637		return strconv.Itoa(vendorApiLevel - 1)
1638	}
1639	if vendorApiLevel < 202404 || vendorApiLevel%100 != 4 {
1640		panic("Unknown vendor API level " + c.VendorApiLevel())
1641	}
1642	return strconv.Itoa(vendorApiLevel - 100)
1643}
1644
1645func IsTrunkStableVendorApiLevel(level string) bool {
1646	levelInt, err := strconv.Atoi(level)
1647	return err == nil && levelInt >= 202404
1648}
1649
1650func (c *config) VendorApiLevelFrozen() bool {
1651	return c.productVariables.GetBuildFlagBool("RELEASE_BOARD_API_LEVEL_FROZEN")
1652}
1653
1654func (c *config) katiPackageMkDir() string {
1655	return filepath.Join(c.soongOutDir, "kati_packaging"+c.katiSuffix)
1656}
1657
1658func (c *deviceConfig) Arches() []Arch {
1659	var arches []Arch
1660	for _, target := range c.config.Targets[Android] {
1661		arches = append(arches, target.Arch)
1662	}
1663	return arches
1664}
1665
1666func (c *deviceConfig) BinderBitness() string {
1667	is32BitBinder := c.config.productVariables.Binder32bit
1668	if is32BitBinder != nil && *is32BitBinder {
1669		return "32"
1670	}
1671	return "64"
1672}
1673
1674func (c *deviceConfig) RecoveryPath() string {
1675	if c.config.productVariables.RecoveryPath != nil {
1676		return *c.config.productVariables.RecoveryPath
1677	}
1678	return "recovery"
1679}
1680
1681func (c *deviceConfig) VendorPath() string {
1682	if c.config.productVariables.VendorPath != nil {
1683		return *c.config.productVariables.VendorPath
1684	}
1685	return "vendor"
1686}
1687
1688func (c *deviceConfig) VendorDlkmPath() string {
1689	if c.config.productVariables.VendorDlkmPath != nil {
1690		return *c.config.productVariables.VendorDlkmPath
1691	}
1692	return "vendor_dlkm"
1693}
1694
1695func (c *deviceConfig) BuildingVendorImage() bool {
1696	return proptools.Bool(c.config.productVariables.BuildingVendorImage)
1697}
1698
1699func (c *deviceConfig) CurrentApiLevelForVendorModules() string {
1700	return StringDefault(c.config.productVariables.DeviceCurrentApiLevelForVendorModules, "current")
1701}
1702
1703func (c *deviceConfig) ExtraVndkVersions() []string {
1704	return c.config.productVariables.ExtraVndkVersions
1705}
1706
1707func (c *deviceConfig) SystemSdkVersions() []string {
1708	return c.config.productVariables.DeviceSystemSdkVersions
1709}
1710
1711func (c *deviceConfig) PlatformSystemSdkVersions() []string {
1712	return c.config.productVariables.Platform_systemsdk_versions
1713}
1714
1715func (c *deviceConfig) OdmPath() string {
1716	if c.config.productVariables.OdmPath != nil {
1717		return *c.config.productVariables.OdmPath
1718	}
1719	return "odm"
1720}
1721
1722func (c *deviceConfig) BuildingOdmImage() bool {
1723	return proptools.Bool(c.config.productVariables.BuildingOdmImage)
1724}
1725
1726func (c *deviceConfig) OdmDlkmPath() string {
1727	if c.config.productVariables.OdmDlkmPath != nil {
1728		return *c.config.productVariables.OdmDlkmPath
1729	}
1730	return "odm_dlkm"
1731}
1732
1733func (c *deviceConfig) ProductPath() string {
1734	if c.config.productVariables.ProductPath != nil {
1735		return *c.config.productVariables.ProductPath
1736	}
1737	return "product"
1738}
1739
1740func (c *deviceConfig) BuildingProductImage() bool {
1741	return proptools.Bool(c.config.productVariables.BuildingProductImage)
1742}
1743
1744func (c *deviceConfig) SystemExtPath() string {
1745	if c.config.productVariables.SystemExtPath != nil {
1746		return *c.config.productVariables.SystemExtPath
1747	}
1748	return "system_ext"
1749}
1750
1751func (c *deviceConfig) SystemDlkmPath() string {
1752	if c.config.productVariables.SystemDlkmPath != nil {
1753		return *c.config.productVariables.SystemDlkmPath
1754	}
1755	return "system_dlkm"
1756}
1757
1758func (c *deviceConfig) OemPath() string {
1759	if c.config.productVariables.OemPath != nil {
1760		return *c.config.productVariables.OemPath
1761	}
1762	return "oem"
1763}
1764
1765func (c *deviceConfig) UserdataPath() string {
1766	if c.config.productVariables.UserdataPath != nil {
1767		return *c.config.productVariables.UserdataPath
1768	}
1769	return "data"
1770}
1771
1772func (c *deviceConfig) BuildingUserdataImage() bool {
1773	return proptools.Bool(c.config.productVariables.BuildingUserdataImage)
1774}
1775
1776func (c *deviceConfig) BuildingRecoveryImage() bool {
1777	return proptools.Bool(c.config.productVariables.BuildingRecoveryImage)
1778}
1779
1780func (c *deviceConfig) BtConfigIncludeDir() string {
1781	return String(c.config.productVariables.BtConfigIncludeDir)
1782}
1783
1784func (c *deviceConfig) DeviceKernelHeaderDirs() []string {
1785	return c.config.productVariables.DeviceKernelHeaders
1786}
1787
1788// JavaCoverageEnabledForPath returns whether Java code coverage is enabled for
1789// path. Coverage is enabled by default when the product variable
1790// JavaCoveragePaths is empty. If JavaCoveragePaths is not empty, coverage is
1791// enabled for any path which is part of this variable (and not part of the
1792// JavaCoverageExcludePaths product variable). Value "*" in JavaCoveragePaths
1793// represents any path.
1794func (c *deviceConfig) JavaCoverageEnabledForPath(path string) bool {
1795	coverage := false
1796	if len(c.config.productVariables.JavaCoveragePaths) == 0 ||
1797		InList("*", c.config.productVariables.JavaCoveragePaths) ||
1798		HasAnyPrefix(path, c.config.productVariables.JavaCoveragePaths) {
1799		coverage = true
1800	}
1801	if coverage && len(c.config.productVariables.JavaCoverageExcludePaths) > 0 {
1802		if HasAnyPrefix(path, c.config.productVariables.JavaCoverageExcludePaths) {
1803			coverage = false
1804		}
1805	}
1806	return coverage
1807}
1808
1809// Returns true if gcov or clang coverage is enabled.
1810func (c *deviceConfig) NativeCoverageEnabled() bool {
1811	return Bool(c.config.productVariables.GcovCoverage) ||
1812		Bool(c.config.productVariables.ClangCoverage)
1813}
1814
1815func (c *deviceConfig) ClangCoverageEnabled() bool {
1816	return Bool(c.config.productVariables.ClangCoverage)
1817}
1818
1819func (c *deviceConfig) ClangCoverageContinuousMode() bool {
1820	return Bool(c.config.productVariables.ClangCoverageContinuousMode)
1821}
1822
1823func (c *deviceConfig) GcovCoverageEnabled() bool {
1824	return Bool(c.config.productVariables.GcovCoverage)
1825}
1826
1827// NativeCoverageEnabledForPath returns whether (GCOV- or Clang-based) native
1828// code coverage is enabled for path. By default, coverage is not enabled for a
1829// given path unless it is part of the NativeCoveragePaths product variable (and
1830// not part of the NativeCoverageExcludePaths product variable). Value "*" in
1831// NativeCoveragePaths represents any path.
1832func (c *deviceConfig) NativeCoverageEnabledForPath(path string) bool {
1833	coverage := false
1834	if len(c.config.productVariables.NativeCoveragePaths) > 0 {
1835		if InList("*", c.config.productVariables.NativeCoveragePaths) || HasAnyPrefix(path, c.config.productVariables.NativeCoveragePaths) {
1836			coverage = true
1837		}
1838	}
1839	if coverage && len(c.config.productVariables.NativeCoverageExcludePaths) > 0 {
1840		if HasAnyPrefix(path, c.config.productVariables.NativeCoverageExcludePaths) {
1841			coverage = false
1842		}
1843	}
1844	return coverage
1845}
1846
1847func (c *deviceConfig) PgoAdditionalProfileDirs() []string {
1848	return c.config.productVariables.PgoAdditionalProfileDirs
1849}
1850
1851// AfdoProfile returns fully qualified path associated to the given module name
1852func (c *deviceConfig) AfdoProfile(name string) (string, error) {
1853	for _, afdoProfile := range c.config.productVariables.AfdoProfiles {
1854		split := strings.Split(afdoProfile, ":")
1855		if len(split) != 3 {
1856			return "", fmt.Errorf("AFDO_PROFILES has invalid value: %s. "+
1857				"The expected format is <module>:<fully-qualified-path-to-fdo_profile>", afdoProfile)
1858		}
1859		if split[0] == name {
1860			return strings.Join([]string{split[1], split[2]}, ":"), nil
1861		}
1862	}
1863	return "", nil
1864}
1865
1866func (c *deviceConfig) VendorSepolicyDirs() []string {
1867	return c.config.productVariables.BoardVendorSepolicyDirs
1868}
1869
1870func (c *deviceConfig) OdmSepolicyDirs() []string {
1871	return c.config.productVariables.BoardOdmSepolicyDirs
1872}
1873
1874func (c *deviceConfig) SystemExtPublicSepolicyDirs() []string {
1875	return c.config.productVariables.SystemExtPublicSepolicyDirs
1876}
1877
1878func (c *deviceConfig) SystemExtPrivateSepolicyDirs() []string {
1879	return c.config.productVariables.SystemExtPrivateSepolicyDirs
1880}
1881
1882func (c *deviceConfig) SepolicyM4Defs() []string {
1883	return c.config.productVariables.BoardSepolicyM4Defs
1884}
1885
1886func (c *deviceConfig) OverrideManifestPackageNameFor(name string) (manifestName string, overridden bool) {
1887	return findOverrideValue(c.config.productVariables.ManifestPackageNameOverrides, name,
1888		"invalid override rule %q in PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES should be <module_name>:<manifest_name>")
1889}
1890
1891func (c *deviceConfig) OverrideCertificateFor(name string) (certificatePath string, overridden bool) {
1892	return findOverrideValue(c.config.productVariables.CertificateOverrides, name,
1893		"invalid override rule %q in PRODUCT_CERTIFICATE_OVERRIDES should be <module_name>:<certificate_module_name>")
1894}
1895
1896func (c *deviceConfig) OverridePackageNameFor(name string) string {
1897	newName, overridden := findOverrideValue(
1898		c.config.productVariables.PackageNameOverrides,
1899		name,
1900		"invalid override rule %q in PRODUCT_PACKAGE_NAME_OVERRIDES should be <module_name>:<package_name>")
1901	if overridden {
1902		return newName
1903	}
1904	return name
1905}
1906
1907func findOverrideValue(overrides []string, name string, errorMsg string) (newValue string, overridden bool) {
1908	if overrides == nil || len(overrides) == 0 {
1909		return "", false
1910	}
1911	for _, o := range overrides {
1912		split := strings.Split(o, ":")
1913		if len(split) != 2 {
1914			// This shouldn't happen as this is first checked in make, but just in case.
1915			panic(fmt.Errorf(errorMsg, o))
1916		}
1917		if matchPattern(split[0], name) {
1918			return substPattern(split[0], split[1], name), true
1919		}
1920	}
1921	return "", false
1922}
1923
1924func (c *deviceConfig) ApexGlobalMinSdkVersionOverride() string {
1925	return String(c.config.productVariables.ApexGlobalMinSdkVersionOverride)
1926}
1927
1928func (c *config) IntegerOverflowDisabledForPath(path string) bool {
1929	if len(c.productVariables.IntegerOverflowExcludePaths) == 0 {
1930		return false
1931	}
1932	return HasAnyPrefix(path, c.productVariables.IntegerOverflowExcludePaths)
1933}
1934
1935func (c *config) CFIDisabledForPath(path string) bool {
1936	if len(c.productVariables.CFIExcludePaths) == 0 {
1937		return false
1938	}
1939	return HasAnyPrefix(path, c.productVariables.CFIExcludePaths)
1940}
1941
1942func (c *config) CFIEnabledForPath(path string) bool {
1943	if len(c.productVariables.CFIIncludePaths) == 0 {
1944		return false
1945	}
1946	return HasAnyPrefix(path, c.productVariables.CFIIncludePaths) && !c.CFIDisabledForPath(path)
1947}
1948
1949func (c *config) MemtagHeapDisabledForPath(path string) bool {
1950	if len(c.productVariables.MemtagHeapExcludePaths) == 0 {
1951		return false
1952	}
1953	return HasAnyPrefix(path, c.productVariables.MemtagHeapExcludePaths)
1954}
1955
1956func (c *config) MemtagHeapAsyncEnabledForPath(path string) bool {
1957	if len(c.productVariables.MemtagHeapAsyncIncludePaths) == 0 {
1958		return false
1959	}
1960	return HasAnyPrefix(path, c.productVariables.MemtagHeapAsyncIncludePaths) && !c.MemtagHeapDisabledForPath(path)
1961}
1962
1963func (c *config) MemtagHeapSyncEnabledForPath(path string) bool {
1964	if len(c.productVariables.MemtagHeapSyncIncludePaths) == 0 {
1965		return false
1966	}
1967	return HasAnyPrefix(path, c.productVariables.MemtagHeapSyncIncludePaths) && !c.MemtagHeapDisabledForPath(path)
1968}
1969
1970func (c *config) HWASanDisabledForPath(path string) bool {
1971	if len(c.productVariables.HWASanExcludePaths) == 0 {
1972		return false
1973	}
1974	return HasAnyPrefix(path, c.productVariables.HWASanExcludePaths)
1975}
1976
1977func (c *config) HWASanEnabledForPath(path string) bool {
1978	if len(c.productVariables.HWASanIncludePaths) == 0 {
1979		return false
1980	}
1981	return HasAnyPrefix(path, c.productVariables.HWASanIncludePaths) && !c.HWASanDisabledForPath(path)
1982}
1983
1984func (c *config) VendorConfig(name string) VendorConfig {
1985	return soongconfig.Config(c.productVariables.VendorVars[name])
1986}
1987
1988func (c *config) NdkAbis() bool {
1989	return Bool(c.productVariables.Ndk_abis)
1990}
1991
1992func (c *config) AmlAbis() bool {
1993	return Bool(c.productVariables.Aml_abis)
1994}
1995
1996func (c *config) ForceApexSymlinkOptimization() bool {
1997	return Bool(c.productVariables.ForceApexSymlinkOptimization)
1998}
1999
2000func (c *config) ApexCompressionEnabled() bool {
2001	return Bool(c.productVariables.CompressedApex) && !c.UnbundledBuildApps()
2002}
2003
2004func (c *config) DefaultApexPayloadType() string {
2005	return StringDefault(c.productVariables.DefaultApexPayloadType, "ext4")
2006}
2007
2008func (c *config) UseSoongSystemImage() bool {
2009	return Bool(c.productVariables.UseSoongSystemImage)
2010}
2011
2012func (c *config) SoongDefinedSystemImage() string {
2013	if c.UseSoongSystemImage() {
2014		return String(c.productVariables.ProductSoongDefinedSystemImage)
2015	}
2016	return ""
2017}
2018
2019func (c *config) EnforceSystemCertificate() bool {
2020	return Bool(c.productVariables.EnforceSystemCertificate)
2021}
2022
2023func (c *config) EnforceSystemCertificateAllowList() []string {
2024	return c.productVariables.EnforceSystemCertificateAllowList
2025}
2026
2027func (c *config) EnforceProductPartitionInterface() bool {
2028	return Bool(c.productVariables.EnforceProductPartitionInterface)
2029}
2030
2031func (c *config) ProductHiddenAPIStubs() []string {
2032	return c.productVariables.ProductHiddenAPIStubs
2033}
2034
2035func (c *config) ProductHiddenAPIStubsSystem() []string {
2036	return c.productVariables.ProductHiddenAPIStubsSystem
2037}
2038
2039func (c *config) ProductHiddenAPIStubsTest() []string {
2040	return c.productVariables.ProductHiddenAPIStubsTest
2041}
2042
2043func (c *deviceConfig) TargetFSConfigGen() []string {
2044	return c.config.productVariables.TargetFSConfigGen
2045}
2046
2047func (c *config) ProductPublicSepolicyDirs() []string {
2048	return c.productVariables.ProductPublicSepolicyDirs
2049}
2050
2051func (c *config) ProductPrivateSepolicyDirs() []string {
2052	return c.productVariables.ProductPrivateSepolicyDirs
2053}
2054
2055func (c *config) TargetMultitreeUpdateMeta() bool {
2056	return c.productVariables.MultitreeUpdateMeta
2057}
2058
2059func (c *deviceConfig) DeviceArch() string {
2060	return String(c.config.productVariables.DeviceArch)
2061}
2062
2063func (c *deviceConfig) DeviceArchVariant() string {
2064	return String(c.config.productVariables.DeviceArchVariant)
2065}
2066
2067func (c *deviceConfig) DeviceSecondaryArch() string {
2068	return String(c.config.productVariables.DeviceSecondaryArch)
2069}
2070
2071func (c *deviceConfig) DeviceSecondaryArchVariant() string {
2072	return String(c.config.productVariables.DeviceSecondaryArchVariant)
2073}
2074
2075func (c *deviceConfig) BoardUsesRecoveryAsBoot() bool {
2076	return Bool(c.config.productVariables.BoardUsesRecoveryAsBoot)
2077}
2078
2079func (c *deviceConfig) BoardKernelBinaries() []string {
2080	return c.config.productVariables.BoardKernelBinaries
2081}
2082
2083func (c *deviceConfig) BoardKernelModuleInterfaceVersions() []string {
2084	return c.config.productVariables.BoardKernelModuleInterfaceVersions
2085}
2086
2087func (c *deviceConfig) BoardMoveRecoveryResourcesToVendorBoot() bool {
2088	return Bool(c.config.productVariables.BoardMoveRecoveryResourcesToVendorBoot)
2089}
2090
2091func (c *deviceConfig) PlatformSepolicyVersion() string {
2092	return String(c.config.productVariables.PlatformSepolicyVersion)
2093}
2094
2095func (c *deviceConfig) PlatformSepolicyCompatVersions() []string {
2096	return c.config.productVariables.PlatformSepolicyCompatVersions
2097}
2098
2099func (c *deviceConfig) BoardSepolicyVers() string {
2100	if ver := String(c.config.productVariables.BoardSepolicyVers); ver != "" {
2101		return ver
2102	}
2103	return c.PlatformSepolicyVersion()
2104}
2105
2106func (c *deviceConfig) SystemExtSepolicyPrebuiltApiDir() string {
2107	return String(c.config.productVariables.SystemExtSepolicyPrebuiltApiDir)
2108}
2109
2110func (c *deviceConfig) ProductSepolicyPrebuiltApiDir() string {
2111	return String(c.config.productVariables.ProductSepolicyPrebuiltApiDir)
2112}
2113
2114func (c *deviceConfig) IsPartnerTrebleSepolicyTestEnabled() bool {
2115	return c.SystemExtSepolicyPrebuiltApiDir() != "" || c.ProductSepolicyPrebuiltApiDir() != ""
2116}
2117
2118func createDirsMap(previous map[string]bool, dirs []string) (map[string]bool, error) {
2119	var ret = make(map[string]bool)
2120	for _, dir := range dirs {
2121		clean := filepath.Clean(dir)
2122		if previous[clean] || ret[clean] {
2123			return nil, fmt.Errorf("Duplicate entry %s", dir)
2124		}
2125		ret[clean] = true
2126	}
2127	return ret, nil
2128}
2129
2130func (c *deviceConfig) createDirsMapOnce(onceKey OnceKey, previous map[string]bool, dirs []string) map[string]bool {
2131	dirMap := c.Once(onceKey, func() interface{} {
2132		ret, err := createDirsMap(previous, dirs)
2133		if err != nil {
2134			panic(fmt.Errorf("%s: %w", onceKey.key, err))
2135		}
2136		return ret
2137	})
2138	if dirMap == nil {
2139		return nil
2140	}
2141	return dirMap.(map[string]bool)
2142}
2143
2144func (c *deviceConfig) ShippingApiLevel() ApiLevel {
2145	if c.config.productVariables.Shipping_api_level == nil {
2146		return NoneApiLevel
2147	}
2148	apiLevel, _ := strconv.Atoi(*c.config.productVariables.Shipping_api_level)
2149	return uncheckedFinalApiLevel(apiLevel)
2150}
2151
2152func (c *deviceConfig) BuildBrokenPluginValidation() []string {
2153	return c.config.productVariables.BuildBrokenPluginValidation
2154}
2155
2156func (c *deviceConfig) BuildBrokenClangAsFlags() bool {
2157	return c.config.productVariables.BuildBrokenClangAsFlags
2158}
2159
2160func (c *deviceConfig) BuildBrokenClangCFlags() bool {
2161	return c.config.productVariables.BuildBrokenClangCFlags
2162}
2163
2164func (c *deviceConfig) BuildBrokenClangProperty() bool {
2165	return c.config.productVariables.BuildBrokenClangProperty
2166}
2167
2168func (c *deviceConfig) BuildBrokenEnforceSyspropOwner() bool {
2169	return c.config.productVariables.BuildBrokenEnforceSyspropOwner
2170}
2171
2172func (c *deviceConfig) BuildBrokenTrebleSyspropNeverallow() bool {
2173	return c.config.productVariables.BuildBrokenTrebleSyspropNeverallow
2174}
2175
2176func (c *deviceConfig) BuildDebugfsRestrictionsEnabled() bool {
2177	return c.config.productVariables.BuildDebugfsRestrictionsEnabled
2178}
2179
2180func (c *deviceConfig) BuildBrokenVendorPropertyNamespace() bool {
2181	return c.config.productVariables.BuildBrokenVendorPropertyNamespace
2182}
2183
2184func (c *deviceConfig) BuildBrokenInputDir(name string) bool {
2185	return InList(name, c.config.productVariables.BuildBrokenInputDirModules)
2186}
2187
2188func (c *deviceConfig) BuildBrokenDontCheckSystemSdk() bool {
2189	return c.config.productVariables.BuildBrokenDontCheckSystemSdk
2190}
2191
2192func (c *deviceConfig) BuildBrokenDupSysprop() bool {
2193	return c.config.productVariables.BuildBrokenDupSysprop
2194}
2195
2196func (c *config) BuildWarningBadOptionalUsesLibsAllowlist() []string {
2197	return c.productVariables.BuildWarningBadOptionalUsesLibsAllowlist
2198}
2199
2200func (c *deviceConfig) GenruleSandboxing() bool {
2201	return Bool(c.config.productVariables.GenruleSandboxing)
2202}
2203
2204func (c *deviceConfig) RequiresInsecureExecmemForSwiftshader() bool {
2205	return c.config.productVariables.RequiresInsecureExecmemForSwiftshader
2206}
2207
2208func (c *deviceConfig) Release_aidl_use_unfrozen() bool {
2209	return Bool(c.config.productVariables.Release_aidl_use_unfrozen)
2210}
2211
2212func (c *config) SelinuxIgnoreNeverallows() bool {
2213	return c.productVariables.SelinuxIgnoreNeverallows
2214}
2215
2216func (c *deviceConfig) SepolicyFreezeTestExtraDirs() []string {
2217	return c.config.productVariables.SepolicyFreezeTestExtraDirs
2218}
2219
2220func (c *deviceConfig) SepolicyFreezeTestExtraPrebuiltDirs() []string {
2221	return c.config.productVariables.SepolicyFreezeTestExtraPrebuiltDirs
2222}
2223
2224func (c *deviceConfig) GenerateAidlNdkPlatformBackend() bool {
2225	return c.config.productVariables.GenerateAidlNdkPlatformBackend
2226}
2227
2228func (c *deviceConfig) AconfigContainerValidation() string {
2229	return c.config.productVariables.AconfigContainerValidation
2230}
2231
2232func (c *config) IgnorePrefer32OnDevice() bool {
2233	return c.productVariables.IgnorePrefer32OnDevice
2234}
2235
2236func (c *config) BootJars() []string {
2237	return c.Once(earlyBootJarsKey, func() interface{} {
2238		list := c.productVariables.BootJars.CopyOfJars()
2239		return append(list, c.productVariables.ApexBootJars.CopyOfJars()...)
2240	}).([]string)
2241}
2242
2243func (c *config) NonApexBootJars() ConfiguredJarList {
2244	return c.productVariables.BootJars
2245}
2246
2247func (c *config) ApexBootJars() ConfiguredJarList {
2248	return c.productVariables.ApexBootJars
2249}
2250
2251func (c *config) RBEWrapper() string {
2252	return c.GetenvWithDefault("RBE_WRAPPER", remoteexec.DefaultWrapperPath)
2253}
2254
2255// UseHostMusl returns true if the host target has been configured to build against musl libc.
2256func (c *config) UseHostMusl() bool {
2257	return Bool(c.productVariables.HostMusl)
2258}
2259
2260// ApiSurfaces directory returns the source path inside the api_surfaces repo
2261// (relative to workspace root).
2262func (c *config) ApiSurfacesDir(s ApiSurface, version string) string {
2263	return filepath.Join(
2264		"build",
2265		"bazel",
2266		"api_surfaces",
2267		s.String(),
2268		version)
2269}
2270
2271func (c *config) JavaCoverageEnabled() bool {
2272	return c.IsEnvTrue("EMMA_INSTRUMENT") || c.IsEnvTrue("EMMA_INSTRUMENT_STATIC") || c.IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK")
2273}
2274
2275func (c *deviceConfig) BuildFromSourceStub() bool {
2276	return Bool(c.config.productVariables.BuildFromSourceStub)
2277}
2278
2279func (c *config) BuildFromTextStub() bool {
2280	// TODO: b/302320354 - Remove the coverage build specific logic once the
2281	// robust solution for handling native properties in from-text stub build
2282	// is implemented.
2283	return !c.buildFromSourceStub &&
2284		!c.JavaCoverageEnabled() &&
2285		!c.deviceConfig.BuildFromSourceStub()
2286}
2287
2288func (c *config) SetBuildFromTextStub(b bool) {
2289	c.buildFromSourceStub = !b
2290	c.productVariables.Build_from_text_stub = boolPtr(b)
2291}
2292
2293func (c *deviceConfig) CheckVendorSeappViolations() bool {
2294	return Bool(c.config.productVariables.CheckVendorSeappViolations)
2295}
2296
2297func (c *config) GetBuildFlag(name string) (string, bool) {
2298	val, ok := c.productVariables.BuildFlags[name]
2299	return val, ok
2300}
2301
2302func (c *config) UseOptimizedResourceShrinkingByDefault() bool {
2303	return c.productVariables.GetBuildFlagBool("RELEASE_USE_OPTIMIZED_RESOURCE_SHRINKING_BY_DEFAULT")
2304}
2305
2306func (c *config) UseR8FullModeByDefault() bool {
2307	return c.productVariables.GetBuildFlagBool("RELEASE_R8_FULL_MODE_BY_DEFAULT")
2308}
2309
2310func (c *config) UseR8OnlyRuntimeVisibleAnnotations() bool {
2311	return c.productVariables.GetBuildFlagBool("RELEASE_R8_ONLY_RUNTIME_VISIBLE_ANNOTATIONS")
2312}
2313
2314func (c *config) UseR8StoreStoreFenceConstructorInlining() bool {
2315	return c.productVariables.GetBuildFlagBool("RELEASE_R8_STORE_STORE_FENCE_CONSTRUCTOR_INLINING")
2316}
2317
2318func (c *config) UseR8GlobalCheckNotNullFlags() bool {
2319	return c.productVariables.GetBuildFlagBool("RELEASE_R8_GLOBAL_CHECK_NOT_NULL_FLAGS")
2320}
2321
2322func (c *config) UseDexV41() bool {
2323	return c.productVariables.GetBuildFlagBool("RELEASE_USE_DEX_V41")
2324}
2325
2326var (
2327	mainlineApexContributionBuildFlagsToApexNames = map[string]string{
2328		"RELEASE_APEX_CONTRIBUTIONS_ADBD":                    "com.android.adbd",
2329		"RELEASE_APEX_CONTRIBUTIONS_ADSERVICES":              "com.android.adservices",
2330		"RELEASE_APEX_CONTRIBUTIONS_APPSEARCH":               "com.android.appsearch",
2331		"RELEASE_APEX_CONTRIBUTIONS_ART":                     "com.android.art",
2332		"RELEASE_APEX_CONTRIBUTIONS_BLUETOOTH":               "com.android.bt",
2333		"RELEASE_APEX_CONTRIBUTIONS_CAPTIVEPORTALLOGIN":      "",
2334		"RELEASE_APEX_CONTRIBUTIONS_CELLBROADCAST":           "com.android.cellbroadcast",
2335		"RELEASE_APEX_CONTRIBUTIONS_CONFIGINFRASTRUCTURE":    "com.android.configinfrastructure",
2336		"RELEASE_APEX_CONTRIBUTIONS_CONNECTIVITY":            "com.android.tethering",
2337		"RELEASE_APEX_CONTRIBUTIONS_CONSCRYPT":               "com.android.conscrypt",
2338		"RELEASE_APEX_CONTRIBUTIONS_CRASHRECOVERY":           "com.android.crashrecovery",
2339		"RELEASE_APEX_CONTRIBUTIONS_DEVICELOCK":              "com.android.devicelock",
2340		"RELEASE_APEX_CONTRIBUTIONS_DOCUMENTSUIGOOGLE":       "",
2341		"RELEASE_APEX_CONTRIBUTIONS_EXTSERVICES":             "com.android.extservices",
2342		"RELEASE_APEX_CONTRIBUTIONS_HEALTHFITNESS":           "com.android.healthfitness",
2343		"RELEASE_APEX_CONTRIBUTIONS_IPSEC":                   "com.android.ipsec",
2344		"RELEASE_APEX_CONTRIBUTIONS_MEDIA":                   "com.android.media",
2345		"RELEASE_APEX_CONTRIBUTIONS_MEDIAPROVIDER":           "com.android.mediaprovider",
2346		"RELEASE_APEX_CONTRIBUTIONS_MODULE_METADATA":         "",
2347		"RELEASE_APEX_CONTRIBUTIONS_NETWORKSTACKGOOGLE":      "",
2348		"RELEASE_APEX_CONTRIBUTIONS_NEURALNETWORKS":          "com.android.neuralnetworks",
2349		"RELEASE_APEX_CONTRIBUTIONS_NFC":                     "com.android.nfcservices",
2350		"RELEASE_APEX_CONTRIBUTIONS_ONDEVICEPERSONALIZATION": "com.android.ondevicepersonalization",
2351		"RELEASE_APEX_CONTRIBUTIONS_PERMISSION":              "com.android.permission",
2352		"RELEASE_APEX_CONTRIBUTIONS_PROFILING":               "com.android.profiling",
2353		"RELEASE_APEX_CONTRIBUTIONS_REMOTEKEYPROVISIONING":   "com.android.rkpd",
2354		"RELEASE_APEX_CONTRIBUTIONS_RESOLV":                  "com.android.resolv",
2355		"RELEASE_APEX_CONTRIBUTIONS_SCHEDULING":              "com.android.scheduling",
2356		"RELEASE_APEX_CONTRIBUTIONS_SDKEXTENSIONS":           "com.android.sdkext",
2357		"RELEASE_APEX_CONTRIBUTIONS_SWCODEC":                 "com.android.media.swcodec",
2358		"RELEASE_APEX_CONTRIBUTIONS_STATSD":                  "com.android.os.statsd",
2359		"RELEASE_APEX_CONTRIBUTIONS_TELEMETRY_TVP":           "",
2360		"RELEASE_APEX_CONTRIBUTIONS_TZDATA":                  "com.android.tzdata",
2361		"RELEASE_APEX_CONTRIBUTIONS_UPROBESTATS":             "com.android.uprobestats",
2362		"RELEASE_APEX_CONTRIBUTIONS_UWB":                     "com.android.uwb",
2363		"RELEASE_APEX_CONTRIBUTIONS_WIFI":                    "com.android.wifi",
2364	}
2365)
2366
2367// Returns the list of _selected_ apex_contributions
2368// Each mainline module will have one entry in the list
2369func (c *config) AllApexContributions() []string {
2370	ret := []string{}
2371	for _, f := range SortedKeys(mainlineApexContributionBuildFlagsToApexNames) {
2372		if val, exists := c.GetBuildFlag(f); exists && val != "" {
2373			ret = append(ret, val)
2374		}
2375	}
2376	return ret
2377}
2378
2379func (c *config) AllMainlineApexNames() []string {
2380	return SortedStringValues(mainlineApexContributionBuildFlagsToApexNames)
2381}
2382
2383func (c *config) BuildIgnoreApexContributionContents() *bool {
2384	return c.productVariables.BuildIgnoreApexContributionContents
2385}
2386
2387func (c *config) ProductLocales() []string {
2388	return c.productVariables.ProductLocales
2389}
2390
2391func (c *config) ProductDefaultWifiChannels() []string {
2392	return c.productVariables.ProductDefaultWifiChannels
2393}
2394
2395func (c *config) BoardUseVbmetaDigestInFingerprint() bool {
2396	return Bool(c.productVariables.BoardUseVbmetaDigestInFingerprint)
2397}
2398
2399func (c *config) OemProperties() []string {
2400	return c.productVariables.OemProperties
2401}
2402
2403func (c *config) UseDebugArt() bool {
2404	// If the ArtTargetIncludeDebugBuild product variable is set then return its value.
2405	if c.productVariables.ArtTargetIncludeDebugBuild != nil {
2406		return Bool(c.productVariables.ArtTargetIncludeDebugBuild)
2407	}
2408
2409	// If the RELEASE_APEX_CONTRIBUTIONS_ART build flag is set to use a prebuilt ART apex
2410	// then don't use the debug apex.
2411	if val, ok := c.GetBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ART"); ok && val != "" {
2412		return false
2413	}
2414
2415	// Default to the debug apex for eng builds.
2416	return Bool(c.productVariables.Eng)
2417}
2418
2419func (c *config) SystemPropFiles(ctx PathContext) Paths {
2420	return PathsForSource(ctx, c.productVariables.SystemPropFiles)
2421}
2422
2423func (c *config) SystemExtPropFiles(ctx PathContext) Paths {
2424	return PathsForSource(ctx, c.productVariables.SystemExtPropFiles)
2425}
2426
2427func (c *config) ProductPropFiles(ctx PathContext) Paths {
2428	return PathsForSource(ctx, c.productVariables.ProductPropFiles)
2429}
2430
2431func (c *config) OdmPropFiles(ctx PathContext) Paths {
2432	return PathsForSource(ctx, c.productVariables.OdmPropFiles)
2433}
2434
2435func (c *config) VendorPropFiles(ctx PathContext) Paths {
2436	return PathsForSource(ctx, c.productVariables.VendorPropFiles)
2437}
2438
2439func (c *config) EnableUffdGc() string {
2440	return String(c.productVariables.EnableUffdGc)
2441}
2442
2443func (c *config) DeviceFrameworkCompatibilityMatrixFile() []string {
2444	return c.productVariables.DeviceFrameworkCompatibilityMatrixFile
2445}
2446
2447func (c *config) DeviceProductCompatibilityMatrixFile() []string {
2448	return c.productVariables.DeviceProductCompatibilityMatrixFile
2449}
2450
2451func (c *config) BoardAvbEnable() bool {
2452	return Bool(c.productVariables.BoardAvbEnable)
2453}
2454
2455func (c *config) BoardAvbSystemAddHashtreeFooterArgs() []string {
2456	return c.productVariables.BoardAvbSystemAddHashtreeFooterArgs
2457}
2458
2459// Returns true if RELEASE_INSTALL_APEX_SYSTEMSERVER_DEXPREOPT_SAME_PARTITION is set to true.
2460// If true, dexpreopt files of apex system server jars will be installed in the same partition as the parent apex.
2461// If false, all these files will be installed in /system partition.
2462func (c Config) InstallApexSystemServerDexpreoptSamePartition() bool {
2463	return c.config.productVariables.GetBuildFlagBool("RELEASE_INSTALL_APEX_SYSTEMSERVER_DEXPREOPT_SAME_PARTITION")
2464}
2465
2466func (c *config) DeviceMatrixFile() []string {
2467	return c.productVariables.DeviceMatrixFile
2468}
2469
2470func (c *config) ProductManifestFiles() []string {
2471	return c.productVariables.ProductManifestFiles
2472}
2473
2474func (c *config) SystemManifestFile() []string {
2475	return c.productVariables.SystemManifestFile
2476}
2477
2478func (c *config) SystemExtManifestFiles() []string {
2479	return c.productVariables.SystemExtManifestFiles
2480}
2481
2482func (c *config) DeviceManifestFiles() []string {
2483	return c.productVariables.DeviceManifestFiles
2484}
2485
2486func (c *config) OdmManifestFiles() []string {
2487	return c.productVariables.OdmManifestFiles
2488}
2489