Merge "Make rollback_index configurable" into main
diff --git a/android/Android.bp b/android/Android.bp
index 4b75148..00dc50a 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -171,7 +171,3 @@
// Used by plugins
visibility: ["//visibility:public"],
}
-
-otatools_package_filegroup {
- name: "otatools_package_filegroup",
-}
diff --git a/android/arch_list.go b/android/arch_list.go
index 389f194..8659549 100644
--- a/android/arch_list.go
+++ b/android/arch_list.go
@@ -27,6 +27,8 @@
"armv8-2a-dotprod",
"armv9-a",
"armv9-2a",
+ "armv9-3a",
+ "armv9-4a",
},
X86: {
"alderlake",
@@ -151,6 +153,12 @@
"armv9-2a": {
"dotprod",
},
+ "armv9-3a": {
+ "dotprod",
+ },
+ "armv9-4a": {
+ "dotprod",
+ },
},
X86: {
"alderlake": {
diff --git a/android/config.go b/android/config.go
index d47f0d4..52d7f3b 100644
--- a/android/config.go
+++ b/android/config.go
@@ -22,6 +22,7 @@
"fmt"
"os"
"path/filepath"
+ "reflect"
"runtime"
"strconv"
"strings"
@@ -108,6 +109,10 @@
const testKeyDir = "build/make/target/product/security"
+func (c Config) genericConfig() Config {
+ return Config{c.config.genericConfig}
+}
+
// SoongOutDir returns the build output directory for the configuration.
func (c Config) SoongOutDir() string {
return c.soongOutDir
@@ -372,7 +377,7 @@
// regenerate build.ninja.
ninjaFileDepsSet sync.Map
- OncePer
+ *OncePer
// If buildFromSourceStub is true then the Java API stubs are
// built from the source Java files, not the signature text files.
@@ -382,6 +387,17 @@
// modules that aren't mixed-built for at least one variant will cause a build
// failure
ensureAllowlistIntegrity bool
+
+ // If isGeneric is true, this config is the generic config.
+ isGeneric bool
+
+ // InstallPath requires the device name.
+ // This is only for the installPath.
+ deviceNameToInstall *string
+
+ // Copy of this config struct but some product-specific variables are
+ // replaced with the generic configuration values.
+ genericConfig *config
}
type partialCompileFlags struct {
@@ -639,11 +655,9 @@
}
}
-// NewConfig creates a new Config object. The srcDir argument specifies the path
-// to the root source directory. It also loads the config file, if found.
-func NewConfig(cmdArgs CmdArgs, availableEnv map[string]string) (Config, error) {
+func initConfig(cmdArgs CmdArgs, availableEnv map[string]string) (*config, error) {
// Make a config with default options.
- config := &config{
+ newConfig := &config{
ProductVariablesFileName: cmdArgs.SoongVariables,
env: availableEnv,
@@ -657,70 +671,72 @@
moduleListFile: cmdArgs.ModuleListFile,
fs: pathtools.NewOsFs(absSrcDir),
+ OncePer: &OncePer{},
+
buildFromSourceStub: cmdArgs.BuildFromSourceStub,
}
variant, ok := os.LookupEnv("TARGET_BUILD_VARIANT")
isEngBuild := !ok || variant == "eng"
- config.deviceConfig = &deviceConfig{
- config: config,
+ newConfig.deviceConfig = &deviceConfig{
+ config: newConfig,
}
// Soundness check of the build and source directories. This won't catch strange
// configurations with symlinks, but at least checks the obvious case.
absBuildDir, err := filepath.Abs(cmdArgs.SoongOutDir)
if err != nil {
- return Config{}, err
+ return &config{}, err
}
absSrcDir, err := filepath.Abs(".")
if err != nil {
- return Config{}, err
+ return &config{}, err
}
if strings.HasPrefix(absSrcDir, absBuildDir) {
- return Config{}, fmt.Errorf("Build dir must not contain source directory")
+ return &config{}, fmt.Errorf("Build dir must not contain source directory")
}
// Load any configurable options from the configuration file
- err = loadConfig(config)
+ err = loadConfig(newConfig)
if err != nil {
- return Config{}, err
+ return &config{}, err
}
KatiEnabledMarkerFile := filepath.Join(cmdArgs.SoongOutDir, ".soong.kati_enabled")
if _, err := os.Stat(absolutePath(KatiEnabledMarkerFile)); err == nil {
- config.katiEnabled = true
+ newConfig.katiEnabled = true
}
- determineBuildOS(config)
+ determineBuildOS(newConfig)
// Sets up the map of target OSes to the finer grained compilation targets
// that are configured from the product variables.
- targets, err := decodeTargetProductVariables(config)
+ targets, err := decodeTargetProductVariables(newConfig)
if err != nil {
- return Config{}, err
+ return &config{}, err
}
- config.partialCompileFlags, err = config.parsePartialCompileFlags(isEngBuild)
+ newConfig.partialCompileFlags, err = newConfig.parsePartialCompileFlags(isEngBuild)
if err != nil {
- return Config{}, err
+ return &config{}, err
}
// Make the CommonOS OsType available for all products.
targets[CommonOS] = []Target{commonTargetMap[CommonOS.Name]}
var archConfig []archConfig
- if config.NdkAbis() {
+ if newConfig.NdkAbis() {
archConfig = getNdkAbisConfig()
- } else if config.AmlAbis() {
+ } else if newConfig.AmlAbis() {
archConfig = getAmlAbisConfig()
}
if archConfig != nil {
androidTargets, err := decodeAndroidArchSettings(archConfig)
if err != nil {
- return Config{}, err
+ return &config{}, err
}
targets[Android] = androidTargets
}
@@ -728,37 +744,113 @@
multilib := make(map[string]bool)
for _, target := range targets[Android] {
if seen := multilib[target.Arch.ArchType.Multilib]; seen {
- config.multilibConflicts[target.Arch.ArchType] = true
+ newConfig.multilibConflicts[target.Arch.ArchType] = true
}
multilib[target.Arch.ArchType.Multilib] = true
}
// Map of OS to compilation targets.
- config.Targets = targets
+ newConfig.Targets = targets
// Compilation targets for host tools.
- config.BuildOSTarget = config.Targets[config.BuildOS][0]
- config.BuildOSCommonTarget = getCommonTargets(config.Targets[config.BuildOS])[0]
+ newConfig.BuildOSTarget = newConfig.Targets[newConfig.BuildOS][0]
+ newConfig.BuildOSCommonTarget = getCommonTargets(newConfig.Targets[newConfig.BuildOS])[0]
// Compilation targets for Android.
- if len(config.Targets[Android]) > 0 {
- config.AndroidCommonTarget = getCommonTargets(config.Targets[Android])[0]
- config.AndroidFirstDeviceTarget = FirstTarget(config.Targets[Android], "lib64", "lib32")[0]
+ if len(newConfig.Targets[Android]) > 0 {
+ newConfig.AndroidCommonTarget = getCommonTargets(newConfig.Targets[Android])[0]
+ newConfig.AndroidFirstDeviceTarget = FirstTarget(newConfig.Targets[Android], "lib64", "lib32")[0]
}
setBuildMode := func(arg string, mode SoongBuildMode) {
if arg != "" {
- if config.BuildMode != AnalysisNoBazel {
+ if newConfig.BuildMode != AnalysisNoBazel {
fmt.Fprintf(os.Stderr, "buildMode is already set, illegal argument: %s", arg)
os.Exit(1)
}
- config.BuildMode = mode
+ newConfig.BuildMode = mode
}
}
setBuildMode(cmdArgs.ModuleGraphFile, GenerateModuleGraph)
setBuildMode(cmdArgs.DocFile, GenerateDocFile)
- config.productVariables.Build_from_text_stub = boolPtr(config.BuildFromTextStub())
+ newConfig.productVariables.Build_from_text_stub = boolPtr(newConfig.BuildFromTextStub())
+
+ newConfig.deviceNameToInstall = newConfig.productVariables.DeviceName
+
+ return newConfig, err
+}
+
+// Replace variables in config.productVariables that have tags with "generic" key.
+// A generic tag may have a string or an int value for the generic configuration.
+// If the value is "unset", generic configuration will unset the variable.
+func overrideGenericConfig(config *config) {
+ config.genericConfig.isGeneric = true
+ type_pv := reflect.TypeOf(config.genericConfig.productVariables)
+ value_pv := reflect.ValueOf(&config.genericConfig.productVariables)
+ for i := range type_pv.NumField() {
+ type_pv_field := type_pv.Field(i)
+ generic_value := type_pv_field.Tag.Get("generic")
+ // If a product variable has an annotation of "generic" tag, use the
+ // value of the tag to set the generic variable.
+ if generic_value != "" {
+ value_pv_field := value_pv.Elem().Field(i)
+
+ if generic_value == "unset" {
+ // unset the product variable
+ value_pv_field.SetZero()
+ continue
+ }
+
+ kind_of_type_pv := type_pv_field.Type.Kind()
+ is_pointer := false
+ if kind_of_type_pv == reflect.Pointer {
+ is_pointer = true
+ kind_of_type_pv = type_pv_field.Type.Elem().Kind()
+ }
+
+ switch kind_of_type_pv {
+ case reflect.String:
+ if is_pointer {
+ value_pv_field.Set(reflect.ValueOf(stringPtr(generic_value)))
+ } else {
+ value_pv_field.Set(reflect.ValueOf(generic_value))
+ }
+ case reflect.Int:
+ generic_int, err := strconv.Atoi(generic_value)
+ if err != nil {
+ panic(fmt.Errorf("Only an int value can be assigned to int variable: %s", err))
+ }
+ if is_pointer {
+ value_pv_field.Set(reflect.ValueOf(intPtr(generic_int)))
+ } else {
+ value_pv_field.Set(reflect.ValueOf(generic_int))
+ }
+ default:
+ panic(fmt.Errorf("Unknown type to replace for generic variable: %s", &kind_of_type_pv))
+ }
+ }
+ }
+
+ // OncePer must be a singleton.
+ config.genericConfig.OncePer = config.OncePer
+ // keep the device name to get the install path.
+ config.genericConfig.deviceNameToInstall = config.deviceNameToInstall
+}
+
+// NewConfig creates a new Config object. It also loads the config file, if
+// found. The Config object includes a duplicated Config object in it for the
+// generic configuration that does not provide any product specific information.
+func NewConfig(cmdArgs CmdArgs, availableEnv map[string]string) (Config, error) {
+ config, err := initConfig(cmdArgs, availableEnv)
+ if err != nil {
+ return Config{}, err
+ }
+
+ // Initialize generic configuration.
+ config.genericConfig, err = initConfig(cmdArgs, availableEnv)
+ // Update product specific variables with the generic configuration.
+ overrideGenericConfig(config)
return Config{config}, err
}
@@ -946,7 +1038,7 @@
// require them to run and get the current build fingerprint. This ensures they
// don't rebuild on every incremental build when the build number changes.
func (c *config) BuildFingerprintFile(ctx PathContext) Path {
- return PathForArbitraryOutput(ctx, "target", "product", c.DeviceName(), String(c.productVariables.BuildFingerprintFile))
+ return PathForArbitraryOutput(ctx, "target", "product", *c.deviceNameToInstall, String(c.productVariables.BuildFingerprintFile))
}
// BuildNumberFile returns the path to a text file containing metadata
@@ -974,7 +1066,7 @@
// require them to run and get the current build thumbprint. This ensures they
// don't rebuild on every incremental build when the build thumbprint changes.
func (c *config) BuildThumbprintFile(ctx PathContext) Path {
- return PathForArbitraryOutput(ctx, "target", "product", c.DeviceName(), String(c.productVariables.BuildThumbprintFile))
+ return PathForArbitraryOutput(ctx, "target", "product", *c.deviceNameToInstall, String(c.productVariables.BuildThumbprintFile))
}
// DeviceName returns the name of the current device target.
@@ -1207,6 +1299,10 @@
return otaPaths
}
+func (c *config) ExtraOtaRecoveryKeys() []string {
+ return c.productVariables.ExtraOtaRecoveryKeys
+}
+
func (c *config) BuildKeys() string {
defaultCert := String(c.productVariables.DefaultAppCertificate)
if defaultCert == "" || defaultCert == filepath.Join(testKeyDir, "testkey") {
diff --git a/android/config_test.go b/android/config_test.go
index d1b26c1..81b7c3e 100644
--- a/android/config_test.go
+++ b/android/config_test.go
@@ -281,3 +281,72 @@
})
}
}
+
+type configTestProperties struct {
+ Use_generic_config *bool
+}
+
+type configTestModule struct {
+ ModuleBase
+ properties configTestProperties
+}
+
+func (d *configTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+ deviceName := ctx.Config().DeviceName()
+ if ctx.ModuleName() == "foo" {
+ if ctx.Module().UseGenericConfig() {
+ ctx.PropertyErrorf("use_generic_config", "must not be set for this test")
+ }
+ } else if ctx.ModuleName() == "bar" {
+ if !ctx.Module().UseGenericConfig() {
+ ctx.ModuleErrorf("\"use_generic_config: true\" must be set for this test")
+ }
+ }
+
+ if ctx.Module().UseGenericConfig() {
+ if deviceName != "generic" {
+ ctx.ModuleErrorf("Device name for this module must be \"generic\" but %q\n", deviceName)
+ }
+ } else {
+ if deviceName == "generic" {
+ ctx.ModuleErrorf("Device name for this module must not be \"generic\"\n")
+ }
+ }
+}
+
+func configTestModuleFactory() Module {
+ module := &configTestModule{}
+ module.AddProperties(&module.properties)
+ InitAndroidModule(module)
+ return module
+}
+
+var prepareForConfigTest = GroupFixturePreparers(
+ FixtureRegisterWithContext(func(ctx RegistrationContext) {
+ ctx.RegisterModuleType("test", configTestModuleFactory)
+ }),
+)
+
+func TestGenericConfig(t *testing.T) {
+ bp := `
+ test {
+ name: "foo",
+ }
+
+ test {
+ name: "bar",
+ use_generic_config: true,
+ }
+ `
+
+ result := GroupFixturePreparers(
+ prepareForConfigTest,
+ FixtureWithRootAndroidBp(bp),
+ ).RunTest(t)
+
+ foo := result.Module("foo", "").(*configTestModule)
+ bar := result.Module("bar", "").(*configTestModule)
+
+ AssertBoolEquals(t, "Do not use generic config", false, foo.UseGenericConfig())
+ AssertBoolEquals(t, "Use generic config", true, bar.UseGenericConfig())
+}
diff --git a/android/early_module_context.go b/android/early_module_context.go
index 8d28285..300edf1 100644
--- a/android/early_module_context.go
+++ b/android/early_module_context.go
@@ -146,6 +146,13 @@
}
func (e *earlyModuleContext) Config() Config {
+ // Only the system image may use the generic config.
+ // If a module builds multiple image variations, provide the generic config only for the core
+ // variant which is installed in the system partition. Other image variant may still read the
+ // original configurations.
+ if e.Module().base().UseGenericConfig() && e.Module().base().commonProperties.ImageVariation == "" {
+ return e.EarlyModuleContext.Config().(Config).genericConfig()
+ }
return e.EarlyModuleContext.Config().(Config)
}
diff --git a/android/filegroup.go b/android/filegroup.go
index 9bcfd0a..4fad52a 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -33,7 +33,6 @@
func RegisterFilegroupBuildComponents(ctx RegistrationContext) {
ctx.RegisterModuleType("filegroup", FileGroupFactory)
ctx.RegisterModuleType("filegroup_defaults", FileGroupDefaultsFactory)
- ctx.RegisterModuleType("otatools_package_filegroup", OtatoolsFileGroupFactory)
}
type fileGroupProperties struct {
@@ -164,54 +163,3 @@
}
}
}
-
-type OtatoolsFileGroup struct {
- ModuleBase
-}
-
-func OtatoolsFileGroupFactory() Module {
- module := &OtatoolsFileGroup{}
- InitAndroidModule(module)
- AddLoadHook(module, func(ctx LoadHookContext) {
- module.createOTAToolsPackagefilegroup(ctx)
- })
- return module
-}
-
-func (fg *OtatoolsFileGroup) GenerateAndroidBuildActions(ctx ModuleContext) {
-}
-
-// Create the filegroup to collect cert files for otatools.zip.
-func (fg *OtatoolsFileGroup) createOTAToolsPackagefilegroup(ctx LoadHookContext) {
- ctx.CreateModuleInDirectory(
- FileGroupFactory,
- ".",
- &struct {
- Name *string
- Srcs []string
- Visibility []string
- }{
- Name: proptools.StringPtr("soong_generated_otatools_package_filegroup"),
- Srcs: []string{
- "build/make/target/product/security/**/*.x509.pem",
- "build/make/target/product/security/**/*.pk8",
- "device/**/*.pk8",
- "device/**/verifiedboot*",
- "device/**/*.pem",
- "device/**/oem*.prop",
- "device/**/*.avbpubkey",
- "external/avb/test/data/**/testkey_*.pem",
- "external/avb/test/data/**/atx_metadata.bin",
- "packages/modules/**/*.x509.pem",
- "packages/modules/**/*.pk8",
- "packages/modules/**/*.key.pem",
- "vendor/**/*.pk8",
- "vendor/**/verifiedboot*",
- "vendor/**/*.pem",
- "vendor/**/oem*.prop",
- "vendor/**/*.avbpubkey",
- },
- Visibility: []string{"//build/make/tools/otatools_package"},
- },
- )
-}
diff --git a/android/module.go b/android/module.go
index 45a20a0..ecd0f23 100644
--- a/android/module.go
+++ b/android/module.go
@@ -129,6 +129,9 @@
// WARNING: This should not be used outside build/soong/fsgen
// Overrides returns the list of modules which should not be installed if this module is installed.
Overrides() []string
+
+ // If this is true, the module must not read product-specific configurations.
+ UseGenericConfig() bool
}
// Qualified id for a module
@@ -508,6 +511,10 @@
// List of module names that are prevented from being installed when this module gets
// installed.
Overrides []string
+
+ // Set to true if this module must be generic and does not require product-specific information.
+ // To be included in the system image, this property must be set to true.
+ Use_generic_config *bool
}
// Properties common to all modules inheriting from ModuleBase. Unlike commonProperties, these
@@ -2589,6 +2596,10 @@
return m.commonProperties.Overrides
}
+func (m *ModuleBase) UseGenericConfig() bool {
+ return proptools.Bool(m.commonProperties.Use_generic_config)
+}
+
type ConfigContext interface {
Config() Config
}
diff --git a/android/module_proxy.go b/android/module_proxy.go
index 77abc11..561c477 100644
--- a/android/module_proxy.go
+++ b/android/module_proxy.go
@@ -231,3 +231,7 @@
func (m ModuleProxy) VintfFragments(ctx ConfigurableEvaluatorContext) []string {
panic("method is not implemented on ModuleProxy")
}
+
+func (m ModuleProxy) UseGenericConfig() bool {
+ panic("method is not implemented on ModuleProxy")
+}
diff --git a/android/neverallow.go b/android/neverallow.go
index 5c90501..e693f2d 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -388,6 +388,7 @@
"prebuilt_radio",
"prebuilt_gpu",
"prebuilt_vendor_overlay",
+ "prebuilt_tee",
).
DefinedInBpFile().
Because("module type not allowed to be defined in bp file")
diff --git a/android/paths.go b/android/paths.go
index 977473f..6612d37 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -2054,7 +2054,7 @@
var partitionPaths []string
if os.Class == Device {
- partitionPaths = []string{"target", "product", ctx.Config().DeviceName(), partition}
+ partitionPaths = []string{"target", "product", *ctx.Config().deviceNameToInstall, partition}
} else {
osName := os.String()
if os == Linux {
diff --git a/android/test_config.go b/android/test_config.go
index 3609e6b..5d79df0 100644
--- a/android/test_config.go
+++ b/android/test_config.go
@@ -23,8 +23,7 @@
"github.com/google/blueprint/proptools"
)
-// TestConfig returns a Config object for testing.
-func TestConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config {
+func initTestConfig(buildDir string, env map[string]string) *config {
envCopy := make(map[string]string)
for k, v := range env {
envCopy[k] = v
@@ -58,6 +57,7 @@
soongOutDir: filepath.Join(buildDir, "soong"),
captureBuild: true,
env: envCopy,
+ OncePer: &OncePer{},
// Set testAllowNonExistentPaths so that test contexts don't need to specify every path
// passed to PathForSource or PathForModuleSrc.
@@ -69,10 +69,21 @@
config: config,
}
config.TestProductVariables = &config.productVariables
+ config.deviceNameToInstall = config.TestProductVariables.DeviceName
+
+ determineBuildOS(config)
+
+ return config
+}
+
+// TestConfig returns a Config object for testing.
+func TestConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config {
+ config := initTestConfig(buildDir, env)
config.mockFileSystem(bp, fs)
- determineBuildOS(config)
+ config.genericConfig = initTestConfig(buildDir, env)
+ overrideGenericConfig(config)
return Config{config}
}
diff --git a/android/variable.go b/android/variable.go
index 3d5a6ae..8c9a0b1 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -225,8 +225,8 @@
Platform_version_last_stable *string `json:",omitempty"`
Platform_version_known_codenames *string `json:",omitempty"`
- DeviceName *string `json:",omitempty"`
- DeviceProduct *string `json:",omitempty"`
+ DeviceName *string `json:",omitempty" generic:"generic"`
+ DeviceProduct *string `json:",omitempty" generic:"generic"`
DeviceArch *string `json:",omitempty"`
DeviceArchVariant *string `json:",omitempty"`
DeviceCpuVariant *string `json:",omitempty"`
diff --git a/apex/apex.go b/apex/apex.go
index c6566e1..a726098 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -569,19 +569,6 @@
shBinary
)
-var (
- classes = map[string]apexFileClass{
- "app": app,
- "appSet": appSet,
- "etc": etc,
- "javaSharedLib": javaSharedLib,
- "nativeExecutable": nativeExecutable,
- "nativeSharedLib": nativeSharedLib,
- "nativeTest": nativeTest,
- "shBinary": shBinary,
- }
-)
-
// apexFile represents a file in an APEX bundle. This is created during the first half of
// GenerateAndroidBuildActions by traversing the dependencies of the APEX. Then in the second half
// of the function, this is used to create commands that copies the files into a staging directory,
@@ -1970,7 +1957,11 @@
case testTag:
if ccInfo, ok := android.OtherModuleProvider(ctx, child, cc.CcInfoProvider); ok {
af := apexFileForExecutable(ctx, child, commonInfo, ccInfo)
- af.class = nativeTest
+ // We make this a nativeExecutable instead of a nativeTest because we don't want
+ // the androidmk modules generated in AndroidMkForFiles to be treated as real
+ // tests that are then packaged into suites. Our AndroidMkForFiles does not
+ // implement enough functionality to support real tests.
+ af.class = nativeExecutable
vctx.filesInfo = append(vctx.filesInfo, af)
return true // track transitive dependencies
} else {
diff --git a/cc/compdb.go b/cc/compdb.go
index 4132e09..3818e9c 100644
--- a/cc/compdb.go
+++ b/cc/compdb.go
@@ -193,7 +193,7 @@
}
builds[src.String()] = compDbEntry{
Directory: android.AbsSrcDirForExistingUseCases(),
- Arguments: getArguments(src, ctx, ccModule, ccPath, cxxPath),
+ Arguments: args,
File: src.String(),
}
}
diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go
index 45b1580..25edb79 100644
--- a/cc/config/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -53,6 +53,16 @@
"-mbranch-protection=standard",
"-fno-stack-protector",
},
+ "armv9-3a": []string{
+ "-march=armv9.3-a",
+ "-mbranch-protection=standard",
+ "-fno-stack-protector",
+ },
+ "armv9-4a": []string{
+ "-march=armv9.4-a",
+ "-mbranch-protection=standard",
+ "-fno-stack-protector",
+ },
}
arm64Ldflags = []string{
diff --git a/ci_tests/ci_test_package_zip.go b/ci_tests/ci_test_package_zip.go
index 95249aa..d7aaa66 100644
--- a/ci_tests/ci_test_package_zip.go
+++ b/ci_tests/ci_test_package_zip.go
@@ -284,6 +284,10 @@
android.AndroidMkEntries{
Class: "ETC",
OutputFile: android.OptionalPathForPath(p.output),
+ ExtraEntries: []android.AndroidMkExtraEntriesFunc{
+ func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
+ entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
+ }},
},
}
}
diff --git a/cmd/find_input_delta/find_input_delta_lib/internal_state.go b/cmd/find_input_delta/find_input_delta_lib/internal_state.go
index bf4f866..0f88159 100644
--- a/cmd/find_input_delta/find_input_delta_lib/internal_state.go
+++ b/cmd/find_input_delta/find_input_delta_lib/internal_state.go
@@ -95,9 +95,14 @@
}
ret := []*fid_proto.PartialCompileInput{}
for _, v := range rc.File {
+ // Only include timestamp when there is no CRC.
+ timeNsec := proto.Int64(v.ModTime().UnixNano())
+ if v.CRC32 != 0 {
+ timeNsec = nil
+ }
pci := &fid_proto.PartialCompileInput{
Name: proto.String(v.Name),
- MtimeNsec: proto.Int64(v.ModTime().UnixNano()),
+ MtimeNsec: timeNsec,
Hash: proto.String(fmt.Sprintf("%08x", v.CRC32)),
}
ret = append(ret, pci)
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index e57384f..af09dbc 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -139,6 +139,11 @@
// Returns all jars that system_server loads.
func (g *GlobalConfig) AllSystemServerJars(ctx android.PathContext) *android.ConfiguredJarList {
+ // dexpreopt does not initialize the soong config.
+ // Initialize the OncePer here.
+ if ctx.Config().OncePer == nil {
+ ctx.Config().OncePer = &android.OncePer{}
+ }
return ctx.Config().Once(allSystemServerJarsKey, func() interface{} {
res := g.AllPlatformSystemServerJars(ctx).AppendList(g.AllApexSystemServerJars(ctx))
return &res
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index 3b0c032..7820047 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -78,6 +78,7 @@
ctx.RegisterModuleType("prebuilt_rfs", PrebuiltRfsFactory)
ctx.RegisterModuleType("prebuilt_framework", PrebuiltFrameworkFactory)
ctx.RegisterModuleType("prebuilt_res", PrebuiltResFactory)
+ ctx.RegisterModuleType("prebuilt_tee", PrebuiltTeeFactory)
ctx.RegisterModuleType("prebuilt_wlc_upt", PrebuiltWlcUptFactory)
ctx.RegisterModuleType("prebuilt_odm", PrebuiltOdmFactory)
ctx.RegisterModuleType("prebuilt_vendor_dlkm", PrebuiltVendorDlkmFactory)
@@ -910,6 +911,16 @@
return module
}
+// prebuilt_tee installs files in <partition>/tee directory.
+func PrebuiltTeeFactory() android.Module {
+ module := &PrebuiltEtc{}
+ InitPrebuiltEtcModule(module, "tee")
+ // This module is device-only
+ android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
+ android.InitDefaultableModule(module)
+ return module
+}
+
// prebuilt_media installs media files in <partition>/media directory.
func PrebuiltMediaFactory() android.Module {
module := &PrebuiltEtc{}
diff --git a/filesystem/android_device.go b/filesystem/android_device.go
index 3f6348d..443e80e 100644
--- a/filesystem/android_device.go
+++ b/filesystem/android_device.go
@@ -748,26 +748,91 @@
}
+var (
+ // https://cs.android.com/android/_/android/platform/build/+/30f05352c3e6f4333c77d4af66c253572d3ea6c9:core/Makefile;l=2111-2120;drc=519f75666431ee2926e0ec8991c682b28a4c9521;bpv=1;bpt=0
+ defaultTargetRecoveryFstypeMountOptions = "ext4=max_batch_time=0,commit=1,data=ordered,barrier=1,errors=panic,nodelalloc"
+)
+
// A partial implementation of make's $PRODUCT_OUT/misc_info.txt
// https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=5894?q=misc_info.txt%20f:build%2Fmake%2Fcore%2FMakefile&ss=android%2Fplatform%2Fsuperproject%2Fmain
// This file is subsequently used by add_img_to_target_files to create additioanl metadata files like apex_info.pb
// TODO (b/399788119): Complete the migration of misc_info.txt
func (a *androidDevice) addMiscInfo(ctx android.ModuleContext) android.Path {
+ buildType := func() string {
+ if ctx.Config().Debuggable() {
+ return "userdebug"
+ } else if ctx.Config().Eng() {
+ return "eng"
+ } else {
+ return "user"
+ }
+ }
+ defaultAppCertificate := func() string {
+ pem, _ := ctx.Config().DefaultAppCertificate(ctx)
+ return strings.TrimSuffix(pem.String(), ".x509.pem")
+ }
+
builder := android.NewRuleBuilder(pctx, ctx)
miscInfo := android.PathForModuleOut(ctx, "misc_info.txt")
builder.Command().
Textf("rm -f %s", miscInfo).
Textf("&& echo recovery_api_version=%s >> %s", ctx.Config().VendorConfig("recovery").String("recovery_api_version"), miscInfo).
Textf("&& echo fstab_version=%s >> %s", ctx.Config().VendorConfig("recovery").String("recovery_fstab_version"), miscInfo).
+ Textf("&& echo build_type=%s >> %s", buildType(), miscInfo).
+ Textf("&& echo default_system_dev_certificate=%s >> %s", defaultAppCertificate(), miscInfo).
+ Textf("&& echo root_dir=%s >> %s", android.PathForModuleInPartitionInstall(ctx, "root"), miscInfo).
ImplicitOutput(miscInfo)
+ if len(ctx.Config().ExtraOtaRecoveryKeys()) > 0 {
+ builder.Command().Textf(`echo "extra_recovery_keys=%s" >> %s`, strings.Join(ctx.Config().ExtraOtaRecoveryKeys(), ""), miscInfo)
+ } else {
+ if a.partitionProps.Boot_partition_name != nil {
+ builder.Command().
+ Textf("echo mkbootimg_args='--header_version %s' >> %s", a.getBootimgHeaderVersion(ctx, a.partitionProps.Boot_partition_name), miscInfo).
+ // TODO: Use boot's header version for recovery for now since cuttlefish does not set `BOARD_RECOVERY_MKBOOTIMG_ARGS`
+ Textf(" && echo recovery_mkbootimg_args='--header_version %s' >> %s", a.getBootimgHeaderVersion(ctx, a.partitionProps.Boot_partition_name), miscInfo)
+ }
+ if a.partitionProps.Init_boot_partition_name != nil {
+ builder.Command().
+ Textf("echo mkbootimg_init_args='--header_version' %s >> %s", a.getBootimgHeaderVersion(ctx, a.partitionProps.Init_boot_partition_name), miscInfo)
+ }
+ builder.Command().
+ Textf("echo mkbootimg_version_args='--os_version %s --os_patch_level %s' >> %s", ctx.Config().PlatformVersionLastStable(), ctx.Config().PlatformSecurityPatch(), miscInfo).
+ Textf(" && echo multistage_support=1 >> %s", miscInfo).
+ Textf(" && echo blockimgdiff_versions=3,4 >> %s", miscInfo)
+ }
+ fsInfos := a.getFsInfos(ctx)
+ if _, ok := fsInfos["vendor"]; ok {
+ builder.Command().Textf("echo board_uses_vendorimage=true >> %s", miscInfo)
+ }
+ if fsInfos["system"].ErofsCompressHints != nil {
+ builder.Command().Textf("echo erofs_default_compress_hints=%s >> %s", fsInfos["system"].ErofsCompressHints, miscInfo)
+ }
+ if releaseTools := android.PathForModuleSrc(ctx, proptools.String(a.deviceProps.Releasetools_extension)); releaseTools != nil {
+ builder.Command().Textf("echo tool_extensions=%s >> %s", filepath.Dir(releaseTools.String()), miscInfo)
+ }
+ // ramdisk uses `compressed_cpio` fs_type
+ // https://cs.android.com/android/_/android/platform/build/+/30f05352c3e6f4333c77d4af66c253572d3ea6c9:core/Makefile;l=5923-5925;drc=519f75666431ee2926e0ec8991c682b28a4c9521;bpv=1;bpt=0
+ if _, ok := fsInfos["ramdisk"]; ok {
+ builder.Command().Textf("echo lz4_ramdisks=true >> %s", miscInfo)
+ }
+ // recovery_mount_options
+ // TODO: Add support for TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS which can be used to override the default
+ builder.Command().Textf("echo recovery_mount_options=%s >> %s", defaultTargetRecoveryFstypeMountOptions, miscInfo)
+
+ // vintf information
+ if proptools.Bool(ctx.Config().ProductVariables().Enforce_vintf_manifest) {
+ builder.Command().Textf("echo vintf_enforce=true >> %s", miscInfo)
+ }
+ if len(ctx.Config().DeviceManifestFiles()) > 0 {
+ builder.Command().Textf("echo vintf_include_empty_vendor_sku=true >> %s", miscInfo)
+ }
if a.partitionProps.Recovery_partition_name == nil {
builder.Command().Textf("echo no_recovery=true >> %s", miscInfo)
}
- fsInfos := a.getFsInfos(ctx)
for _, partition := range android.SortedKeys(fsInfos) {
- if fsInfos[partition].UseAvb {
- builder.Command().Textf("echo 'avb_%s_hashtree_enable=true' >> %s", partition, miscInfo)
+ if fsInfos[partition].PropFileForMiscInfo != nil {
+ builder.Command().Text("cat").Input(fsInfos[partition].PropFileForMiscInfo).Textf(" >> %s", miscInfo)
}
}
if len(a.partitionProps.Vbmeta_partitions) > 0 {
@@ -785,6 +850,10 @@
if info, ok := android.OtherModuleProvider(ctx, superPartition, SuperImageProvider); ok {
// cat dynamic_partition_info.txt
builder.Command().Text("cat").Input(info.DynamicPartitionsInfo).Textf(" >> %s", miscInfo)
+ if info.AbUpdate {
+ builder.Command().Textf("echo ab_update=true >> %s", miscInfo)
+ }
+
} else {
ctx.ModuleErrorf("Super partition %s does set SuperImageProvider\n", superPartition.Name())
}
@@ -805,11 +874,20 @@
builder.Command().Text("cat").Input(bootImgInfo.PropFileForMiscInfo).Textf(" >> %s", miscInfo)
}
+ // Sort and dedup
+ builder.Command().Textf("sort -u %s -o %s", miscInfo, miscInfo)
+
builder.Build("misc_info", "Building misc_info")
return miscInfo
}
+func (a *androidDevice) getBootimgHeaderVersion(ctx android.ModuleContext, bootImgName *string) string {
+ bootImg := ctx.GetDirectDepProxyWithTag(proptools.String(bootImgName), filesystemDepTag)
+ bootImgInfo, _ := android.OtherModuleProvider(ctx, bootImg, BootimgInfoProvider)
+ return bootImgInfo.HeaderVersion
+}
+
// addImgToTargetFiles invokes `add_img_to_target_files` and creates the following files in META/
// - apex_info.pb
// - care_map.pb
diff --git a/filesystem/bootimg.go b/filesystem/bootimg.go
index 7959365..5ab0c68 100644
--- a/filesystem/bootimg.go
+++ b/filesystem/bootimg.go
@@ -244,6 +244,7 @@
Bootconfig: b.getBootconfigPath(ctx),
Output: output,
PropFileForMiscInfo: b.buildPropFileForMiscInfo(ctx),
+ HeaderVersion: proptools.String(b.properties.Header_version),
})
extractedPublicKey := android.PathForModuleOut(ctx, b.partitionName()+".avbpubkey")
@@ -292,6 +293,7 @@
Bootconfig android.Path
Output android.Path
PropFileForMiscInfo android.Path
+ HeaderVersion string
}
func (b *bootimg) getKernelPath(ctx android.ModuleContext) android.Path {
@@ -510,6 +512,25 @@
return propFile, deps
}
+func (b *bootimg) getAvbHashFooterArgs(ctx android.ModuleContext) string {
+ ret := ""
+ if !b.bootImageType.isVendorBoot() {
+ ret += "--prop " + fmt.Sprintf("com.android.build.%s.os_version:%s", b.bootImageType.String(), ctx.Config().PlatformVersionLastStable())
+ }
+
+ fingerprintFile := ctx.Config().BuildFingerprintFile(ctx)
+ ret += " --prop " + fmt.Sprintf("com.android.build.%s.fingerprint:{CONTENTS_OF:%s}", b.bootImageType.String(), fingerprintFile.String())
+
+ if b.properties.Security_patch != nil {
+ ret += " --prop " + fmt.Sprintf("com.android.build.%s.security_patch:%s", b.bootImageType.String(), *b.properties.Security_patch)
+ }
+
+ if b.properties.Avb_rollback_index != nil {
+ ret += " --rollback_index " + strconv.FormatInt(*b.properties.Avb_rollback_index, 10)
+ }
+ return strings.TrimSpace(ret)
+}
+
func (b *bootimg) buildPropFileForMiscInfo(ctx android.ModuleContext) android.Path {
var sb strings.Builder
addStr := func(name string, value string) {
@@ -517,15 +538,28 @@
}
bootImgType := proptools.String(b.properties.Boot_image_type)
- addStr("avb_"+bootImgType+"_add_hash_footer_args", "TODO(b/398036609)")
+ addStr("avb_"+bootImgType+"_add_hash_footer_args", b.getAvbHashFooterArgs(ctx))
if b.properties.Avb_private_key != nil {
addStr("avb_"+bootImgType+"_algorithm", proptools.StringDefault(b.properties.Avb_algorithm, "SHA256_RSA4096"))
addStr("avb_"+bootImgType+"_key_path", android.PathForModuleSrc(ctx, proptools.String(b.properties.Avb_private_key)).String())
addStr("avb_"+bootImgType+"_rollback_index_location", strconv.Itoa(proptools.Int(b.properties.Avb_rollback_index_location)))
}
+ if b.properties.Partition_size != nil {
+ addStr(bootImgType+"_size", strconv.FormatInt(*b.properties.Partition_size, 10))
+ }
+ if bootImgType != "boot" {
+ addStr(bootImgType, "true")
+ }
- propFile := android.PathForModuleOut(ctx, "prop_for_misc_info")
- android.WriteFileRuleVerbatim(ctx, propFile, sb.String())
+ propFilePreProcessing := android.PathForModuleOut(ctx, "prop_for_misc_info_pre_processing")
+ android.WriteFileRuleVerbatim(ctx, propFilePreProcessing, sb.String())
+ propFile := android.PathForModuleOut(ctx, "prop_file_for_misc_info")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: textFileProcessorRule,
+ Input: propFilePreProcessing,
+ Output: propFile,
+ })
+
return propFile
}
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index b854880..e86ebf4 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -452,9 +452,17 @@
Owners []InstalledModuleInfo
- UseAvb bool
-
HasFsverity bool
+
+ PropFileForMiscInfo android.Path
+
+ // Additional avb and partition size information.
+ // `system_other` will use this information of `system` dep for misc_info.txt processing.
+ PartitionSize *int64
+ UseAvb bool
+ AvbAlgorithm string
+ AvbHashAlgorithm string
+ AvbKey android.Path
}
// FullInstallPathInfo contains information about the "full install" paths of all the files
@@ -638,9 +646,11 @@
var buildImagePropFile android.Path
var buildImagePropFileDeps android.Paths
var extraRootDirs android.Paths
+ var propFileForMiscInfo android.Path
switch f.fsType(ctx) {
case ext4Type, erofsType, f2fsType:
buildImagePropFile, buildImagePropFileDeps = f.buildPropFile(ctx)
+ propFileForMiscInfo = f.buildPropFileForMiscInfo(ctx)
output := android.PathForModuleOut(ctx, f.installFileName())
f.buildImageUsingBuildImage(ctx, builder, buildImageParams{rootDir, buildImagePropFile, buildImagePropFileDeps, output})
f.output = output
@@ -703,12 +713,21 @@
[]InstalledFilesStruct{buildInstalledFiles(ctx, partitionNameForInstalledFiles, rootDir, f.output)},
includeFilesInstalledFiles(ctx),
),
- ErofsCompressHints: erofsCompressHints,
- SelinuxFc: f.selinuxFc,
- FilesystemConfig: f.generateFilesystemConfig(ctx, rootDir, rebasedDir),
- Owners: f.gatherOwners(specs),
- UseAvb: proptools.Bool(f.properties.Use_avb),
- HasFsverity: f.properties.Fsverity.Inputs.GetOrDefault(ctx, nil) != nil,
+ ErofsCompressHints: erofsCompressHints,
+ SelinuxFc: f.selinuxFc,
+ FilesystemConfig: f.generateFilesystemConfig(ctx, rootDir, rebasedDir),
+ Owners: f.gatherOwners(specs),
+ HasFsverity: f.properties.Fsverity.Inputs.GetOrDefault(ctx, nil) != nil,
+ PropFileForMiscInfo: propFileForMiscInfo,
+ PartitionSize: f.properties.Partition_size,
+ }
+ if proptools.Bool(f.properties.Use_avb) {
+ fsInfo.UseAvb = true
+ fsInfo.AvbAlgorithm = proptools.StringDefault(f.properties.Avb_algorithm, "SHA256_RSA4096")
+ fsInfo.AvbHashAlgorithm = proptools.StringDefault(f.properties.Avb_hash_algorithm, "sha256")
+ if f.properties.Avb_private_key != nil {
+ fsInfo.AvbKey = android.PathForModuleSrc(ctx, *f.properties.Avb_private_key)
+ }
}
android.SetProvider(ctx, FilesystemProvider, fsInfo)
@@ -1144,6 +1163,83 @@
return propFile, deps
}
+func (f *filesystem) buildPropFileForMiscInfo(ctx android.ModuleContext) android.Path {
+ var lines []string
+ addStr := func(name string, value string) {
+ lines = append(lines, fmt.Sprintf("%s=%s", name, value))
+ }
+
+ addStr("use_dynamic_partition_size", "true")
+ addStr("ext_mkuserimg", "mkuserimg_mke2fs")
+
+ addStr("building_"+f.partitionName()+"_image", "true")
+ addStr(f.partitionName()+"_fs_type", f.fsType(ctx).String())
+
+ if proptools.Bool(f.properties.Use_avb) {
+ addStr("avb_"+f.partitionName()+"_hashtree_enable", "true")
+ if f.properties.Avb_private_key != nil {
+ key := android.PathForModuleSrc(ctx, *f.properties.Avb_private_key)
+ addStr("avb_"+f.partitionName()+"_key_path", key.String())
+ }
+ addStr("avb_"+f.partitionName()+"_add_hashtree_footer_args", strings.TrimSpace(f.getAvbAddHashtreeFooterArgs(ctx)))
+ }
+
+ if f.selinuxFc != nil {
+ addStr(f.partitionName()+"_selinux_fc", f.selinuxFc.String())
+ }
+
+ // Disable sparse only when partition size is not defined. disable_sparse has the same
+ // effect as <partition name>_disable_sparse.
+ if f.properties.Partition_size == nil {
+ addStr(f.partitionName()+"_disable_sparse", "true")
+ } else if f.partitionName() == "userdata" {
+ // Add userdata's partition size to misc_info.txt.
+ // userdata has been special-cased to make the make packaging misc_info.txt implementation
+ addStr("userdata_size", strconv.FormatInt(*f.properties.Partition_size, 10))
+ }
+
+ fst := f.fsType(ctx)
+ switch fst {
+ case erofsType:
+ // Add erofs properties
+ addStr("erofs_default_compressor", proptools.StringDefault(f.properties.Erofs.Compressor, "lz4hc,9"))
+ if proptools.BoolDefault(f.properties.Erofs.Sparse, true) {
+ // 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")
+ }
+ 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")
+ }
+ }
+
+ if proptools.BoolDefault(f.properties.Support_casefolding, false) {
+ addStr("needs_casefold", "1")
+ }
+
+ if proptools.BoolDefault(f.properties.Support_project_quota, false) {
+ addStr("needs_projid", "1")
+ }
+
+ if proptools.BoolDefault(f.properties.Enable_compression, false) {
+ addStr("needs_compress", "1")
+ }
+
+ sort.Strings(lines)
+
+ propFilePreProcessing := android.PathForModuleOut(ctx, "prop_misc_info_pre_processing")
+ android.WriteFileRule(ctx, propFilePreProcessing, strings.Join(lines, "\n"))
+ propFile := android.PathForModuleOut(ctx, "prop_file_for_misc_info")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: textFileProcessorRule,
+ Input: propFilePreProcessing,
+ Output: propFile,
+ })
+
+ return propFile
+}
+
func (f *filesystem) getAvbAddHashtreeFooterArgs(ctx android.ModuleContext) string {
avb_add_hashtree_footer_args := ""
if !proptools.BoolDefault(f.properties.Use_fec, true) {
diff --git a/filesystem/super_image.go b/filesystem/super_image.go
index cd7df02..cf7e125 100644
--- a/filesystem/super_image.go
+++ b/filesystem/super_image.go
@@ -122,6 +122,8 @@
DynamicPartitionsInfo android.Path
SuperEmptyImage android.Path
+
+ AbUpdate bool
}
var SuperImageProvider = blueprint.NewProvider[SuperImageInfo]()
@@ -201,6 +203,7 @@
SubImageInfo: subImageInfos,
DynamicPartitionsInfo: s.generateDynamicPartitionsInfo(ctx),
SuperEmptyImage: superEmptyImage,
+ AbUpdate: proptools.Bool(s.properties.Ab_update),
})
ctx.SetOutputFiles([]android.Path{output}, "")
ctx.CheckbuildFile(output)
diff --git a/filesystem/system_other.go b/filesystem/system_other.go
index cbfd78b..348c010 100644
--- a/filesystem/system_other.go
+++ b/filesystem/system_other.go
@@ -16,8 +16,11 @@
import (
"android/soong/android"
+ "fmt"
"path/filepath"
+ "sort"
"strings"
+ "time"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -172,10 +175,11 @@
builder.Build("build_system_other_hermetic", "build system other")
fsInfo := FilesystemInfo{
- Output: output,
- OutputHermetic: outputHermetic,
- RootDir: stagingDir,
- FilesystemConfig: m.generateFilesystemConfig(ctx, stagingDir, stagingDirTimestamp),
+ Output: output,
+ OutputHermetic: outputHermetic,
+ RootDir: stagingDir,
+ FilesystemConfig: m.generateFilesystemConfig(ctx, stagingDir, stagingDirTimestamp),
+ PropFileForMiscInfo: m.buildPropFileForMiscInfo(ctx),
}
android.SetProvider(ctx, FilesystemProvider, fsInfo)
@@ -204,3 +208,52 @@
Textf(" && echo use_fixed_timestamp=true >> %s", propFilePinnedTimestamp)
return propFilePinnedTimestamp
}
+
+func (f *systemOtherImage) buildPropFileForMiscInfo(ctx android.ModuleContext) android.Path {
+ var lines []string
+ addStr := func(name string, value string) {
+ lines = append(lines, fmt.Sprintf("%s=%s", name, value))
+ }
+
+ addStr("building_system_other_image", "true")
+
+ systemImage := ctx.GetDirectDepProxyWithTag(*f.properties.System_image, systemImageDependencyTag)
+ systemInfo, ok := android.OtherModuleProvider(ctx, systemImage, FilesystemProvider)
+ if !ok {
+ ctx.PropertyErrorf("system_image", "Expected system_image module to provide FilesystemProvider")
+ return nil
+ }
+ if systemInfo.PartitionSize == nil {
+ addStr("system_other_disable_sparse", "true")
+ }
+ if systemInfo.UseAvb {
+ addStr("avb_system_other_hashtree_enable", "true")
+ addStr("avb_system_other_algorithm", systemInfo.AvbAlgorithm)
+ footerArgs := fmt.Sprintf("--hash_algorithm %s", systemInfo.AvbHashAlgorithm)
+ if rollbackIndex, err := f.avbRollbackIndex(ctx); err == nil {
+ footerArgs += fmt.Sprintf(" --rollback_index %d", rollbackIndex)
+ } else {
+ ctx.ModuleErrorf("Could not determine rollback_index %s\n", err)
+ }
+ addStr("avb_system_other_add_hashtree_footer_args", footerArgs)
+ if systemInfo.AvbKey != nil {
+ addStr("avb_system_other_key_path", systemInfo.AvbKey.String())
+ }
+ }
+
+ sort.Strings(lines)
+
+ propFile := android.PathForModuleOut(ctx, "prop_file")
+ android.WriteFileRule(ctx, propFile, strings.Join(lines, "\n"))
+ return propFile
+}
+
+// Use the default: PlatformSecurityPatch
+// TODO: Get this value from vbmeta_system
+func (f *systemOtherImage) avbRollbackIndex(ctx android.ModuleContext) (int64, error) {
+ t, err := time.Parse(time.DateOnly, ctx.Config().PlatformSecurityPatch())
+ if err != nil {
+ return -1, err
+ }
+ return t.Unix(), err
+}
diff --git a/fsgen/filesystem_creator_test.go b/fsgen/filesystem_creator_test.go
index 81236a0..651d2d1 100644
--- a/fsgen/filesystem_creator_test.go
+++ b/fsgen/filesystem_creator_test.go
@@ -312,14 +312,14 @@
}),
).RunTest(t)
- checkModuleProp := func(m android.Module, matcher func(actual interface{}) bool) bool {
+ getModuleProp := func(m android.Module, matcher func(actual interface{}) string) string {
for _, prop := range m.GetProperties() {
- if matcher(prop) {
- return true
+ if str := matcher(prop); str != "" {
+ return str
}
}
- return false
+ return ""
}
// check generated prebuilt_* module type install path and install partition
@@ -350,6 +350,37 @@
etcModule.SubDir(),
)
+ // check that generated prebuilt_* module sets correct srcs
+ eval := generatedModule.ConfigurableEvaluator(android.PanickingConfigAndErrorContext(result.TestContext))
+ android.AssertStringEquals(
+ t,
+ "module expected to set correct srcs property",
+ "Vendor_0079_Product_0011.kl",
+ getModuleProp(generatedModule, func(actual interface{}) string {
+ if p, ok := actual.(*etc.PrebuiltEtcProperties); ok {
+ srcs := p.Srcs.GetOrDefault(eval, nil)
+ if len(srcs) == 2 {
+ return srcs[0]
+ }
+ }
+ return ""
+ }),
+ )
+ android.AssertStringEquals(
+ t,
+ "module expected to set correct srcs property",
+ "Vendor_0079_Product_18d4.kl",
+ getModuleProp(generatedModule, func(actual interface{}) string {
+ if p, ok := actual.(*etc.PrebuiltEtcProperties); ok {
+ srcs := p.Srcs.GetOrDefault(eval, nil)
+ if len(srcs) == 2 {
+ return srcs[1]
+ }
+ }
+ return ""
+ }),
+ )
+
// check that prebuilt_* module is not generated for non existing source file
android.AssertStringEquals(
t,
@@ -363,60 +394,130 @@
generatedModule1 := result.ModuleForTests(t, "product-device_sample_etc-etc-1", "android_arm64_armv8-a").Module()
// check that generated prebuilt_* module sets correct srcs and dsts property
- eval := generatedModule0.ConfigurableEvaluator(android.PanickingConfigAndErrorContext(result.TestContext))
- android.AssertBoolEquals(
+ eval = generatedModule0.ConfigurableEvaluator(android.PanickingConfigAndErrorContext(result.TestContext))
+ android.AssertStringEquals(
t,
"module expected to set correct srcs property",
- true,
- checkModuleProp(generatedModule0, func(actual interface{}) bool {
+ "apns-full-conf.xml",
+ getModuleProp(generatedModule0, func(actual interface{}) string {
if p, ok := actual.(*etc.PrebuiltEtcProperties); ok {
srcs := p.Srcs.GetOrDefault(eval, nil)
- return len(srcs) == 1 &&
- srcs[0] == "apns-full-conf.xml"
+ if len(srcs) == 1 {
+ return srcs[0]
+ }
}
- return false
+ return ""
}),
)
- android.AssertBoolEquals(
+ android.AssertStringEquals(
t,
"module expected to set correct dsts property",
- true,
- checkModuleProp(generatedModule0, func(actual interface{}) bool {
+ "apns-conf.xml",
+ getModuleProp(generatedModule0, func(actual interface{}) string {
if p, ok := actual.(*etc.PrebuiltDstsProperties); ok {
dsts := p.Dsts.GetOrDefault(eval, nil)
- return len(dsts) == 1 &&
- dsts[0] == "apns-conf.xml"
+ if len(dsts) == 1 {
+ return dsts[0]
+ }
}
- return false
+ return ""
}),
)
// check that generated prebuilt_* module sets correct srcs and dsts property
eval = generatedModule1.ConfigurableEvaluator(android.PanickingConfigAndErrorContext(result.TestContext))
- android.AssertBoolEquals(
+ android.AssertStringEquals(
t,
"module expected to set correct srcs property",
- true,
- checkModuleProp(generatedModule1, func(actual interface{}) bool {
+ "apns-full-conf.xml",
+ getModuleProp(generatedModule1, func(actual interface{}) string {
if p, ok := actual.(*etc.PrebuiltEtcProperties); ok {
srcs := p.Srcs.GetOrDefault(eval, nil)
- return len(srcs) == 1 &&
- srcs[0] == "apns-full-conf.xml"
+ if len(srcs) == 1 {
+ return srcs[0]
+ }
}
- return false
+ return ""
}),
)
- android.AssertBoolEquals(
+ android.AssertStringEquals(
t,
"module expected to set correct dsts property",
- true,
- checkModuleProp(generatedModule1, func(actual interface{}) bool {
+ "apns-conf-2.xml",
+ getModuleProp(generatedModule1, func(actual interface{}) string {
if p, ok := actual.(*etc.PrebuiltDstsProperties); ok {
dsts := p.Dsts.GetOrDefault(eval, nil)
- return len(dsts) == 1 &&
- dsts[0] == "apns-conf-2.xml"
+ if len(dsts) == 1 {
+ return dsts[0]
+ }
}
- return false
+ return ""
+ }),
+ )
+
+ generatedModule0 = result.ModuleForTests(t, "system-device_sample_etc-foo-0", "android_common").Module()
+ generatedModule1 = result.ModuleForTests(t, "system-device_sample_etc-foo-1", "android_common").Module()
+
+ // check that generated prebuilt_* module sets correct srcs and dsts property
+ eval = generatedModule0.ConfigurableEvaluator(android.PanickingConfigAndErrorContext(result.TestContext))
+ android.AssertStringEquals(
+ t,
+ "module expected to set correct srcs property",
+ "apns-full-conf.xml",
+ getModuleProp(generatedModule0, func(actual interface{}) string {
+ if p, ok := actual.(*etc.PrebuiltEtcProperties); ok {
+ srcs := p.Srcs.GetOrDefault(eval, nil)
+ if len(srcs) == 1 {
+ return srcs[0]
+ }
+ }
+ return ""
+ }),
+ )
+ android.AssertStringEquals(
+ t,
+ "module expected to set correct dsts property",
+ "foo/file.txt",
+ getModuleProp(generatedModule0, func(actual interface{}) string {
+ if p, ok := actual.(*etc.PrebuiltDstsProperties); ok {
+ dsts := p.Dsts.GetOrDefault(eval, nil)
+ if len(dsts) == 1 {
+ return dsts[0]
+ }
+ }
+ return ""
+ }),
+ )
+
+ // check generated prebuilt_* module specifies correct install path and relative install path
+ etcModule, _ = generatedModule1.(*etc.PrebuiltEtc)
+ android.AssertStringEquals(
+ t,
+ "module expected to have . install path",
+ ".",
+ etcModule.BaseDir(),
+ )
+ android.AssertStringEquals(
+ t,
+ "module expected to set correct relative_install_path properties",
+ "foo",
+ etcModule.SubDir(),
+ )
+
+ // check that generated prebuilt_* module sets correct srcs
+ eval = generatedModule1.ConfigurableEvaluator(android.PanickingConfigAndErrorContext(result.TestContext))
+ android.AssertStringEquals(
+ t,
+ "module expected to set correct srcs property",
+ "apns-full-conf.xml",
+ getModuleProp(generatedModule1, func(actual interface{}) string {
+ if p, ok := actual.(*etc.PrebuiltEtcProperties); ok {
+ srcs := p.Srcs.GetOrDefault(eval, nil)
+ if len(srcs) == 1 {
+ return srcs[0]
+ }
+ }
+ return ""
}),
)
}
diff --git a/fsgen/prebuilt_etc_modules_gen.go b/fsgen/prebuilt_etc_modules_gen.go
index df36197..e9dabe4 100644
--- a/fsgen/prebuilt_etc_modules_gen.go
+++ b/fsgen/prebuilt_etc_modules_gen.go
@@ -215,6 +215,7 @@
"system": etc.PrebuiltSystemFactory,
"res": etc.PrebuiltResFactory,
"rfs": etc.PrebuiltRfsFactory,
+ "tee": etc.PrebuiltTeeFactory,
"tts": etc.PrebuiltVoicepackFactory,
"tvconfig": etc.PrebuiltTvConfigFactory,
"tvservice": etc.PrebuiltTvServiceFactory,
@@ -340,28 +341,35 @@
// Set appropriate srcs, dsts, and releative_install_path based on
// the source and install file names
- if allCopyFileNamesUnchanged {
- modulePropsPtr.Srcs = srcBaseFiles
+ modulePropsPtr.Srcs = srcBaseFiles
- // Specify relative_install_path if it is not installed in the root directory of the
- // partition
+ // prebuilt_root should only be used in very limited cases in prebuilt_etc moddule gen, where:
+ // - all source file names are identical to the installed file names, and
+ // - all source files are installed in root, not the subdirectories of root
+ // prebuilt_root currently does not have a good way to specify the names of the multiple
+ // installed files, and prebuilt_root does not allow installing files at a subdirectory
+ // of the root.
+ // Use prebuilt_any instead of prebuilt_root if either of the conditions are not met as
+ // a fallback behavior.
+ if etcInstallPathKey == "" {
+ if !(allCopyFileNamesUnchanged && android.InList(relDestDirFromInstallDirBase, []string{"", "."})) {
+ moduleFactory = etc.PrebuiltAnyFactory
+ }
+ }
+
+ if allCopyFileNamesUnchanged {
+ // Specify relative_install_path if it is not installed in the base directory of the module.
+ // In case of prebuilt_{root,any} this is equivalent to the root of the partition.
if !android.InList(relDestDirFromInstallDirBase, []string{"", "."}) {
propsList = append(propsList, &prebuiltSubdirProperties{
Relative_install_path: proptools.StringPtr(relDestDirFromInstallDirBase),
})
}
} else {
- // If dsts property has to be set and the selected module type is prebuilt_root,
- // use prebuilt_any instead.
- if etcInstallPathKey == "" {
- moduleFactory = etc.PrebuiltAnyFactory
- }
- modulePropsPtr.Srcs = srcBaseFiles
dsts := proptools.NewConfigurable[[]string](nil, nil)
for _, installBaseFile := range installBaseFiles {
dsts.AppendSimpleValue([]string{filepath.Join(relDestDirFromInstallDirBase, installBaseFile)})
}
-
propsList = append(propsList, &etc.PrebuiltDstsProperties{
Dsts: dsts,
})
diff --git a/genrule/Android.bp b/genrule/Android.bp
index 49df480..b82f2a9 100644
--- a/genrule/Android.bp
+++ b/genrule/Android.bp
@@ -14,7 +14,6 @@
"soong-shared",
],
srcs: [
- "allowlists.go",
"genrule.go",
"locations.go",
],
diff --git a/genrule/allowlists.go b/genrule/allowlists.go
deleted file mode 100644
index 45a7f72..0000000
--- a/genrule/allowlists.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2023 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 genrule
-
-var (
- SandboxingDenyModuleList = []string{
- // go/keep-sorted start
- // go/keep-sorted end
- }
-)
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 710ec95..a7c09e7 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -969,30 +969,9 @@
return module
}
-var sandboxingAllowlistKey = android.NewOnceKey("genruleSandboxingAllowlistKey")
-
-type sandboxingAllowlistSets struct {
- sandboxingDenyModuleSet map[string]bool
-}
-
-func getSandboxingAllowlistSets(ctx android.PathContext) *sandboxingAllowlistSets {
- return ctx.Config().Once(sandboxingAllowlistKey, func() interface{} {
- sandboxingDenyModuleSet := map[string]bool{}
-
- android.AddToStringSet(sandboxingDenyModuleSet, SandboxingDenyModuleList)
- return &sandboxingAllowlistSets{
- sandboxingDenyModuleSet: sandboxingDenyModuleSet,
- }
- }).(*sandboxingAllowlistSets)
-}
-
func getSandboxedRuleBuilder(ctx android.ModuleContext, r *android.RuleBuilder) *android.RuleBuilder {
if !ctx.DeviceConfig().GenruleSandboxing() {
return r.SandboxTools()
}
- sandboxingAllowlistSets := getSandboxingAllowlistSets(ctx)
- if sandboxingAllowlistSets.sandboxingDenyModuleSet[ctx.ModuleName()] {
- return r.SandboxTools()
- }
return r.SandboxInputs()
}
diff --git a/rust/config/arm64_device.go b/rust/config/arm64_device.go
index 94a4457..efcd56a 100644
--- a/rust/config/arm64_device.go
+++ b/rust/config/arm64_device.go
@@ -45,6 +45,14 @@
"-Z branch-protection=bti,pac-ret",
"-Z stack-protector=none",
},
+ "armv9-3a": []string{
+ "-Z branch-protection=bti,pac-ret",
+ "-Z stack-protector=none",
+ },
+ "armv9-4a": []string{
+ "-Z branch-protection=bti,pac-ret",
+ "-Z stack-protector=none",
+ },
}
)
diff --git a/rust/image.go b/rust/image.go
index 51b8289..aa10a6d 100644
--- a/rust/image.go
+++ b/rust/image.go
@@ -137,7 +137,7 @@
// Additionally check if this module is inVendor() that means it is a "vendor" variant of a
// module. As well as SoC specific modules, vendor variants must be installed to /vendor
// unless they have "odm_available: true".
- return mod.InVendor() && !mod.VendorVariantToOdm()
+ return mod.HasVendorVariant() && mod.InVendor() && !mod.VendorVariantToOdm()
}
func (mod *Module) InstallInOdm() bool {
diff --git a/tradefed_modules/Android.bp b/tradefed_modules/Android.bp
index a765a05..37bae39 100644
--- a/tradefed_modules/Android.bp
+++ b/tradefed_modules/Android.bp
@@ -14,11 +14,9 @@
],
srcs: [
"test_module_config.go",
- "test_suite.go",
],
testSrcs: [
"test_module_config_test.go",
- "test_suite_test.go",
],
pluginFor: ["soong_build"],
}
diff --git a/tradefed_modules/test_suite.go b/tradefed_modules/test_suite.go
deleted file mode 100644
index 8b7babf..0000000
--- a/tradefed_modules/test_suite.go
+++ /dev/null
@@ -1,173 +0,0 @@
-// 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 tradefed_modules
-
-import (
- "encoding/json"
- "path"
- "path/filepath"
-
- "android/soong/android"
- "android/soong/tradefed"
- "github.com/google/blueprint"
-)
-
-const testSuiteModuleType = "test_suite"
-
-type testSuiteTag struct {
- blueprint.BaseDependencyTag
-}
-
-type testSuiteManifest struct {
- Name string `json:"name"`
- Files []string `json:"files"`
-}
-
-func init() {
- RegisterTestSuiteBuildComponents(android.InitRegistrationContext)
-}
-
-func RegisterTestSuiteBuildComponents(ctx android.RegistrationContext) {
- ctx.RegisterModuleType(testSuiteModuleType, TestSuiteFactory)
-}
-
-var PrepareForTestWithTestSuiteBuildComponents = android.GroupFixturePreparers(
- android.FixtureRegisterWithContext(RegisterTestSuiteBuildComponents),
-)
-
-type testSuiteProperties struct {
- Description string
- Tests []string `android:"path,arch_variant"`
-}
-
-type testSuiteModule struct {
- android.ModuleBase
- android.DefaultableModuleBase
- testSuiteProperties
-}
-
-func (t *testSuiteModule) DepsMutator(ctx android.BottomUpMutatorContext) {
- for _, test := range t.Tests {
- if ctx.OtherModuleDependencyVariantExists(ctx.Config().BuildOSCommonTarget.Variations(), test) {
- // Host tests.
- ctx.AddVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), testSuiteTag{}, test)
- } else {
- // Target tests.
- ctx.AddDependency(ctx.Module(), testSuiteTag{}, test)
- }
- }
-}
-
-func (t *testSuiteModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- suiteName := ctx.ModuleName()
- modulesByName := make(map[string]android.Module)
- ctx.WalkDeps(func(child, parent android.Module) bool {
- // Recurse into test_suite dependencies.
- if ctx.OtherModuleType(child) == testSuiteModuleType {
- ctx.Phony(suiteName, android.PathForPhony(ctx, child.Name()))
- return true
- }
-
- // Only write out top level test suite dependencies here.
- if _, ok := ctx.OtherModuleDependencyTag(child).(testSuiteTag); !ok {
- return false
- }
-
- if !child.InstallInTestcases() {
- ctx.ModuleErrorf("test_suite only supports modules installed in testcases. %q is not installed in testcases.", child.Name())
- return false
- }
-
- modulesByName[child.Name()] = child
- return false
- })
-
- var files []string
- for name, module := range modulesByName {
- // Get the test provider data from the child.
- tp, ok := android.OtherModuleProvider(ctx, module, tradefed.BaseTestProviderKey)
- if !ok {
- // TODO: Consider printing out a list of all module types.
- ctx.ModuleErrorf("%q is not a test module.", name)
- continue
- }
-
- files = append(files, packageModuleFiles(ctx, suiteName, module, tp)...)
- ctx.Phony(suiteName, android.PathForPhony(ctx, name))
- }
-
- manifestPath := android.PathForSuiteInstall(ctx, suiteName, suiteName+".json")
- b, err := json.Marshal(testSuiteManifest{Name: suiteName, Files: android.SortedUniqueStrings(files)})
- if err != nil {
- ctx.ModuleErrorf("Failed to marshal manifest: %v", err)
- return
- }
- android.WriteFileRule(ctx, manifestPath, string(b))
-
- ctx.Phony(suiteName, manifestPath)
-}
-
-func TestSuiteFactory() android.Module {
- module := &testSuiteModule{}
- module.AddProperties(&module.testSuiteProperties)
-
- android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
- android.InitDefaultableModule(module)
-
- return module
-}
-
-func packageModuleFiles(ctx android.ModuleContext, suiteName string, module android.Module, tp tradefed.BaseTestProviderData) []string {
-
- hostOrTarget := "target"
- if tp.IsHost {
- hostOrTarget = "host"
- }
-
- // suiteRoot at out/soong/packaging/<suiteName>.
- suiteRoot := android.PathForSuiteInstall(ctx, suiteName)
-
- var installed android.InstallPaths
- // Install links to installed files from the module.
- if installFilesInfo, ok := android.OtherModuleProvider(ctx, module, android.InstallFilesProvider); ok {
- for _, f := range installFilesInfo.InstallFiles {
- // rel is anything under .../<partition>, normally under .../testcases.
- rel := android.Rel(ctx, f.PartitionDir(), f.String())
-
- // Install the file under <suiteRoot>/<host|target>/<partition>.
- installDir := suiteRoot.Join(ctx, hostOrTarget, f.Partition(), path.Dir(rel))
- linkTo, err := filepath.Rel(installDir.String(), f.String())
- if err != nil {
- ctx.ModuleErrorf("Failed to get relative path from %s to %s: %v", installDir.String(), f.String(), err)
- continue
- }
- installed = append(installed, ctx.InstallAbsoluteSymlink(installDir, path.Base(rel), linkTo))
- }
- }
-
- // Install config file.
- if tp.TestConfig != nil {
- moduleRoot := suiteRoot.Join(ctx, hostOrTarget, "testcases", module.Name())
- installed = append(installed, ctx.InstallFile(moduleRoot, module.Name()+".config", tp.TestConfig))
- }
-
- // Add to phony and manifest, manifestpaths are relative to suiteRoot.
- var manifestEntries []string
- for _, f := range installed {
- manifestEntries = append(manifestEntries, android.Rel(ctx, suiteRoot.String(), f.String()))
- ctx.Phony(suiteName, f)
- }
- return manifestEntries
-}
diff --git a/tradefed_modules/test_suite_test.go b/tradefed_modules/test_suite_test.go
deleted file mode 100644
index 3e1472c..0000000
--- a/tradefed_modules/test_suite_test.go
+++ /dev/null
@@ -1,151 +0,0 @@
-// 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 tradefed_modules
-
-import (
- "android/soong/android"
- "android/soong/java"
- "encoding/json"
- "slices"
- "testing"
-)
-
-func TestTestSuites(t *testing.T) {
- t.Parallel()
- ctx := android.GroupFixturePreparers(
- java.PrepareForTestWithJavaDefaultModules,
- android.FixtureRegisterWithContext(RegisterTestSuiteBuildComponents),
- ).RunTestWithBp(t, `
- android_test {
- name: "TestModule1",
- sdk_version: "current",
- }
-
- android_test {
- name: "TestModule2",
- sdk_version: "current",
- }
-
- test_suite {
- name: "my-suite",
- description: "a test suite",
- tests: [
- "TestModule1",
- "TestModule2",
- ]
- }
- `)
- manifestPath := ctx.ModuleForTests(t, "my-suite", "android_common").Output("out/soong/test_suites/my-suite/my-suite.json")
- var actual testSuiteManifest
- if err := json.Unmarshal([]byte(android.ContentFromFileRuleForTests(t, ctx.TestContext, manifestPath)), &actual); err != nil {
- t.Errorf("failed to unmarshal manifest: %v", err)
- }
- slices.Sort(actual.Files)
-
- expected := testSuiteManifest{
- Name: "my-suite",
- Files: []string{
- "target/testcases/TestModule1/TestModule1.config",
- "target/testcases/TestModule1/arm64/TestModule1.apk",
- "target/testcases/TestModule2/TestModule2.config",
- "target/testcases/TestModule2/arm64/TestModule2.apk",
- },
- }
-
- android.AssertDeepEquals(t, "manifests differ", expected, actual)
-}
-
-func TestTestSuitesWithNested(t *testing.T) {
- t.Parallel()
- ctx := android.GroupFixturePreparers(
- java.PrepareForTestWithJavaDefaultModules,
- android.FixtureRegisterWithContext(RegisterTestSuiteBuildComponents),
- ).RunTestWithBp(t, `
- android_test {
- name: "TestModule1",
- sdk_version: "current",
- }
-
- android_test {
- name: "TestModule2",
- sdk_version: "current",
- }
-
- android_test {
- name: "TestModule3",
- sdk_version: "current",
- }
-
- test_suite {
- name: "my-child-suite",
- description: "a child test suite",
- tests: [
- "TestModule1",
- "TestModule2",
- ]
- }
-
- test_suite {
- name: "my-all-tests-suite",
- description: "a parent test suite",
- tests: [
- "TestModule1",
- "TestModule3",
- "my-child-suite",
- ]
- }
- `)
- manifestPath := ctx.ModuleForTests(t, "my-all-tests-suite", "android_common").Output("out/soong/test_suites/my-all-tests-suite/my-all-tests-suite.json")
- var actual testSuiteManifest
- if err := json.Unmarshal([]byte(android.ContentFromFileRuleForTests(t, ctx.TestContext, manifestPath)), &actual); err != nil {
- t.Errorf("failed to unmarshal manifest: %v", err)
- }
- slices.Sort(actual.Files)
-
- expected := testSuiteManifest{
- Name: "my-all-tests-suite",
- Files: []string{
- "target/testcases/TestModule1/TestModule1.config",
- "target/testcases/TestModule1/arm64/TestModule1.apk",
- "target/testcases/TestModule2/TestModule2.config",
- "target/testcases/TestModule2/arm64/TestModule2.apk",
- "target/testcases/TestModule3/TestModule3.config",
- "target/testcases/TestModule3/arm64/TestModule3.apk",
- },
- }
-
- android.AssertDeepEquals(t, "manifests differ", expected, actual)
-}
-
-func TestTestSuitesNotInstalledInTestcases(t *testing.T) {
- t.Parallel()
- android.GroupFixturePreparers(
- java.PrepareForTestWithJavaDefaultModules,
- android.FixtureRegisterWithContext(RegisterTestSuiteBuildComponents),
- ).ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern([]string{
- `"SomeHostTest" is not installed in testcases`,
- })).RunTestWithBp(t, `
- java_test_host {
- name: "SomeHostTest",
- srcs: ["a.java"],
- }
- test_suite {
- name: "my-suite",
- description: "a test suite",
- tests: [
- "SomeHostTest",
- ]
- }
- `)
-}