Merge "Remove --allowlists" into main
diff --git a/android/apex.go b/android/apex.go
index 79ab13c..e73b3e6 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -833,7 +833,7 @@
// If this is the FinalModule (last visited module) copy
// AnyVariantDirectlyInAnyApex to all the other variants
- if am == mctx.FinalModule().(ApexModule) {
+ if mctx.IsFinalModule(am) {
mctx.VisitAllModuleVariants(func(variant Module) {
variant.(ApexModule).apexModuleBase().ApexProperties.AnyVariantDirectlyInAnyApex =
base.ApexProperties.AnyVariantDirectlyInAnyApex
diff --git a/android/base_module_context.go b/android/base_module_context.go
index 02c0158..060fae5 100644
--- a/android/base_module_context.go
+++ b/android/base_module_context.go
@@ -198,9 +198,15 @@
// singleton actions that are only done once for all variants of a module.
FinalModule() Module
+ // IsFinalModule returns if the current module is the last variant. Variants of a module are always visited in
+ // order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from all
+ // variants using VisitAllModuleVariants if the current module is the last one. This can be used to perform
+ // singleton actions that are only done once for all variants of a module.
+ IsFinalModule(module Module) bool
+
// VisitAllModuleVariants calls visit for each variant of the current module. Variants of a module are always
// visited in order by mutators and GenerateBuildActions, so the data created by the current mutator can be read
- // from all variants if the current module == FinalModule(). Otherwise, care must be taken to not access any
+ // from all variants if the current module is the last one. Otherwise, care must be taken to not access any
// data modified by the current mutator.
VisitAllModuleVariants(visit func(Module))
@@ -592,6 +598,10 @@
return b.bp.FinalModule().(Module)
}
+func (b *baseModuleContext) IsFinalModule(module Module) bool {
+ return b.bp.IsFinalModule(module)
+}
+
// IsMetaDependencyTag returns true for cross-cutting metadata dependencies.
func IsMetaDependencyTag(tag blueprint.DependencyTag) bool {
if tag == licenseKindTag {
diff --git a/android/module.go b/android/module.go
index 6217833..58ae885 100644
--- a/android/module.go
+++ b/android/module.go
@@ -2036,7 +2036,7 @@
ctx.GetMissingDependencies()
}
- if m == ctx.FinalModule().(Module).base() {
+ if ctx.IsFinalModule(m.module) {
m.generateModuleTarget(ctx)
if ctx.Failed() {
return
diff --git a/android/singleton.go b/android/singleton.go
index 6438182..0754b0c 100644
--- a/android/singleton.go
+++ b/android/singleton.go
@@ -81,7 +81,7 @@
VisitAllModuleVariantProxies(module Module, visit func(proxy ModuleProxy))
PrimaryModule(module Module) Module
- FinalModule(module Module) Module
+ IsFinalModule(module Module) bool
AddNinjaFileDeps(deps ...string)
@@ -273,8 +273,8 @@
return s.SingletonContext.PrimaryModule(module).(Module)
}
-func (s *singletonContextAdaptor) FinalModule(module Module) Module {
- return s.SingletonContext.FinalModule(module).(Module)
+func (s *singletonContextAdaptor) IsFinalModule(module Module) bool {
+ return s.SingletonContext.IsFinalModule(module)
}
func (s *singletonContextAdaptor) ModuleVariantsFromName(referer Module, name string) []Module {
diff --git a/android/variable.go b/android/variable.go
index 142fab9..f82c9ca 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -577,6 +577,14 @@
BoardAvbRollbackIndexLocation string `json:",omitempty"`
}
+type ChainedAvbPartitionProps struct {
+ Partitions []string `json:",omitempty"`
+ Key string `json:",omitempty"`
+ Algorithm string `json:",omitempty"`
+ RollbackIndex string `json:",omitempty"`
+ RollbackIndexLocation string `json:",omitempty"`
+}
+
type PartitionVariables struct {
ProductDirectory string `json:",omitempty"`
PartitionQualifiedVariables map[string]PartitionQualifiedVariablesType
@@ -601,7 +609,12 @@
ProductUseDynamicPartitionSize bool `json:",omitempty"`
CopyImagesForTargetFilesZip bool `json:",omitempty"`
- BoardAvbEnable bool `json:",omitempty"`
+ BoardAvbEnable bool `json:",omitempty"`
+ BoardAvbAlgorithm string `json:",omitempty"`
+ BoardAvbKeyPath string `json:",omitempty"`
+ BoardAvbRollbackIndex string `json:",omitempty"`
+ BuildingVbmetaImage bool `json:",omitempty"`
+ ChainedVbmetaPartitions map[string]ChainedAvbPartitionProps `json:",omitempty"`
ProductPackages []string `json:",omitempty"`
ProductPackagesDebug []string `json:",omitempty"`
diff --git a/cc/tidy.go b/cc/tidy.go
index 89bae17..5cbf8f0 100644
--- a/cc/tidy.go
+++ b/cc/tidy.go
@@ -254,7 +254,7 @@
// Collect tidy/obj targets from the 'final' modules.
ctx.VisitAllModules(func(module android.Module) {
- if module == ctx.FinalModule(module) {
+ if ctx.IsFinalModule(module) {
collectTidyObjModuleTargets(ctx, module, tidyModulesInDirGroup, objModulesInDirGroup)
}
})
diff --git a/filesystem/android_device.go b/filesystem/android_device.go
index 9071272..2645dc4 100644
--- a/filesystem/android_device.go
+++ b/filesystem/android_device.go
@@ -34,6 +34,8 @@
Vendor_partition_name *string
// Name of the Odm partition filesystem module
Odm_partition_name *string
+ // The vbmeta partition and its "chained" partitions
+ Vbmeta_partitions []string
}
type androidDevice struct {
@@ -46,7 +48,6 @@
module := &androidDevice{}
module.AddProperties(&module.partitionProps)
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
-
return module
}
@@ -69,6 +70,9 @@
addDependencyIfDefined(a.partitionProps.Product_partition_name)
addDependencyIfDefined(a.partitionProps.Vendor_partition_name)
addDependencyIfDefined(a.partitionProps.Odm_partition_name)
+ for _, vbmetaPartition := range a.partitionProps.Vbmeta_partitions {
+ ctx.AddDependency(ctx.Module(), filesystemDepTag, vbmetaPartition)
+ }
}
func (a *androidDevice) GenerateAndroidBuildActions(ctx android.ModuleContext) {
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 6ed962f..e84139b 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -147,6 +147,8 @@
Erofs ErofsProperties
+ F2fs F2fsProperties
+
Linkerconfig LinkerConfigProperties
// Determines if the module is auto-generated from Soong or not. If the module is
@@ -166,6 +168,11 @@
Sparse *bool
}
+// Additional properties required to generate f2fs FS partitions.
+type F2fsProperties struct {
+ Sparse *bool
+}
+
type LinkerConfigProperties struct {
// Build a linker.config.pb file
@@ -227,6 +234,7 @@
const (
ext4Type fsType = iota
erofsType
+ f2fsType
compressedCpioType
cpioType // uncompressed
unknown
@@ -249,6 +257,8 @@
return ext4Type
case "erofs":
return erofsType
+ case "f2fs":
+ return f2fsType
case "compressed_cpio":
return compressedCpioType
case "cpio":
@@ -289,7 +299,7 @@
func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) {
validatePartitionType(ctx, f)
switch f.fsType(ctx) {
- case ext4Type, erofsType:
+ case ext4Type, erofsType, f2fsType:
f.output = f.buildImageUsingBuildImage(ctx)
case compressedCpioType:
f.output = f.buildCpioImage(ctx, true)
@@ -505,6 +515,8 @@
return "ext4"
case erofsType:
return "erofs"
+ case f2fsType:
+ return "f2fs"
}
panic(fmt.Errorf("unsupported fs type %v", t))
}
@@ -554,8 +566,11 @@
addStr("uuid", uuid)
addStr("hash_seed", uuid)
}
- // Add erofs properties
- if f.fsType(ctx) == erofsType {
+
+ fst := f.fsType(ctx)
+ switch fst {
+ case erofsType:
+ // Add erofs properties
if compressor := f.properties.Erofs.Compressor; compressor != nil {
addStr("erofs_default_compressor", proptools.String(compressor))
}
@@ -566,17 +581,39 @@
// https://source.corp.google.com/h/googleplex-android/platform/build/+/88b1c67239ca545b11580237242774b411f2fed9:core/Makefile;l=2292;bpv=1;bpt=0;drc=ea8f34bc1d6e63656b4ec32f2391e9d54b3ebb6b
addStr("erofs_sparse_flag", "-s")
}
- } else if f.properties.Erofs.Compressor != nil || f.properties.Erofs.Compress_hints != nil || f.properties.Erofs.Sparse != nil {
- // Raise an exception if the propfile contains erofs properties, but the fstype is not erofs
- fs := fsTypeStr(f.fsType(ctx))
- ctx.PropertyErrorf("erofs", "erofs is non-empty, but FS type is %s\n. Please delete erofs properties if this partition should use %s\n", fs, fs)
+ case f2fsType:
+ if proptools.BoolDefault(f.properties.F2fs.Sparse, true) {
+ // https://source.corp.google.com/h/googleplex-android/platform/build/+/88b1c67239ca545b11580237242774b411f2fed9:core/Makefile;l=2294;drc=ea8f34bc1d6e63656b4ec32f2391e9d54b3ebb6b;bpv=1;bpt=0
+ addStr("f2fs_sparse_flag", "-S")
+ }
}
+ f.checkFsTypePropertyError(ctx, fst, fsTypeStr(fst))
propFile = android.PathForModuleOut(ctx, "prop").OutputPath
android.WriteFileRuleVerbatim(ctx, propFile, propFileString.String())
return propFile, deps
}
+// This method checks if there is any property set for the fstype(s) other than
+// the current fstype.
+func (f *filesystem) checkFsTypePropertyError(ctx android.ModuleContext, t fsType, fs string) {
+ raiseError := func(otherFsType, currentFsType string) {
+ errMsg := fmt.Sprintf("%s is non-empty, but FS type is %s\n. Please delete %s properties if this partition should use %s\n", otherFsType, currentFsType, otherFsType, currentFsType)
+ ctx.PropertyErrorf(otherFsType, errMsg)
+ }
+
+ if t != erofsType {
+ if f.properties.Erofs.Compressor != nil || f.properties.Erofs.Compress_hints != nil || f.properties.Erofs.Sparse != nil {
+ raiseError("erofs", fs)
+ }
+ }
+ if t != f2fsType {
+ if f.properties.F2fs.Sparse != nil {
+ raiseError("f2fs", fs)
+ }
+ }
+}
+
func (f *filesystem) buildCpioImage(ctx android.ModuleContext, compressed bool) android.OutputPath {
if proptools.Bool(f.properties.Use_avb) {
ctx.PropertyErrorf("use_avb", "signing compresed cpio image using avbtool is not supported."+
diff --git a/filesystem/filesystem_test.go b/filesystem/filesystem_test.go
index 29f9373..801a175 100644
--- a/filesystem/filesystem_test.go
+++ b/filesystem/filesystem_test.go
@@ -585,6 +585,35 @@
android.AssertStringDoesContain(t, "erofs fs type sparse", buildImageConfig, "erofs_sparse_flag=-s")
}
+func TestF2fsPartition(t *testing.T) {
+ result := fixture.RunTestWithBp(t, `
+ android_filesystem {
+ name: "f2fs_partition",
+ type: "f2fs",
+ }
+ `)
+
+ partition := result.ModuleForTests("f2fs_partition", "android_common")
+ buildImageConfig := android.ContentFromFileRuleForTests(t, result.TestContext, partition.Output("prop"))
+ android.AssertStringDoesContain(t, "f2fs fs type", buildImageConfig, "fs_type=f2fs")
+ android.AssertStringDoesContain(t, "f2fs fs type sparse", buildImageConfig, "f2fs_sparse_flag=-S")
+}
+
+func TestFsTypesPropertyError(t *testing.T) {
+ fixture.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(
+ "erofs: erofs is non-empty, but FS type is f2fs\n. Please delete erofs properties if this partition should use f2fs\n")).
+ RunTestWithBp(t, `
+ android_filesystem {
+ name: "f2fs_partition",
+ type: "f2fs",
+ erofs: {
+ compressor: "lz4hc,9",
+ compress_hints: "compress_hints.txt",
+ },
+ }
+ `)
+}
+
// If a system_ext/ module depends on system/ module, the dependency should *not*
// be installed in system_ext/
func TestDoNotPackageCrossPartitionDependencies(t *testing.T) {
diff --git a/filesystem/vbmeta.go b/filesystem/vbmeta.go
index 0bae479..6a3fc1f 100644
--- a/filesystem/vbmeta.go
+++ b/filesystem/vbmeta.go
@@ -25,19 +25,19 @@
)
func init() {
- android.RegisterModuleType("vbmeta", vbmetaFactory)
+ android.RegisterModuleType("vbmeta", VbmetaFactory)
}
type vbmeta struct {
android.ModuleBase
- properties vbmetaProperties
+ properties VbmetaProperties
output android.OutputPath
installDir android.InstallPath
}
-type vbmetaProperties struct {
+type VbmetaProperties struct {
// Name of the partition stored in vbmeta desc. Defaults to the name of this module.
Partition_name *string
@@ -50,9 +50,8 @@
// Algorithm that avbtool will use to sign this vbmeta image. Default is SHA256_RSA4096.
Algorithm *string
- // File whose content will provide the rollback index. If unspecified, the rollback index
- // is from PLATFORM_SECURITY_PATCH
- Rollback_index_file *string `android:"path"`
+ // The rollback index. If unspecified, the rollback index is from PLATFORM_SECURITY_PATCH
+ Rollback_index *int64
// Rollback index location of this vbmeta image. Must be 0, 1, 2, etc. Default is 0.
Rollback_index_location *int64
@@ -62,7 +61,7 @@
Partitions proptools.Configurable[[]string]
// List of chained partitions that this vbmeta deletages the verification.
- Chained_partitions []chainedPartitionProperties
+ Chained_partitions []ChainedPartitionProperties
// List of key-value pair of avb properties
Avb_properties []avbProperty
@@ -76,7 +75,7 @@
Value *string
}
-type chainedPartitionProperties struct {
+type ChainedPartitionProperties struct {
// Name of the chained partition
Name *string
@@ -95,7 +94,7 @@
}
// vbmeta is the partition image that has the verification information for other partitions.
-func vbmetaFactory() android.Module {
+func VbmetaFactory() android.Module {
module := &vbmeta{}
module.AddProperties(&module.properties)
android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
@@ -217,15 +216,12 @@
// Returns the embedded shell command that prints the rollback index
func (v *vbmeta) rollbackIndexCommand(ctx android.ModuleContext) string {
- var cmd string
- if v.properties.Rollback_index_file != nil {
- f := android.PathForModuleSrc(ctx, proptools.String(v.properties.Rollback_index_file))
- cmd = "cat " + f.String()
+ if v.properties.Rollback_index != nil {
+ return fmt.Sprintf("%d", *v.properties.Rollback_index)
} else {
- cmd = "date -d 'TZ=\"GMT\" " + ctx.Config().PlatformSecurityPatch() + "' +%s"
+ // Take the first line and remove the newline char
+ return "$(date -d 'TZ=\"GMT\" " + ctx.Config().PlatformSecurityPatch() + "' +%s | head -1 | tr -d '\n'" + ")"
}
- // Take the first line and remove the newline char
- return "$(" + cmd + " | head -1 | tr -d '\n'" + ")"
}
// Extract public keys from chained_partitions.private_key. The keys are indexed with the partition
diff --git a/fsgen/Android.bp b/fsgen/Android.bp
index 690ad28..8cd7518 100644
--- a/fsgen/Android.bp
+++ b/fsgen/Android.bp
@@ -16,6 +16,7 @@
"filesystem_creator.go",
"fsgen_mutators.go",
"prebuilt_etc_modules_gen.go",
+ "vbmeta_partitions.go",
],
testSrcs: [
"filesystem_creator_test.go",
diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go
index e884d9a..c9bbf3f 100644
--- a/fsgen/filesystem_creator.go
+++ b/fsgen/filesystem_creator.go
@@ -44,6 +44,9 @@
type filesystemCreatorProps struct {
Generated_partition_types []string `blueprint:"mutated"`
Unsupported_partition_types []string `blueprint:"mutated"`
+
+ Vbmeta_module_names []string `blueprint:"mutated"`
+ Vbmeta_partition_names []string `blueprint:"mutated"`
}
type filesystemCreator struct {
@@ -67,16 +70,24 @@
}
func (f *filesystemCreator) createInternalModules(ctx android.LoadHookContext) {
- soongGeneratedPartitions := &ctx.Config().Get(fsGenStateOnceKey).(*FsGenState).soongGeneratedPartitions
- for _, partitionType := range *soongGeneratedPartitions {
+ soongGeneratedPartitions := generatedPartitions(ctx)
+ finalSoongGeneratedPartitions := make([]string, 0, len(soongGeneratedPartitions))
+ for _, partitionType := range soongGeneratedPartitions {
if f.createPartition(ctx, partitionType) {
f.properties.Generated_partition_types = append(f.properties.Generated_partition_types, partitionType)
+ finalSoongGeneratedPartitions = append(finalSoongGeneratedPartitions, partitionType)
} else {
f.properties.Unsupported_partition_types = append(f.properties.Unsupported_partition_types, partitionType)
- _, *soongGeneratedPartitions = android.RemoveFromList(partitionType, *soongGeneratedPartitions)
}
}
- f.createDeviceModule(ctx)
+
+ for _, x := range createVbmetaPartitions(ctx, finalSoongGeneratedPartitions) {
+ f.properties.Vbmeta_module_names = append(f.properties.Vbmeta_module_names, x.moduleName)
+ f.properties.Vbmeta_partition_names = append(f.properties.Vbmeta_partition_names, x.partitionName)
+ }
+
+ ctx.Config().Get(fsGenStateOnceKey).(*FsGenState).soongGeneratedPartitions = finalSoongGeneratedPartitions
+ f.createDeviceModule(ctx, finalSoongGeneratedPartitions, f.properties.Vbmeta_module_names)
}
func generatedModuleName(cfg android.Config, suffix string) string {
@@ -91,7 +102,11 @@
return generatedModuleName(cfg, fmt.Sprintf("%s_image", partitionType))
}
-func (f *filesystemCreator) createDeviceModule(ctx android.LoadHookContext) {
+func (f *filesystemCreator) createDeviceModule(
+ ctx android.LoadHookContext,
+ generatedPartitionTypes []string,
+ vbmetaPartitions []string,
+) {
baseProps := &struct {
Name *string
}{
@@ -100,21 +115,22 @@
// Currently, only the system and system_ext partition module is created.
partitionProps := &filesystem.PartitionNameProperties{}
- if android.InList("system", f.properties.Generated_partition_types) {
+ if android.InList("system", generatedPartitionTypes) {
partitionProps.System_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system"))
}
- if android.InList("system_ext", f.properties.Generated_partition_types) {
+ if android.InList("system_ext", generatedPartitionTypes) {
partitionProps.System_ext_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_ext"))
}
- if android.InList("vendor", f.properties.Generated_partition_types) {
+ if android.InList("vendor", generatedPartitionTypes) {
partitionProps.Vendor_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor"))
}
- if android.InList("product", f.properties.Generated_partition_types) {
+ if android.InList("product", generatedPartitionTypes) {
partitionProps.Product_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "product"))
}
- if android.InList("odm", f.properties.Generated_partition_types) {
+ if android.InList("odm", generatedPartitionTypes) {
partitionProps.Odm_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "odm"))
}
+ partitionProps.Vbmeta_partitions = vbmetaPartitions
ctx.CreateModule(filesystem.AndroidDeviceFactory, baseProps, partitionProps)
}
@@ -344,12 +360,15 @@
type filesystemBaseProperty struct {
Name *string
Compile_multilib *string
+ Visibility []string
}
func generateBaseProps(namePtr *string) *filesystemBaseProperty {
return &filesystemBaseProperty{
Name: namePtr,
Compile_multilib: proptools.StringPtr("both"),
+ // The vbmeta modules are currently in the root directory and depend on the partitions
+ Visibility: []string{"//.", "//build/soong:__subpackages__"},
}
}
@@ -440,16 +459,42 @@
return file
}
+func createVbmetaDiff(ctx android.ModuleContext, vbmetaModuleName string, vbmetaPartitionName string) android.Path {
+ vbmetaModule := ctx.GetDirectDepWithTag(vbmetaModuleName, generatedVbmetaPartitionDepTag)
+ outputFilesProvider, ok := android.OtherModuleProvider(ctx, vbmetaModule, android.OutputFilesProvider)
+ if !ok {
+ ctx.ModuleErrorf("Expected module %s to provide OutputFiles", vbmetaModule)
+ }
+ if len(outputFilesProvider.DefaultOutputFiles) != 1 {
+ ctx.ModuleErrorf("Expected 1 output file from module %s", vbmetaModule)
+ }
+ soongVbMetaFile := outputFilesProvider.DefaultOutputFiles[0]
+ makeVbmetaFile := android.PathForArbitraryOutput(ctx, fmt.Sprintf("target/product/%s/%s.img", ctx.Config().DeviceName(), vbmetaPartitionName))
+
+ diffTestResultFile := android.PathForModuleOut(ctx, fmt.Sprintf("diff_test_%s.txt", vbmetaModuleName))
+ builder := android.NewRuleBuilder(pctx, ctx)
+ builder.Command().Text("diff").
+ Input(soongVbMetaFile).
+ Input(makeVbmetaFile)
+ builder.Command().Text("touch").Output(diffTestResultFile)
+ builder.Build(vbmetaModuleName+" diff test", vbmetaModuleName+" diff test")
+ return diffTestResultFile
+}
+
type systemImageDepTagType struct {
blueprint.BaseDependencyTag
}
var generatedFilesystemDepTag systemImageDepTagType
+var generatedVbmetaPartitionDepTag systemImageDepTagType
func (f *filesystemCreator) DepsMutator(ctx android.BottomUpMutatorContext) {
for _, partitionType := range f.properties.Generated_partition_types {
ctx.AddDependency(ctx.Module(), generatedFilesystemDepTag, generatedModuleNameForPartition(ctx.Config(), partitionType))
}
+ for _, vbmetaModule := range f.properties.Vbmeta_module_names {
+ ctx.AddDependency(ctx.Module(), generatedVbmetaPartitionDepTag, vbmetaModule)
+ }
}
func (f *filesystemCreator) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -479,6 +524,11 @@
diffTestFiles = append(diffTestFiles, diffTestFile)
ctx.Phony(fmt.Sprintf("soong_generated_%s_filesystem_test", partitionType), diffTestFile)
}
+ for i, vbmetaModule := range f.properties.Vbmeta_module_names {
+ diffTestFile := createVbmetaDiff(ctx, vbmetaModule, f.properties.Vbmeta_partition_names[i])
+ diffTestFiles = append(diffTestFiles, diffTestFile)
+ ctx.Phony(fmt.Sprintf("soong_generated_%s_filesystem_test", f.properties.Vbmeta_partition_names[i]), diffTestFile)
+ }
ctx.Phony("soong_generated_filesystem_tests", diffTestFiles...)
}
diff --git a/fsgen/fsgen_mutators.go b/fsgen/fsgen_mutators.go
index f3aec00..92ea128 100644
--- a/fsgen/fsgen_mutators.go
+++ b/fsgen/fsgen_mutators.go
@@ -145,7 +145,6 @@
},
"system_dlkm": {},
},
- soongGeneratedPartitions: generatedPartitions(ctx),
fsDepsMutex: sync.Mutex{},
moduleToInstallationProps: map[string]installationProperties{},
}
diff --git a/fsgen/vbmeta_partitions.go b/fsgen/vbmeta_partitions.go
new file mode 100644
index 0000000..280e405
--- /dev/null
+++ b/fsgen/vbmeta_partitions.go
@@ -0,0 +1,184 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// 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 fsgen
+
+import (
+ "android/soong/android"
+ "android/soong/filesystem"
+ "slices"
+ "strconv"
+
+ "github.com/google/blueprint/proptools"
+)
+
+type vbmetaModuleInfo struct {
+ // The name of the generated vbmeta module
+ moduleName string
+ // The name of the module that avb understands. This is the name passed to --chain_partition,
+ // and also the basename of the output file. (the output file is called partitionName + ".img")
+ partitionName string
+}
+
+// Creates the vbmeta partition and the chained vbmeta partitions. Returns the list of module names
+// that the function created. May return nil if the product isn't using avb.
+//
+// AVB is Android Verified Boot: https://source.android.com/docs/security/features/verifiedboot
+// It works by signing all the partitions, but then also including an extra metadata paritition
+// called vbmeta that depends on all the other signed partitions. This creates a requirement
+// that you update all those partitions and the vbmeta partition together, so in order to relax
+// that requirement products can set up "chained" vbmeta partitions, where a chained partition
+// like vbmeta_system might contain the avb metadata for just a few products. In cuttlefish
+// vbmeta_system contains metadata about product, system, and system_ext. Using chained partitions,
+// that group of partitions can be updated independently from the other signed partitions.
+func createVbmetaPartitions(ctx android.LoadHookContext, generatedPartitionTypes []string) []vbmetaModuleInfo {
+ partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
+ // Some products seem to have BuildingVbmetaImage as true even when BoardAvbEnable is false
+ if !partitionVars.BuildingVbmetaImage || !partitionVars.BoardAvbEnable {
+ return nil
+ }
+
+ var result []vbmetaModuleInfo
+
+ var chainedPartitions []filesystem.ChainedPartitionProperties
+ var partitionTypesHandledByChainedPartitions []string
+ for chainedName, props := range partitionVars.ChainedVbmetaPartitions {
+ chainedName = "vbmeta_" + chainedName
+ if len(props.Partitions) == 0 {
+ continue
+ }
+ if len(props.Key) == 0 {
+ ctx.ModuleErrorf("No key found for chained avb partition %q", chainedName)
+ continue
+ }
+ if len(props.Algorithm) == 0 {
+ ctx.ModuleErrorf("No algorithm found for chained avb partition %q", chainedName)
+ continue
+ }
+ if len(props.RollbackIndex) == 0 {
+ ctx.ModuleErrorf("No rollback index found for chained avb partition %q", chainedName)
+ continue
+ }
+ ril, err := strconv.ParseInt(props.RollbackIndexLocation, 10, 32)
+ if err != nil {
+ ctx.ModuleErrorf("Rollback index location must be an int, got %q", props.RollbackIndexLocation)
+ continue
+ }
+ // The default is to use the PlatformSecurityPatch, and a lot of product config files
+ // just set it to the platform security patch, so detect that and don't set the property
+ // in soong.
+ var rollbackIndex *int64
+ if props.RollbackIndex != ctx.Config().PlatformSecurityPatch() {
+ i, err := strconv.ParseInt(props.RollbackIndex, 10, 32)
+ if err != nil {
+ ctx.ModuleErrorf("Rollback index must be an int, got %q", props.RollbackIndex)
+ continue
+ }
+ rollbackIndex = &i
+ }
+
+ var partitionModules []string
+ for _, partition := range props.Partitions {
+ partitionTypesHandledByChainedPartitions = append(partitionTypesHandledByChainedPartitions, partition)
+ if !slices.Contains(generatedPartitionTypes, partition) {
+ // The partition is probably unsupported.
+ continue
+ }
+ partitionModules = append(partitionModules, generatedModuleNameForPartition(ctx.Config(), partition))
+ }
+
+ name := generatedModuleName(ctx.Config(), chainedName)
+ ctx.CreateModuleInDirectory(
+ filesystem.VbmetaFactory,
+ ".", // Create in the root directory for now so its easy to get the key
+ &filesystem.VbmetaProperties{
+ Partition_name: proptools.StringPtr(chainedName),
+ Stem: proptools.StringPtr(chainedName + ".img"),
+ Private_key: proptools.StringPtr(props.Key),
+ Algorithm: &props.Algorithm,
+ Rollback_index: rollbackIndex,
+ Rollback_index_location: &ril,
+ Partitions: proptools.NewSimpleConfigurable(partitionModules),
+ }, &struct {
+ Name *string
+ }{
+ Name: &name,
+ },
+ ).HideFromMake()
+
+ chainedPartitions = append(chainedPartitions, filesystem.ChainedPartitionProperties{
+ Name: &chainedName,
+ Rollback_index_location: &ril,
+ Private_key: &props.Key,
+ })
+
+ result = append(result, vbmetaModuleInfo{
+ moduleName: name,
+ partitionName: chainedName,
+ })
+ }
+
+ vbmetaModuleName := generatedModuleName(ctx.Config(), "vbmeta")
+
+ var algorithm *string
+ var ri *int64
+ var key *string
+ if len(partitionVars.BoardAvbKeyPath) == 0 {
+ // Match make's defaults: https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=4568;drc=5b55f926830963c02ab1d2d91e46442f04ba3af0
+ key = proptools.StringPtr("external/avb/test/data/testkey_rsa4096.pem")
+ algorithm = proptools.StringPtr("SHA256_RSA4096")
+ } else {
+ key = proptools.StringPtr(partitionVars.BoardAvbKeyPath)
+ algorithm = proptools.StringPtr(partitionVars.BoardAvbAlgorithm)
+ }
+ if len(partitionVars.BoardAvbRollbackIndex) > 0 {
+ parsedRi, err := strconv.ParseInt(partitionVars.BoardAvbRollbackIndex, 10, 32)
+ if err != nil {
+ ctx.ModuleErrorf("Rollback index location must be an int, got %q", partitionVars.BoardAvbRollbackIndex)
+ }
+ ri = &parsedRi
+ }
+
+ var partitionModules []string
+ for _, partitionType := range generatedPartitionTypes {
+ if slices.Contains(partitionTypesHandledByChainedPartitions, partitionType) {
+ // Already handled by a chained vbmeta partition
+ continue
+ }
+ partitionModules = append(partitionModules, generatedModuleNameForPartition(ctx.Config(), partitionType))
+ }
+
+ ctx.CreateModuleInDirectory(
+ filesystem.VbmetaFactory,
+ ".", // Create in the root directory for now so its easy to get the key
+ &filesystem.VbmetaProperties{
+ Stem: proptools.StringPtr("vbmeta.img"),
+ Algorithm: algorithm,
+ Private_key: key,
+ Rollback_index: ri,
+ Chained_partitions: chainedPartitions,
+ Partitions: proptools.NewSimpleConfigurable(partitionModules),
+ }, &struct {
+ Name *string
+ }{
+ Name: &vbmetaModuleName,
+ },
+ ).HideFromMake()
+
+ result = append(result, vbmetaModuleInfo{
+ moduleName: vbmetaModuleName,
+ partitionName: "vbmeta",
+ })
+ return result
+}
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index 1a33680..7c0f544 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -520,7 +520,7 @@
// be output to Make but it does not really matter which variant is output. The default/platform
// variant is the first (ctx.PrimaryModule()) and is usually hidden from make so this just picks
// the last variant (ctx.FinalModule()).
- if ctx.Module() != ctx.FinalModule() {
+ if !ctx.IsFinalModule(ctx.Module()) {
b.HideFromMake()
}
}