summaryrefslogtreecommitdiff
path: root/android
diff options
context:
space:
mode:
Diffstat (limited to 'android')
-rw-r--r--android/Android.bp1
-rw-r--r--android/apex.go198
-rw-r--r--android/apex_test.go23
-rw-r--r--android/build_prop.go21
-rw-r--r--android/config.go8
-rw-r--r--android/container.go4
-rw-r--r--android/module.go2
-rw-r--r--android/module_context.go5
-rw-r--r--android/packaging.go6
-rw-r--r--android/prebuilt_test.go5
-rw-r--r--android/rule_builder.go40
-rw-r--r--android/rule_builder_test.go64
-rw-r--r--android/sbom.go18
-rw-r--r--android/selects_test.go48
-rw-r--r--android/test_config.go1
-rw-r--r--android/variable.go33
-rw-r--r--android/vendor_api_levels.go49
17 files changed, 190 insertions, 336 deletions
diff --git a/android/Android.bp b/android/Android.bp
index a9a3564ab..dfea8f999 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -111,6 +111,7 @@ bootstrap_go_package {
"testing.go",
"util.go",
"variable.go",
+ "vendor_api_levels.go",
"vintf_fragment.go",
"vintf_data.go",
"visibility.go",
diff --git a/android/apex.go b/android/apex.go
index 9277ff31b..db9391204 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -16,7 +16,6 @@ package android
import (
"fmt"
- "reflect"
"slices"
"sort"
"strconv"
@@ -62,19 +61,6 @@ type ApexInfo struct {
// that are merged together.
InApexVariants []string
- // List of APEX Soong module names that this module is part of. Note that the list includes
- // different variations of the same APEX. For example, if module `foo` is included in the
- // apex `com.android.foo`, and also if there is an override_apex module
- // `com.mycompany.android.foo` overriding `com.android.foo`, then this list contains both
- // `com.android.foo` and `com.mycompany.android.foo`. If the APEX Soong module is a
- // prebuilt, the name here doesn't have the `prebuilt_` prefix.
- InApexModules []string
-
- // Pointers to the ApexContents struct each of which is for apexBundle modules that this
- // module is part of. The ApexContents gives information about which modules the apexBundle
- // has and whether a module became part of the apexBundle via a direct dependency or not.
- ApexContents []*ApexContents
-
// True if this is for a prebuilt_apex.
//
// If true then this will customize the apex processing to make it suitable for handling
@@ -105,7 +91,6 @@ func (i ApexInfo) AddJSONData(d *map[string]interface{}) {
(*d)["Apex"] = map[string]interface{}{
"ApexVariationName": i.ApexVariationName,
"MinSdkVersion": i.MinSdkVersion,
- "InApexModules": i.InApexModules,
"InApexVariants": i.InApexVariants,
"ForPrebuiltApex": i.ForPrebuiltApex,
}
@@ -140,15 +125,6 @@ func (i ApexInfo) InApexVariant(apexVariant string) bool {
return false
}
-func (i ApexInfo) InApexModule(apexModuleName string) bool {
- for _, a := range i.InApexModules {
- if a == apexModuleName {
- return true
- }
- }
- return false
-}
-
// To satisfy the comparable interface
func (i ApexInfo) Equal(other any) bool {
otherApexInfo, ok := other.(ApexInfo)
@@ -156,13 +132,11 @@ func (i ApexInfo) Equal(other any) bool {
i.MinSdkVersion == otherApexInfo.MinSdkVersion &&
i.Updatable == otherApexInfo.Updatable &&
i.UsePlatformApis == otherApexInfo.UsePlatformApis &&
- reflect.DeepEqual(i.InApexVariants, otherApexInfo.InApexVariants) &&
- reflect.DeepEqual(i.InApexModules, otherApexInfo.InApexModules)
+ slices.Equal(i.InApexVariants, otherApexInfo.InApexVariants)
}
// ApexBundleInfo contains information about the dependencies of an apex
type ApexBundleInfo struct {
- Contents *ApexContents
}
var ApexBundleInfoProvider = blueprint.NewMutatorProvider[ApexBundleInfo]("apex_info")
@@ -220,15 +194,8 @@ type ApexModule interface {
// this after apex.apexMutator is run.
InAnyApex() bool
- // Returns true if this module is directly in any APEX. Call this AFTER apex.apexMutator is
- // run.
- DirectlyInAnyApex() bool
-
- // NotInPlatform tells whether or not this module is included in an APEX and therefore
- // shouldn't be exposed to the platform (i.e. outside of the APEX) directly. A module is
- // considered to be included in an APEX either when there actually is an APEX that
- // explicitly has the module as its dependency or the module is not available to the
- // platform, which indicates that the module belongs to at least one or more other APEXes.
+ // NotInPlatform returns true if the module is not available to the platform due to
+ // apex_available being set and not containing "//apex_available:platform".
NotInPlatform() bool
// Tests if this module could have APEX variants. Even when a module type implements
@@ -285,20 +252,6 @@ type ApexProperties struct {
// Default is ["//apex_available:platform"].
Apex_available []string
- // See ApexModule.InAnyApex()
- InAnyApex bool `blueprint:"mutated"`
-
- // See ApexModule.DirectlyInAnyApex()
- DirectlyInAnyApex bool `blueprint:"mutated"`
-
- // AnyVariantDirectlyInAnyApex is true in the primary variant of a module if _any_ variant
- // of the module is directly in any apex. This includes host, arch, asan, etc. variants. It
- // is unused in any variant that is not the primary variant. Ideally this wouldn't be used,
- // as it incorrectly mixes arch variants if only one arch is in an apex, but a few places
- // depend on it, for example when an ASAN variant is created before the apexMutator. Call
- // this after apex.apexMutator is run.
- AnyVariantDirectlyInAnyApex bool `blueprint:"mutated"`
-
// See ApexModule.NotAvailableForPlatform()
NotAvailableForPlatform bool `blueprint:"mutated"`
@@ -335,16 +288,6 @@ type AlwaysRequireApexVariantTag interface {
AlwaysRequireApexVariant() bool
}
-// Marker interface that identifies dependencies that should inherit the DirectlyInAnyApex state
-// from the parent to the child. For example, stubs libraries are marked as DirectlyInAnyApex if
-// their implementation is in an apex.
-type CopyDirectlyInAnyApexTag interface {
- blueprint.DependencyTag
-
- // Method that differentiates this interface from others.
- CopyDirectlyInAnyApex()
-}
-
// Interface that identifies dependencies to skip Apex dependency check
type SkipApexAllowedDependenciesCheck interface {
// Returns true to skip the Apex dependency check, which limits the allowed dependency in build.
@@ -395,40 +338,27 @@ func (m *ApexModuleBase) ApexAvailable() []string {
func (m *ApexModuleBase) BuildForApex(apex ApexInfo) {
m.apexInfosLock.Lock()
defer m.apexInfosLock.Unlock()
- for i, v := range m.apexInfos {
- if v.ApexVariationName == apex.ApexVariationName {
- if len(apex.InApexModules) != 1 {
- panic(fmt.Errorf("Newly created apexInfo must be for a single APEX"))
- }
- // Even when the ApexVariantNames are the same, the given ApexInfo might
- // actually be for different APEX. This can happen when an APEX is
- // overridden via override_apex. For example, there can be two apexes
- // `com.android.foo` (from the `apex` module type) and
- // `com.mycompany.android.foo` (from the `override_apex` module type), both
- // of which has the same ApexVariantName `com.android.foo`. Add the apex
- // name to the list so that it's not lost.
- if !InList(apex.InApexModules[0], v.InApexModules) {
- m.apexInfos[i].InApexModules = append(m.apexInfos[i].InApexModules, apex.InApexModules[0])
- }
- return
- }
+ if slices.ContainsFunc(m.apexInfos, func(existing ApexInfo) bool {
+ return existing.ApexVariationName == apex.ApexVariationName
+ }) {
+ return
}
m.apexInfos = append(m.apexInfos, apex)
}
// Implements ApexModule
func (m *ApexModuleBase) InAnyApex() bool {
- return m.ApexProperties.InAnyApex
-}
-
-// Implements ApexModule
-func (m *ApexModuleBase) DirectlyInAnyApex() bool {
- return m.ApexProperties.DirectlyInAnyApex
+ for _, apex_name := range m.ApexProperties.Apex_available {
+ if apex_name != AvailableToPlatform {
+ return true
+ }
+ }
+ return false
}
// Implements ApexModule
func (m *ApexModuleBase) NotInPlatform() bool {
- return m.ApexProperties.AnyVariantDirectlyInAnyApex || !m.AvailableFor(AvailableToPlatform)
+ return !m.AvailableFor(AvailableToPlatform)
}
// Implements ApexModule
@@ -585,8 +515,6 @@ func mergeApexVariations(apexInfos []ApexInfo) (merged []ApexInfo, aliases [][2]
if index, exists := seen[mergedName]; exists {
// Variants having the same mergedName are deduped
merged[index].InApexVariants = append(merged[index].InApexVariants, variantName)
- merged[index].InApexModules = append(merged[index].InApexModules, apexInfo.InApexModules...)
- merged[index].ApexContents = append(merged[index].ApexContents, apexInfo.ApexContents...)
merged[index].Updatable = merged[index].Updatable || apexInfo.Updatable
// Platform APIs is allowed for this module only when all APEXes containing
// the module are with `use_platform_apis: true`.
@@ -596,8 +524,6 @@ func mergeApexVariations(apexInfos []ApexInfo) (merged []ApexInfo, aliases [][2]
seen[mergedName] = len(merged)
apexInfo.ApexVariationName = mergedName
apexInfo.InApexVariants = CopyOf(apexInfo.InApexVariants)
- apexInfo.InApexModules = CopyOf(apexInfo.InApexModules)
- apexInfo.ApexContents = append([]*ApexContents(nil), apexInfo.ApexContents...)
apexInfo.TestApexes = CopyOf(apexInfo.TestApexes)
merged = append(merged, apexInfo)
}
@@ -685,15 +611,6 @@ func MutateApexTransition(ctx BaseModuleContext, variation string) {
apexInfos, _ = mergeApexVariations(apexInfos)
}
- var inApex ApexMembership
- for _, a := range apexInfos {
- for _, apexContents := range a.ApexContents {
- inApex = inApex.merge(apexContents.contents[ctx.ModuleName()])
- }
- }
- base.ApexProperties.InAnyApex = true
- base.ApexProperties.DirectlyInAnyApex = inApex == directlyInApex
-
if platformVariation && !ctx.Host() && !module.AvailableFor(AvailableToPlatform) && module.NotAvailableForPlatform() {
// Do not install the module for platform, but still allow it to output
// uninstallable AndroidMk entries in certain cases when they have side
@@ -783,93 +700,6 @@ func UpdateUniqueApexVariationsForDeps(mctx BottomUpMutatorContext, am ApexModul
})
}
-// UpdateDirectlyInAnyApex uses the final module to store if any variant of this module is directly
-// in any APEX, and then copies the final value to all the modules. It also copies the
-// DirectlyInAnyApex value to any transitive dependencies with a CopyDirectlyInAnyApexTag
-// dependency tag.
-func UpdateDirectlyInAnyApex(mctx BottomUpMutatorContext, am ApexModule) {
- base := am.apexModuleBase()
- // Copy DirectlyInAnyApex and InAnyApex from any transitive dependencies with a
- // CopyDirectlyInAnyApexTag dependency tag.
- mctx.WalkDeps(func(child, parent Module) bool {
- if _, ok := mctx.OtherModuleDependencyTag(child).(CopyDirectlyInAnyApexTag); ok {
- depBase := child.(ApexModule).apexModuleBase()
- depBase.apexPropertiesLock.Lock()
- defer depBase.apexPropertiesLock.Unlock()
- depBase.ApexProperties.DirectlyInAnyApex = base.ApexProperties.DirectlyInAnyApex
- depBase.ApexProperties.InAnyApex = base.ApexProperties.InAnyApex
- return true
- }
- return false
- })
-
- if base.ApexProperties.DirectlyInAnyApex {
- // Variants of a module are always visited sequentially in order, so it is safe to
- // write to another variant of this module. For a BottomUpMutator the
- // PrimaryModule() is visited first and FinalModule() is visited last.
- mctx.FinalModule().(ApexModule).apexModuleBase().ApexProperties.AnyVariantDirectlyInAnyApex = true
- }
-
- // If this is the FinalModule (last visited module) copy
- // AnyVariantDirectlyInAnyApex to all the other variants
- if mctx.IsFinalModule(am) {
- mctx.VisitAllModuleVariants(func(variant Module) {
- variant.(ApexModule).apexModuleBase().ApexProperties.AnyVariantDirectlyInAnyApex =
- base.ApexProperties.AnyVariantDirectlyInAnyApex
- })
- }
-}
-
-// ApexMembership tells how a module became part of an APEX.
-type ApexMembership int
-
-const (
- notInApex ApexMembership = 0
- indirectlyInApex = iota
- directlyInApex
-)
-
-// ApexContents gives an information about member modules of an apexBundle. Each apexBundle has an
-// apexContents, and modules in that apex have a provider containing the apexContents of each
-// apexBundle they are part of.
-type ApexContents struct {
- // map from a module name to its membership in this apexBundle
- contents map[string]ApexMembership
-}
-
-// NewApexContents creates and initializes an ApexContents that is suitable
-// for use with an apex module.
-// - contents is a map from a module name to information about its membership within
-// the apex.
-func NewApexContents(contents map[string]ApexMembership) *ApexContents {
- return &ApexContents{
- contents: contents,
- }
-}
-
-// Updates an existing membership by adding a new direct (or indirect) membership
-func (i ApexMembership) Add(direct bool) ApexMembership {
- if direct || i == directlyInApex {
- return directlyInApex
- }
- return indirectlyInApex
-}
-
-// Merges two membership into one. Merging is needed because a module can be a part of an apexBundle
-// in many different paths. For example, it could be dependend on by the apexBundle directly, but at
-// the same time, there might be an indirect dependency to the module. In that case, the more
-// specific dependency (the direct one) is chosen.
-func (i ApexMembership) merge(other ApexMembership) ApexMembership {
- if other == directlyInApex || i == directlyInApex {
- return directlyInApex
- }
-
- if other == indirectlyInApex || i == indirectlyInApex {
- return indirectlyInApex
- }
- return notInApex
-}
-
////////////////////////////////////////////////////////////////////////////////////////////////////
//Below are routines for extra safety checks.
//
diff --git a/android/apex_test.go b/android/apex_test.go
index 347bf7d98..78597b234 100644
--- a/android/apex_test.go
+++ b/android/apex_test.go
@@ -37,7 +37,6 @@ func Test_mergeApexVariations(t *testing.T) {
ApexVariationName: "foo",
MinSdkVersion: FutureApiLevel,
InApexVariants: []string{"foo"},
- InApexModules: []string{"foo"},
ForPrebuiltApex: NotForPrebuiltApex,
},
},
@@ -46,7 +45,6 @@ func Test_mergeApexVariations(t *testing.T) {
ApexVariationName: "apex10000",
MinSdkVersion: FutureApiLevel,
InApexVariants: []string{"foo"},
- InApexModules: []string{"foo"},
ForPrebuiltApex: NotForPrebuiltApex,
},
},
@@ -61,14 +59,12 @@ func Test_mergeApexVariations(t *testing.T) {
ApexVariationName: "foo",
MinSdkVersion: FutureApiLevel,
InApexVariants: []string{"foo"},
- InApexModules: []string{"foo"},
ForPrebuiltApex: NotForPrebuiltApex,
},
{
ApexVariationName: "bar",
MinSdkVersion: FutureApiLevel,
InApexVariants: []string{"bar"},
- InApexModules: []string{"bar"},
ForPrebuiltApex: NotForPrebuiltApex,
},
},
@@ -77,7 +73,6 @@ func Test_mergeApexVariations(t *testing.T) {
ApexVariationName: "apex10000",
MinSdkVersion: FutureApiLevel,
InApexVariants: []string{"foo", "bar"},
- InApexModules: []string{"foo", "bar"},
}},
wantAliases: [][2]string{
{"foo", "apex10000"},
@@ -91,14 +86,12 @@ func Test_mergeApexVariations(t *testing.T) {
ApexVariationName: "foo",
MinSdkVersion: FutureApiLevel,
InApexVariants: []string{"foo"},
- InApexModules: []string{"foo"},
ForPrebuiltApex: NotForPrebuiltApex,
},
{
ApexVariationName: "bar",
MinSdkVersion: uncheckedFinalApiLevel(30),
InApexVariants: []string{"bar"},
- InApexModules: []string{"bar"},
ForPrebuiltApex: NotForPrebuiltApex,
},
},
@@ -107,14 +100,12 @@ func Test_mergeApexVariations(t *testing.T) {
ApexVariationName: "apex10000",
MinSdkVersion: FutureApiLevel,
InApexVariants: []string{"foo"},
- InApexModules: []string{"foo"},
ForPrebuiltApex: NotForPrebuiltApex,
},
{
ApexVariationName: "apex30",
MinSdkVersion: uncheckedFinalApiLevel(30),
InApexVariants: []string{"bar"},
- InApexModules: []string{"bar"},
ForPrebuiltApex: NotForPrebuiltApex,
},
},
@@ -130,7 +121,6 @@ func Test_mergeApexVariations(t *testing.T) {
ApexVariationName: "foo",
MinSdkVersion: FutureApiLevel,
InApexVariants: []string{"foo"},
- InApexModules: []string{"foo"},
ForPrebuiltApex: NotForPrebuiltApex,
},
{
@@ -138,7 +128,6 @@ func Test_mergeApexVariations(t *testing.T) {
MinSdkVersion: FutureApiLevel,
Updatable: true,
InApexVariants: []string{"bar"},
- InApexModules: []string{"bar"},
ForPrebuiltApex: NotForPrebuiltApex,
},
},
@@ -148,7 +137,6 @@ func Test_mergeApexVariations(t *testing.T) {
MinSdkVersion: FutureApiLevel,
Updatable: true,
InApexVariants: []string{"foo", "bar"},
- InApexModules: []string{"foo", "bar"},
ForPrebuiltApex: NotForPrebuiltApex,
},
},
@@ -164,7 +152,6 @@ func Test_mergeApexVariations(t *testing.T) {
ApexVariationName: "foo",
MinSdkVersion: FutureApiLevel,
InApexVariants: []string{"foo"},
- InApexModules: []string{"foo"},
ForPrebuiltApex: NotForPrebuiltApex,
},
{
@@ -172,7 +159,6 @@ func Test_mergeApexVariations(t *testing.T) {
MinSdkVersion: FutureApiLevel,
Updatable: true,
InApexVariants: []string{"bar"},
- InApexModules: []string{"bar"},
ForPrebuiltApex: NotForPrebuiltApex,
},
// This one should not be merged in with the others because it is for
@@ -182,7 +168,6 @@ func Test_mergeApexVariations(t *testing.T) {
MinSdkVersion: FutureApiLevel,
Updatable: true,
InApexVariants: []string{"baz"},
- InApexModules: []string{"baz"},
ForPrebuiltApex: ForPrebuiltApex,
},
},
@@ -192,7 +177,6 @@ func Test_mergeApexVariations(t *testing.T) {
MinSdkVersion: FutureApiLevel,
Updatable: true,
InApexVariants: []string{"foo", "bar"},
- InApexModules: []string{"foo", "bar"},
ForPrebuiltApex: NotForPrebuiltApex,
},
{
@@ -200,7 +184,6 @@ func Test_mergeApexVariations(t *testing.T) {
MinSdkVersion: FutureApiLevel,
Updatable: true,
InApexVariants: []string{"baz"},
- InApexModules: []string{"baz"},
ForPrebuiltApex: ForPrebuiltApex,
},
},
@@ -216,7 +199,6 @@ func Test_mergeApexVariations(t *testing.T) {
ApexVariationName: "foo",
MinSdkVersion: FutureApiLevel,
InApexVariants: []string{"foo"},
- InApexModules: []string{"foo"},
ForPrebuiltApex: NotForPrebuiltApex,
},
{
@@ -224,7 +206,6 @@ func Test_mergeApexVariations(t *testing.T) {
MinSdkVersion: FutureApiLevel,
UsePlatformApis: true,
InApexVariants: []string{"bar"},
- InApexModules: []string{"bar"},
ForPrebuiltApex: NotForPrebuiltApex,
},
},
@@ -233,7 +214,6 @@ func Test_mergeApexVariations(t *testing.T) {
ApexVariationName: "apex10000",
MinSdkVersion: FutureApiLevel,
InApexVariants: []string{"foo", "bar"},
- InApexModules: []string{"foo", "bar"},
ForPrebuiltApex: NotForPrebuiltApex,
},
},
@@ -250,7 +230,6 @@ func Test_mergeApexVariations(t *testing.T) {
MinSdkVersion: FutureApiLevel,
UsePlatformApis: true,
InApexVariants: []string{"foo"},
- InApexModules: []string{"foo"},
ForPrebuiltApex: NotForPrebuiltApex,
},
{
@@ -258,7 +237,6 @@ func Test_mergeApexVariations(t *testing.T) {
MinSdkVersion: FutureApiLevel,
UsePlatformApis: true,
InApexVariants: []string{"bar"},
- InApexModules: []string{"bar"},
ForPrebuiltApex: NotForPrebuiltApex,
},
},
@@ -268,7 +246,6 @@ func Test_mergeApexVariations(t *testing.T) {
MinSdkVersion: FutureApiLevel,
UsePlatformApis: true,
InApexVariants: []string{"foo", "bar"},
- InApexModules: []string{"foo", "bar"},
ForPrebuiltApex: NotForPrebuiltApex,
},
},
diff --git a/android/build_prop.go b/android/build_prop.go
index cda56f1e0..2f71bc03f 100644
--- a/android/build_prop.go
+++ b/android/build_prop.go
@@ -15,6 +15,8 @@
package android
import (
+ "fmt"
+
"github.com/google/blueprint/proptools"
)
@@ -173,7 +175,16 @@ func (p *buildPropModule) GenerateAndroidBuildActions(ctx ModuleContext) {
postProcessCmd.Text(outputFilePath.String())
postProcessCmd.Flags(p.properties.Block_list)
- rule.Command().Text("echo").Text(proptools.NinjaAndShellEscape("# end of file")).FlagWithArg(">> ", outputFilePath.String())
+ for _, footer := range p.properties.Footer_files {
+ path := PathForModuleSrc(ctx, footer)
+ rule.appendText(outputFilePath, "####################################")
+ rule.appendTextf(outputFilePath, "# Adding footer from %v", footer)
+ rule.appendTextf(outputFilePath, "# with path %v", path)
+ rule.appendText(outputFilePath, "####################################")
+ rule.Command().Text("cat").FlagWithInput("", path).FlagWithArg(">> ", outputFilePath.String())
+ }
+
+ rule.appendText(outputFilePath, "# end of file")
rule.Build(ctx.ModuleName(), "generating build.prop")
@@ -184,6 +195,14 @@ func (p *buildPropModule) GenerateAndroidBuildActions(ctx ModuleContext) {
p.outputFilePath = outputFilePath
}
+func (r *RuleBuilder) appendText(path ModuleOutPath, text string) {
+ r.Command().Text("echo").Text(proptools.NinjaAndShellEscape(text)).FlagWithArg(">> ", path.String())
+}
+
+func (r *RuleBuilder) appendTextf(path ModuleOutPath, format string, a ...any) {
+ r.appendText(path, fmt.Sprintf(format, a...))
+}
+
func (p *buildPropModule) AndroidMkEntries() []AndroidMkEntries {
return []AndroidMkEntries{{
Class: "ETC",
diff --git a/android/config.go b/android/config.go
index 27d3b87ba..dff3ea5bd 100644
--- a/android/config.go
+++ b/android/config.go
@@ -285,6 +285,10 @@ func (c Config) ReleaseCreateAconfigStorageFile() bool {
return c.config.productVariables.GetBuildFlagBool("RELEASE_CREATE_ACONFIG_STORAGE_FILE")
}
+func (c Config) ReleaseUseSystemFeatureBuildFlags() bool {
+ return c.config.productVariables.GetBuildFlagBool("RELEASE_USE_SYSTEM_FEATURE_BUILD_FLAGS")
+}
+
// A DeviceConfig object represents the configuration for a particular device
// being built. For now there will only be one of these, but in the future there
// may be multiple devices being built.
@@ -1834,6 +1838,10 @@ func (c *config) ApexCompressionEnabled() bool {
return Bool(c.productVariables.CompressedApex) && !c.UnbundledBuildApps()
}
+func (c *config) DefaultApexPayloadType() string {
+ return StringDefault(c.productVariables.DefaultApexPayloadType, "ext4")
+}
+
func (c *config) UseSoongSystemImage() bool {
return Bool(c.productVariables.UseSoongSystemImage)
}
diff --git a/android/container.go b/android/container.go
index 2a3777b30..27b17ed99 100644
--- a/android/container.go
+++ b/android/container.go
@@ -93,7 +93,7 @@ var globallyAllowlistedDependencies = []string{
// TODO(b/363016634): Remove from the allowlist when the module is converted
// to java_sdk_library and the java_aconfig_library modules depend on the stub.
- "aconfig_storage_reader_java",
+ "aconfig_storage_stub",
// framework-res provides core resources essential for building apps and system UI.
// This module is implicitly added as a dependency for java modules even when the
@@ -382,7 +382,7 @@ func (c *ContainersInfo) BelongingContainers() []*container {
func (c *ContainersInfo) ApexNames() (ret []string) {
for _, apex := range c.belongingApexes {
- ret = append(ret, apex.InApexModules...)
+ ret = append(ret, apex.InApexVariants...)
}
slices.Sort(ret)
return ret
diff --git a/android/module.go b/android/module.go
index 686a90ef0..5437d48ee 100644
--- a/android/module.go
+++ b/android/module.go
@@ -2455,6 +2455,8 @@ func (e configurationEvalutor) EvaluateConfiguration(condition proptools.Configu
return proptools.ConfigurableValueString(v)
case "bool":
return proptools.ConfigurableValueBool(v == "true")
+ case "string_list":
+ return proptools.ConfigurableValueStringList(strings.Split(v, " "))
default:
panic("unhandled soong config variable type: " + ty)
}
diff --git a/android/module_context.go b/android/module_context.go
index 20149074e..ae7b54f66 100644
--- a/android/module_context.go
+++ b/android/module_context.go
@@ -831,6 +831,11 @@ func (m *moduleContext) ModuleInfoJSON() *ModuleInfoJSON {
}
func (m *moduleContext) SetOutputFiles(outputFiles Paths, tag string) {
+ for _, outputFile := range outputFiles {
+ if outputFile == nil {
+ panic("outputfiles cannot be nil")
+ }
+ }
if tag == "" {
if len(m.outputFiles.DefaultOutputFiles) > 0 {
m.ModuleErrorf("Module %s default OutputFiles cannot be overwritten", m.ModuleName())
diff --git a/android/packaging.go b/android/packaging.go
index e71d983eb..dcd8844f0 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -410,9 +410,9 @@ func (PackagingItemAlwaysDepTag) IsPackagingItem() bool {
return true
}
-// highPriorityDepTag provides default implementation of HighPriorityPackagingItem interface.
type highPriorityDepTag struct {
- blueprint.DependencyTag
+ blueprint.BaseDependencyTag
+ PackagingItemAlwaysDepTag
}
// See PackageModule.AddDeps
@@ -433,7 +433,7 @@ func (p *PackagingBase) AddDeps(ctx BottomUpMutatorContext, depTag blueprint.Dep
}
depTagToUse := depTag
if highPriority {
- depTagToUse = highPriorityDepTag{depTag}
+ depTagToUse = highPriorityDepTag{}
}
ctx.AddFarVariationDependencies(targetVariation, depTagToUse, dep)
diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go
index 5e4af0ba5..b90ef3b1c 100644
--- a/android/prebuilt_test.go
+++ b/android/prebuilt_test.go
@@ -508,11 +508,10 @@ func (p *prebuiltModule) Name() string {
}
func (p *prebuiltModule) GenerateAndroidBuildActions(ctx ModuleContext) {
- var src Path
if len(p.properties.Srcs) >= 1 {
- src = p.prebuilt.SingleSourcePath(ctx)
+ src := p.prebuilt.SingleSourcePath(ctx)
+ ctx.SetOutputFiles(Paths{src}, "")
}
- ctx.SetOutputFiles(Paths{src}, "")
}
func (p *prebuiltModule) Prebuilt() *Prebuilt {
diff --git a/android/rule_builder.go b/android/rule_builder.go
index 403c18418..83f8b9992 100644
--- a/android/rule_builder.go
+++ b/android/rule_builder.go
@@ -488,21 +488,15 @@ func (r *RuleBuilder) depFileMergerCmd(depFiles WritablePaths) *RuleBuilderComma
Inputs(depFiles.Paths())
}
-// BuildWithNinjaVars adds the built command line to the build graph, with dependencies on Inputs and Tools, and output files for
-// Outputs. This function will not escape Ninja variables, so it may be used to write sandbox manifests using Ninja variables.
-func (r *RuleBuilder) BuildWithUnescapedNinjaVars(name string, desc string) {
- r.build(name, desc, false)
-}
-
// Build adds the built command line to the build graph, with dependencies on Inputs and Tools, and output files for
// Outputs.
func (r *RuleBuilder) Build(name string, desc string) {
- r.build(name, desc, true)
+ r.build(name, desc)
}
var sandboxEnvOnceKey = NewOnceKey("sandbox_environment_variables")
-func (r *RuleBuilder) build(name string, desc string, ninjaEscapeCommandString bool) {
+func (r *RuleBuilder) build(name string, desc string) {
name = ninjaNameEscape(name)
if len(r.missingDeps) > 0 {
@@ -611,6 +605,7 @@ func (r *RuleBuilder) build(name string, desc string, ninjaEscapeCommandString b
nsjailCmd.WriteString(" -m none:/tmp:tmpfs:size=1073741824") // 1GB, should be enough
nsjailCmd.WriteString(" -D nsjail_build_sandbox")
nsjailCmd.WriteString(" --disable_rlimits")
+ nsjailCmd.WriteString(" --skip_setsid") // ABFS relies on process-groups to track file operations
nsjailCmd.WriteString(" -q")
nsjailCmd.WriteString(" -- ")
nsjailCmd.WriteString("/bin/bash -c ")
@@ -764,30 +759,7 @@ func (r *RuleBuilder) build(name string, desc string, ninjaEscapeCommandString b
if err != nil {
ReportPathErrorf(r.ctx, "sbox manifest failed to marshal: %q", err)
}
- if ninjaEscapeCommandString {
- WriteFileRule(r.ctx, r.sboxManifestPath, string(pbText))
- } else {
- // We need to have a rule to write files that is
- // defined on the RuleBuilder's pctx in order to
- // write Ninja variables in the string.
- // The WriteFileRule function above rule can only write
- // raw strings because it is defined on the android
- // package's pctx, and it can't access variables defined
- // in another context.
- r.ctx.Build(r.pctx, BuildParams{
- Rule: r.ctx.Rule(r.pctx, "unescapedWriteFile", blueprint.RuleParams{
- Command: `rm -rf ${out} && cat ${out}.rsp > ${out}`,
- Rspfile: "${out}.rsp",
- RspfileContent: "${content}",
- Description: "write file",
- }, "content"),
- Output: r.sboxManifestPath,
- Description: "write sbox manifest " + r.sboxManifestPath.Base(),
- Args: map[string]string{
- "content": string(pbText),
- },
- })
- }
+ WriteFileRule(r.ctx, r.sboxManifestPath, string(pbText))
// Generate a new string to use as the command line of the sbox rule. This uses
// a RuleBuilderCommand as a convenience method of building the command line, then
@@ -881,9 +853,7 @@ func (r *RuleBuilder) build(name string, desc string, ninjaEscapeCommandString b
pool = localPool
}
- if ninjaEscapeCommandString {
- commandString = proptools.NinjaEscape(commandString)
- }
+ commandString = proptools.NinjaEscape(commandString)
args_vars := make([]string, len(r.args))
i := 0
diff --git a/android/rule_builder_test.go b/android/rule_builder_test.go
index 6a8a964a1..e1a1e08c4 100644
--- a/android/rule_builder_test.go
+++ b/android/rule_builder_test.go
@@ -475,10 +475,9 @@ type testRuleBuilderModule struct {
Srcs []string
Flags []string
- Restat bool
- Sbox bool
- Sbox_inputs bool
- Unescape_ninja_vars bool
+ Restat bool
+ Sbox bool
+ Sbox_inputs bool
}
}
@@ -498,7 +497,7 @@ func (t *testRuleBuilderModule) GenerateAndroidBuildActions(ctx ModuleContext) {
testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, t.properties.Flags,
out, outDep, outDir,
- manifestPath, t.properties.Restat, t.properties.Sbox, t.properties.Sbox_inputs, t.properties.Unescape_ninja_vars,
+ manifestPath, t.properties.Restat, t.properties.Sbox, t.properties.Sbox_inputs,
rspFile, rspFileContents, rspFile2, rspFileContents2)
}
@@ -523,14 +522,14 @@ func (t *testRuleBuilderSingleton) GenerateBuildActions(ctx SingletonContext) {
manifestPath := PathForOutput(ctx, "singleton/sbox.textproto")
testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, nil, out, outDep, outDir,
- manifestPath, true, false, false, false,
+ manifestPath, true, false, false,
rspFile, rspFileContents, rspFile2, rspFileContents2)
}
func testRuleBuilder_Build(ctx BuilderContext, in Paths, implicit, orderOnly, validation Path,
flags []string,
out, outDep, outDir, manifestPath WritablePath,
- restat, sbox, sboxInputs, unescapeNinjaVars bool,
+ restat, sbox, sboxInputs bool,
rspFile WritablePath, rspFileContents Paths, rspFile2 WritablePath, rspFileContents2 Paths) {
rule := NewRuleBuilder(pctx_ruleBuilderTest, ctx)
@@ -558,11 +557,7 @@ func testRuleBuilder_Build(ctx BuilderContext, in Paths, implicit, orderOnly, va
rule.Restat()
}
- if unescapeNinjaVars {
- rule.BuildWithUnescapedNinjaVars("rule", "desc")
- } else {
- rule.Build("rule", "desc")
- }
+ rule.Build("rule", "desc")
}
var prepareForRuleBuilderTest = FixtureRegisterWithContext(func(ctx RegistrationContext) {
@@ -777,48 +772,3 @@ func TestRuleBuilderHashInputs(t *testing.T) {
})
}
}
-
-func TestRuleBuilderWithNinjaVarEscaping(t *testing.T) {
- bp := `
- rule_builder_test {
- name: "foo_sbox_escaped",
- flags: ["${cmdFlags}"],
- sbox: true,
- sbox_inputs: true,
- }
- rule_builder_test {
- name: "foo_sbox_unescaped",
- flags: ["${cmdFlags}"],
- sbox: true,
- sbox_inputs: true,
- unescape_ninja_vars: true,
- }
- `
- result := GroupFixturePreparers(
- prepareForRuleBuilderTest,
- FixtureWithRootAndroidBp(bp),
- ).RunTest(t)
-
- escapedNinjaMod := result.ModuleForTests("foo_sbox_escaped", "").Output("sbox.textproto")
- AssertStringEquals(t, "expected rule", "android/soong/android.rawFileCopy", escapedNinjaMod.Rule.String())
- AssertStringDoesContain(
- t,
- "",
- ContentFromFileRuleForTests(t, result.TestContext, escapedNinjaMod),
- "${cmdFlags}",
- )
-
- unescapedNinjaMod := result.ModuleForTests("foo_sbox_unescaped", "").Rule("unescapedWriteFile")
- AssertStringDoesContain(
- t,
- "",
- unescapedNinjaMod.BuildParams.Args["content"],
- "${cmdFlags}",
- )
- AssertStringDoesNotContain(
- t,
- "",
- unescapedNinjaMod.BuildParams.Args["content"],
- "$${cmdFlags}",
- )
-}
diff --git a/android/sbom.go b/android/sbom.go
index 2a5499ed8..f2b9c0ff1 100644
--- a/android/sbom.go
+++ b/android/sbom.go
@@ -15,9 +15,7 @@
package android
import (
- "io"
"path/filepath"
- "strings"
"github.com/google/blueprint"
)
@@ -55,21 +53,7 @@ func (this *sbomSingleton) GenerateBuildActions(ctx SingletonContext) {
if !ctx.Config().HasDeviceProduct() {
return
}
- // Get all METADATA files and add them as implicit input
- metadataFileListFile := PathForArbitraryOutput(ctx, ".module_paths", "METADATA.list")
- f, err := ctx.Config().fs.Open(metadataFileListFile.String())
- if err != nil {
- panic(err)
- }
- b, err := io.ReadAll(f)
- if err != nil {
- panic(err)
- }
- allMetadataFiles := strings.Split(string(b), "\n")
- implicits := []Path{metadataFileListFile}
- for _, path := range allMetadataFiles {
- implicits = append(implicits, PathForSource(ctx, path))
- }
+ implicits := []Path{}
prodVars := ctx.Config().productVariables
buildFingerprintFile := PathForArbitraryOutput(ctx, "target", "product", String(prodVars.DeviceName), "build_fingerprint.txt")
implicits = append(implicits, buildFingerprintFile)
diff --git a/android/selects_test.go b/android/selects_test.go
index 90d7091e0..1397ed8b7 100644
--- a/android/selects_test.go
+++ b/android/selects_test.go
@@ -1031,6 +1031,54 @@ my_module_type {
my_string_list: &[]string{"d2", "e2", "f2", "a1", "b1", "c1"},
},
},
+ {
+ name: "string list variables",
+ bp: `
+my_module_type {
+ name: "foo",
+ my_string_list: ["a"] + select(soong_config_variable("my_namespace", "my_var"), {
+ any @ my_var: my_var,
+ default: [],
+ }),
+}
+`,
+ vendorVars: map[string]map[string]string{
+ "my_namespace": {
+ "my_var": "b c",
+ },
+ },
+ vendorVarTypes: map[string]map[string]string{
+ "my_namespace": {
+ "my_var": "string_list",
+ },
+ },
+ provider: selectsTestProvider{
+ my_string_list: &[]string{"a", "b", "c"},
+ },
+ },
+ {
+ name: "string list variables don't match string matchers",
+ bp: `
+my_module_type {
+ name: "foo",
+ my_string_list: ["a"] + select(soong_config_variable("my_namespace", "my_var"), {
+ "foo": ["b"],
+ default: [],
+ }),
+}
+`,
+ vendorVars: map[string]map[string]string{
+ "my_namespace": {
+ "my_var": "b c",
+ },
+ },
+ vendorVarTypes: map[string]map[string]string{
+ "my_namespace": {
+ "my_var": "string_list",
+ },
+ },
+ expectedError: `Expected all branches of a select on condition soong_config_variable\("my_namespace", "my_var"\) to have type string_list, found string`,
+ },
}
for _, tc := range testCases {
diff --git a/android/test_config.go b/android/test_config.go
index f2510387f..3609e6b78 100644
--- a/android/test_config.go
+++ b/android/test_config.go
@@ -45,6 +45,7 @@ func TestConfig(buildDir string, env map[string]string, bp string, fs map[string
Platform_version_active_codenames: []string{"S", "Tiramisu"},
DeviceSystemSdkVersions: []string{"29", "30", "S"},
Platform_systemsdk_versions: []string{"29", "30", "S", "Tiramisu"},
+ VendorApiLevel: stringPtr("202404"),
AAPTConfig: []string{"normal", "large", "xlarge", "hdpi", "xhdpi", "xxhdpi"},
AAPTPreferredConfig: stringPtr("xhdpi"),
AAPTCharacteristics: stringPtr("nosdcard"),
diff --git a/android/variable.go b/android/variable.go
index 2d43c6da4..36ddc1c81 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -408,9 +408,10 @@ type ProductVariables struct {
Ndk_abis *bool `json:",omitempty"`
- ForceApexSymlinkOptimization *bool `json:",omitempty"`
- CompressedApex *bool `json:",omitempty"`
- Aml_abis *bool `json:",omitempty"`
+ ForceApexSymlinkOptimization *bool `json:",omitempty"`
+ CompressedApex *bool `json:",omitempty"`
+ DefaultApexPayloadType *string `json:",omitempty"`
+ Aml_abis *bool `json:",omitempty"`
DexpreoptGlobalConfig *string `json:",omitempty"`
@@ -609,15 +610,25 @@ type PartitionVariables struct {
ProductUseDynamicPartitionSize bool `json:",omitempty"`
CopyImagesForTargetFilesZip bool `json:",omitempty"`
+ VendorSecurityPatch string `json:",omitempty"`
+
// Boot image stuff
- ProductBuildBootImage bool `json:",omitempty"`
- ProductBuildInitBootImage bool `json:",omitempty"`
- BoardUsesRecoveryAsBoot bool `json:",omitempty"`
- BoardPrebuiltBootimage string `json:",omitempty"`
- BoardPrebuiltInitBootimage string `json:",omitempty"`
- BoardBootimagePartitionSize string `json:",omitempty"`
- BoardInitBootimagePartitionSize string `json:",omitempty"`
- BoardBootHeaderVersion string `json:",omitempty"`
+ BuildingRamdiskImage bool `json:",omitempty"`
+ ProductBuildBootImage bool `json:",omitempty"`
+ ProductBuildVendorBootImage string `json:",omitempty"`
+ ProductBuildInitBootImage bool `json:",omitempty"`
+ BoardUsesRecoveryAsBoot bool `json:",omitempty"`
+ BoardPrebuiltBootimage string `json:",omitempty"`
+ BoardPrebuiltInitBootimage string `json:",omitempty"`
+ BoardBootimagePartitionSize string `json:",omitempty"`
+ BoardInitBootimagePartitionSize string `json:",omitempty"`
+ BoardBootHeaderVersion string `json:",omitempty"`
+ TargetKernelPath string `json:",omitempty"`
+ BoardUsesGenericKernelImage bool `json:",omitempty"`
+ BootSecurityPatch string `json:",omitempty"`
+ InitBootSecurityPatch string `json:",omitempty"`
+ BoardIncludeDtbInBootimg bool `json:",omitempty"`
+ InternalKernelCmdline []string `json:",omitempty"`
// Avb (android verified boot) stuff
BoardAvbEnable bool `json:",omitempty"`
diff --git a/android/vendor_api_levels.go b/android/vendor_api_levels.go
new file mode 100644
index 000000000..4d364fde6
--- /dev/null
+++ b/android/vendor_api_levels.go
@@ -0,0 +1,49 @@
+// Copyright 2024 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android
+
+import (
+ "fmt"
+ "strconv"
+)
+
+func getSdkVersionOfVendorApiLevel(apiLevel int) (int, bool) {
+ ok := true
+ sdkVersion := -1
+ switch apiLevel {
+ case 202404:
+ sdkVersion = 35
+ case 202504:
+ sdkVersion = 36
+ default:
+ ok = false
+ }
+ return sdkVersion, ok
+}
+
+func GetSdkVersionForVendorApiLevel(vendorApiLevel string) (ApiLevel, error) {
+ vendorApiLevelInt, err := strconv.Atoi(vendorApiLevel)
+ if err != nil {
+ return NoneApiLevel, fmt.Errorf("The vendor API level %q must be able to be parsed as an integer", vendorApiLevel)
+ }
+ if vendorApiLevelInt < 35 {
+ return uncheckedFinalApiLevel(vendorApiLevelInt), nil
+ }
+
+ if sdkInt, ok := getSdkVersionOfVendorApiLevel(vendorApiLevelInt); ok {
+ return uncheckedFinalApiLevel(sdkInt), nil
+ }
+ return NoneApiLevel, fmt.Errorf("Unknown vendor API level %q. Requires updating the map in vendor_api_level.go?", vendorApiLevel)
+}