diff options
-rw-r--r-- | aconfig/Android.bp | 11 | ||||
-rw-r--r-- | aconfig/all_aconfig_declarations.go | 40 | ||||
-rw-r--r-- | aconfig/all_aconfig_declarations_test.go | 48 | ||||
-rw-r--r-- | aconfig/init.go | 10 | ||||
-rw-r--r-- | android/android_info.go | 12 | ||||
-rw-r--r-- | android/compliance_metadata.go | 4 | ||||
-rw-r--r-- | android/config.go | 9 | ||||
-rw-r--r-- | android/variable.go | 2 | ||||
-rw-r--r-- | apex/apex.go | 11 | ||||
-rw-r--r-- | cc/cc.go | 29 | ||||
-rw-r--r-- | cc/test.go | 8 | ||||
-rw-r--r-- | filesystem/Android.bp | 1 | ||||
-rw-r--r-- | filesystem/filesystem.go | 70 | ||||
-rw-r--r-- | filesystem/super_image.go | 27 | ||||
-rw-r--r-- | filesystem/system_other.go | 137 | ||||
-rw-r--r-- | fsgen/filesystem_creator.go | 30 | ||||
-rw-r--r-- | fsgen/super_img.go | 11 | ||||
-rw-r--r-- | fsgen/vbmeta_partitions.go | 3 | ||||
-rw-r--r-- | java/aar.go | 2 | ||||
-rw-r--r-- | java/app_import_test.go | 39 | ||||
-rw-r--r-- | java/base.go | 9 | ||||
-rw-r--r-- | java/dex.go | 2 | ||||
-rw-r--r-- | java/droiddoc.go | 13 | ||||
-rw-r--r-- | java/droidstubs.go | 80 | ||||
-rw-r--r-- | java/droidstubs_test.go | 44 | ||||
-rw-r--r-- | java/java.go | 16 | ||||
-rw-r--r-- | scripts/gen_build_prop.py | 10 | ||||
-rw-r--r-- | ui/build/paths/config.go | 6 |
28 files changed, 524 insertions, 160 deletions
diff --git a/aconfig/Android.bp b/aconfig/Android.bp index 402cf1649..1505ba55e 100644 --- a/aconfig/Android.bp +++ b/aconfig/Android.bp @@ -25,7 +25,16 @@ bootstrap_go_package { "aconfig_declarations_test.go", "aconfig_values_test.go", "aconfig_value_set_test.go", - "all_aconfig_declarations_test.go", ], pluginFor: ["soong_build"], } + +all_aconfig_declarations { + name: "all_aconfig_declarations", + api_files: [ + ":frameworks-base-api-current.txt", + ":frameworks-base-api-system-current.txt", + ":frameworks-base-api-system-server-current.txt", + ":frameworks-base-api-module-lib-current.txt", + ], +} diff --git a/aconfig/all_aconfig_declarations.go b/aconfig/all_aconfig_declarations.go index 3262493c3..bb906077a 100644 --- a/aconfig/all_aconfig_declarations.go +++ b/aconfig/all_aconfig_declarations.go @@ -28,8 +28,11 @@ import ( // Note that this is ALL aconfig_declarations modules present in the tree, not just // ones that are relevant to the product currently being built, so that that infra // doesn't need to pull from multiple builds and merge them. -func AllAconfigDeclarationsFactory() android.Singleton { - return &allAconfigDeclarationsSingleton{releaseMap: make(map[string]allAconfigReleaseDeclarationsSingleton)} +func AllAconfigDeclarationsFactory() android.SingletonModule { + module := &allAconfigDeclarationsSingleton{releaseMap: make(map[string]allAconfigReleaseDeclarationsSingleton)} + module.AddProperties(&module.properties) + android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon) + return module } type allAconfigReleaseDeclarationsSingleton struct { @@ -37,8 +40,15 @@ type allAconfigReleaseDeclarationsSingleton struct { intermediateTextProtoPath android.OutputPath } +type allAconfigReleaseDeclarationsProperties struct { + Api_files []string `android:"arch_variant,path"` +} + type allAconfigDeclarationsSingleton struct { + android.SingletonModuleBase + releaseMap map[string]allAconfigReleaseDeclarationsSingleton + properties allAconfigReleaseDeclarationsProperties } func (this *allAconfigDeclarationsSingleton) sortedConfigNames() []string { @@ -50,7 +60,30 @@ func (this *allAconfigDeclarationsSingleton) sortedConfigNames() []string { return names } -func (this *allAconfigDeclarationsSingleton) GenerateBuildActions(ctx android.SingletonContext) { +func (this *allAconfigDeclarationsSingleton) GenerateAndroidBuildActions(ctx android.ModuleContext) { + apiFiles := android.Paths{} + for _, apiFile := range this.properties.Api_files { + if path := android.PathForModuleSrc(ctx, apiFile); path != nil { + apiFiles = append(apiFiles, path) + } + } + flagFile := android.PathForIntermediates(ctx, "all_aconfig_declarations.pb") + + output := android.PathForIntermediates(ctx, "finalized-flags.txt") + + ctx.Build(pctx, android.BuildParams{ + Rule: RecordFinalizedFlagsRule, + Inputs: append(apiFiles, flagFile), + Output: output, + Args: map[string]string{ + "api_files": android.JoinPathsWithPrefix(apiFiles, "--api-file "), + "flag_file": "--flag-file " + flagFile.String(), + }, + }) + ctx.Phony("all_aconfig_declarations", output) +} + +func (this *allAconfigDeclarationsSingleton) GenerateSingletonBuildActions(ctx android.SingletonContext) { for _, rcName := range append([]string{""}, ctx.Config().ReleaseAconfigExtraReleaseConfigs()...) { // Find all of the aconfig_declarations modules var packages = make(map[string]int) @@ -116,4 +149,5 @@ func (this *allAconfigDeclarationsSingleton) MakeVars(ctx android.MakeVarsContex ctx.DistForGoalWithFilename(goal, this.releaseMap[rcName].intermediateTextProtoPath, assembleFileName(rcName, "flags.textproto")) } } + ctx.DistForGoalWithFilename("sdk", android.PathForIntermediates(ctx, "finalized-flags.txt"), "finalized-flags.txt") } diff --git a/aconfig/all_aconfig_declarations_test.go b/aconfig/all_aconfig_declarations_test.go deleted file mode 100644 index 0b2021e7b..000000000 --- a/aconfig/all_aconfig_declarations_test.go +++ /dev/null @@ -1,48 +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 aconfig - -import ( - "testing" - - "android/soong/android" -) - -func TestTwoAconfigDeclarationsPerPackage(t *testing.T) { - bp := ` - aconfig_declarations { - name: "module_name.foo", - package: "com.example.package", - container: "com.android.foo", - srcs: [ - "foo.aconfig", - ], - } - - aconfig_declarations { - name: "module_name.bar", - package: "com.example.package", - container: "com.android.foo", - srcs: [ - "bar.aconfig", - ], - } - ` - errMsg := "Only one aconfig_declarations allowed for each package." - android.GroupFixturePreparers( - PrepareForTestWithAconfigBuildComponents). - ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(errMsg)). - RunTestWithBp(t, bp) -} diff --git a/aconfig/init.go b/aconfig/init.go index ab6ee46d0..e221153a7 100644 --- a/aconfig/init.go +++ b/aconfig/init.go @@ -70,6 +70,13 @@ var ( "${aconfig}", }, }, "cache_files") + RecordFinalizedFlagsRule = pctx.AndroidStaticRule("RecordFinalizedFlagsRule", + blueprint.RuleParams{ + Command: `${record-finalized-flags} ${flag_file} ${api_files} > ${out}`, + CommandDeps: []string{ + "${record-finalized-flags}", + }, + }, "api_files", "flag_file") CreateStorageRule = pctx.AndroidStaticRule("aconfig_create_storage", blueprint.RuleParams{ @@ -112,12 +119,13 @@ func init() { RegisterBuildComponents(android.InitRegistrationContext) pctx.HostBinToolVariable("aconfig", "aconfig") pctx.HostBinToolVariable("soong_zip", "soong_zip") + pctx.HostBinToolVariable("record-finalized-flags", "record-finalized-flags") } func RegisterBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("aconfig_declarations", DeclarationsFactory) ctx.RegisterModuleType("aconfig_values", ValuesFactory) ctx.RegisterModuleType("aconfig_value_set", ValueSetFactory) - ctx.RegisterParallelSingletonType("all_aconfig_declarations", AllAconfigDeclarationsFactory) + ctx.RegisterSingletonModuleType("all_aconfig_declarations", AllAconfigDeclarationsFactory) ctx.RegisterParallelSingletonType("exported_java_aconfig_library", ExportedJavaDeclarationsLibraryFactory) } diff --git a/android/android_info.go b/android/android_info.go index 561fa4c0c..9a68d1082 100644 --- a/android/android_info.go +++ b/android/android_info.go @@ -58,19 +58,17 @@ func (p *androidInfoModule) GenerateAndroidBuildActions(ctx ModuleContext) { androidInfoTxtName := proptools.StringDefault(p.properties.Stem, ctx.ModuleName()+".txt") androidInfoTxt := PathForModuleOut(ctx, androidInfoTxtName) androidInfoProp := androidInfoTxt.ReplaceExtension(ctx, "prop") - timestamp := PathForModuleOut(ctx, "timestamp") if boardInfoFiles := PathsForModuleSrc(ctx, p.properties.Board_info_files); len(boardInfoFiles) > 0 { ctx.Build(pctx, BuildParams{ - Rule: mergeAndRemoveComments, - Inputs: boardInfoFiles, - Output: androidInfoTxt, - Validation: timestamp, + Rule: mergeAndRemoveComments, + Inputs: boardInfoFiles, + Output: androidInfoTxt, }) } else if bootloaderBoardName := proptools.String(p.properties.Bootloader_board_name); bootloaderBoardName != "" { - WriteFileRule(ctx, androidInfoTxt, "board="+bootloaderBoardName, timestamp) + WriteFileRule(ctx, androidInfoTxt, "board="+bootloaderBoardName) } else { - WriteFileRule(ctx, androidInfoTxt, "", timestamp) + WriteFileRule(ctx, androidInfoTxt, "") } // Create android_info.prop diff --git a/android/compliance_metadata.go b/android/compliance_metadata.go index 2f11df6e0..dcf393d66 100644 --- a/android/compliance_metadata.go +++ b/android/compliance_metadata.go @@ -43,6 +43,7 @@ var ( STATIC_DEP_FILES string WHOLE_STATIC_DEPS string WHOLE_STATIC_DEP_FILES string + HEADER_LIBS string LICENSES string // module_type=package @@ -71,6 +72,7 @@ var ( "static_dep_files", "whole_static_deps", "whole_static_dep_files", + "header_libs", "licenses", "pkg_default_applicable_licenses", @@ -106,6 +108,8 @@ var ( ComplianceMetadataProp.WHOLE_STATIC_DEPS, // Space separated file paths of whole static dependencies ComplianceMetadataProp.WHOLE_STATIC_DEP_FILES, + // Space separated modules name of header libs + ComplianceMetadataProp.HEADER_LIBS, ComplianceMetadataProp.LICENSES, // module_type=package ComplianceMetadataProp.PKG_DEFAULT_APPLICABLE_LICENSES, diff --git a/android/config.go b/android/config.go index 39d6e2709..9c614f5b3 100644 --- a/android/config.go +++ b/android/config.go @@ -2175,6 +2175,10 @@ func (c *config) UseTransitiveJarsInClasspath() bool { return c.productVariables.GetBuildFlagBool("RELEASE_USE_TRANSITIVE_JARS_IN_CLASSPATH") } +func (c *config) UseR8FullModeByDefault() bool { + return c.productVariables.GetBuildFlagBool("RELEASE_R8_FULL_MODE_BY_DEFAULT") +} + func (c *config) UseR8OnlyRuntimeVisibleAnnotations() bool { return c.productVariables.GetBuildFlagBool("RELEASE_R8_ONLY_RUNTIME_VISIBLE_ANNOTATIONS") } @@ -2199,7 +2203,7 @@ var ( "RELEASE_APEX_CONTRIBUTIONS_CONFIGINFRASTRUCTURE": "com.android.configinfrastructure", "RELEASE_APEX_CONTRIBUTIONS_CONNECTIVITY": "com.android.tethering", "RELEASE_APEX_CONTRIBUTIONS_CONSCRYPT": "com.android.conscrypt", - "RELEASE_APEX_CONTRIBUTIONS_CRASHRECOVERY": "", + "RELEASE_APEX_CONTRIBUTIONS_CRASHRECOVERY": "com.android.crashrecovery", "RELEASE_APEX_CONTRIBUTIONS_DEVICELOCK": "com.android.devicelock", "RELEASE_APEX_CONTRIBUTIONS_DOCUMENTSUIGOOGLE": "", "RELEASE_APEX_CONTRIBUTIONS_EXTSERVICES": "com.android.extservices", @@ -2210,9 +2214,11 @@ var ( "RELEASE_APEX_CONTRIBUTIONS_MODULE_METADATA": "", "RELEASE_APEX_CONTRIBUTIONS_NETWORKSTACKGOOGLE": "", "RELEASE_APEX_CONTRIBUTIONS_NEURALNETWORKS": "com.android.neuralnetworks", + "RELEASE_APEX_CONTRIBUTIONS_NFC": "com.android.nfcservices", "RELEASE_APEX_CONTRIBUTIONS_ONDEVICEPERSONALIZATION": "com.android.ondevicepersonalization", "RELEASE_APEX_CONTRIBUTIONS_PERMISSION": "com.android.permission", "RELEASE_APEX_CONTRIBUTIONS_PRIMARY_LIBS": "", + "RELEASE_APEX_CONTRIBUTIONS_PROFILING": "com.android.profiling", "RELEASE_APEX_CONTRIBUTIONS_REMOTEKEYPROVISIONING": "com.android.rkpd", "RELEASE_APEX_CONTRIBUTIONS_RESOLV": "com.android.resolv", "RELEASE_APEX_CONTRIBUTIONS_SCHEDULING": "com.android.scheduling", @@ -2221,6 +2227,7 @@ var ( "RELEASE_APEX_CONTRIBUTIONS_STATSD": "com.android.os.statsd", "RELEASE_APEX_CONTRIBUTIONS_TELEMETRY_TVP": "", "RELEASE_APEX_CONTRIBUTIONS_TZDATA": "com.android.tzdata", + "RELEASE_APEX_CONTRIBUTIONS_UPROBESTATS": "com.android.uprobestats", "RELEASE_APEX_CONTRIBUTIONS_UWB": "com.android.uwb", "RELEASE_APEX_CONTRIBUTIONS_WIFI": "com.android.wifi", } diff --git a/android/variable.go b/android/variable.go index 08bcedf76..14094e2d8 100644 --- a/android/variable.go +++ b/android/variable.go @@ -623,6 +623,8 @@ type PartitionVariables struct { VendorDlkmSecurityPatch string `json:",omitempty"` OdmDlkmSecurityPatch string `json:",omitempty"` + BuildingSystemOtherImage bool `json:",omitempty"` + // Boot image stuff BuildingRamdiskImage bool `json:",omitempty"` ProductBuildBootImage bool `json:",omitempty"` diff --git a/apex/apex.go b/apex/apex.go index 428d57e08..d98cfae32 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -2570,7 +2570,7 @@ func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext fromName := ctx.OtherModuleName(from) toName := ctx.OtherModuleName(to) - // The dynamic linker and crash_dump tool in the runtime APEX is the only + // The dynamic linker and crash_dump tool in the runtime APEX is an // exception to this rule. It can't make the static dependencies dynamic // because it can't do the dynamic linking for itself. // Same rule should be applied to linkerconfig, because it should be executed @@ -2579,6 +2579,15 @@ func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext return false } + // b/389067742 adds libz as an exception to this check. Although libz is + // a part of NDK and thus provides a stable interface, it never was the + // intention because the upstream zlib provides neither ABI- nor behavior- + // stability. Therefore, we want to allow portable components like APEXes to + // bundle libz by statically linking to it. + if toName == "libz" { + return false + } + isStubLibraryFromOtherApex := info.HasStubsVariants && !librariesDirectlyInApex[toName] if isStubLibraryFromOtherApex && !externalDep { ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+ @@ -2409,7 +2409,7 @@ func (c *Module) setOutputFiles(ctx ModuleContext) { func buildComplianceMetadataInfo(ctx ModuleContext, c *Module, deps PathDeps) { // Dump metadata that can not be done in android/compliance-metadata.go complianceMetadataInfo := ctx.ComplianceMetadataInfo() - complianceMetadataInfo.SetStringValue(android.ComplianceMetadataProp.IS_STATIC_LIB, strconv.FormatBool(ctx.static())) + complianceMetadataInfo.SetStringValue(android.ComplianceMetadataProp.IS_STATIC_LIB, strconv.FormatBool(ctx.static() || ctx.ModuleType() == "cc_object")) complianceMetadataInfo.SetStringValue(android.ComplianceMetadataProp.BUILT_FILES, c.outputFile.String()) // Static deps @@ -2418,11 +2418,28 @@ func buildComplianceMetadataInfo(ctx ModuleContext, c *Module, deps PathDeps) { for _, dep := range staticDeps { staticDepNames = append(staticDepNames, dep.Name()) } + // Process CrtBegin and CrtEnd as static libs + ctx.VisitDirectDeps(func(dep android.Module) { + depName := ctx.OtherModuleName(dep) + depTag := ctx.OtherModuleDependencyTag(dep) + switch depTag { + case CrtBeginDepTag: + staticDepNames = append(staticDepNames, depName) + case CrtEndDepTag: + staticDepNames = append(staticDepNames, depName) + } + }) - staticDepPaths := make([]string, 0, len(deps.StaticLibs)) + staticDepPaths := make([]string, 0, len(deps.StaticLibs)+len(deps.CrtBegin)+len(deps.CrtEnd)) for _, dep := range deps.StaticLibs { staticDepPaths = append(staticDepPaths, dep.String()) } + for _, dep := range deps.CrtBegin { + staticDepPaths = append(staticDepPaths, dep.String()) + } + for _, dep := range deps.CrtEnd { + staticDepPaths = append(staticDepPaths, dep.String()) + } complianceMetadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEPS, android.FirstUniqueStrings(staticDepNames)) complianceMetadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEP_FILES, android.FirstUniqueStrings(staticDepPaths)) @@ -2439,6 +2456,14 @@ func buildComplianceMetadataInfo(ctx ModuleContext, c *Module, deps PathDeps) { } complianceMetadataInfo.SetListValue(android.ComplianceMetadataProp.WHOLE_STATIC_DEPS, android.FirstUniqueStrings(wholeStaticDepNames)) complianceMetadataInfo.SetListValue(android.ComplianceMetadataProp.WHOLE_STATIC_DEP_FILES, android.FirstUniqueStrings(wholeStaticDepPaths)) + + // Header libs + headerLibDeps := ctx.GetDirectDepsProxyWithTag(HeaderDepTag()) + headerLibDepNames := make([]string, 0, len(headerLibDeps)) + for _, dep := range headerLibDeps { + headerLibDepNames = append(headerLibDepNames, dep.Name()) + } + complianceMetadataInfo.SetListValue(android.ComplianceMetadataProp.HEADER_LIBS, android.FirstUniqueStrings(headerLibDepNames)) } func (c *Module) maybeUnhideFromMake() { diff --git a/cc/test.go b/cc/test.go index abf916219..32b155198 100644 --- a/cc/test.go +++ b/cc/test.go @@ -29,8 +29,8 @@ type TestLinkerProperties struct { // if set, build against the gtest library. Defaults to true. Gtest *bool - // if set, use the isolated gtest runner. Defaults to true if gtest is also true and the arch is Windows, false - // otherwise. + // if set, use the isolated gtest runner. Defaults to false. + // Isolation is not supported on Windows. Isolated *bool } @@ -198,8 +198,8 @@ func (test *testDecorator) gtest() bool { return BoolDefault(test.LinkerProperties.Gtest, true) } -func (test *testDecorator) isolated(ctx android.EarlyModuleContext) bool { - return BoolDefault(test.LinkerProperties.Isolated, false) +func (test *testDecorator) isolated(ctx android.BaseModuleContext) bool { + return BoolDefault(test.LinkerProperties.Isolated, false) && !ctx.Windows() } // NOTE: Keep this in sync with cc/cc_test.bzl#gtest_copts diff --git a/filesystem/Android.bp b/filesystem/Android.bp index 986b72edb..cb76df2d9 100644 --- a/filesystem/Android.bp +++ b/filesystem/Android.bp @@ -28,6 +28,7 @@ bootstrap_go_package { "raw_binary.go", "super_image.go", "system_image.go", + "system_other.go", "vbmeta.go", "testing.go", ], diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index ad19cc6e0..68cbee95f 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -20,6 +20,7 @@ import ( "io" "path/filepath" "slices" + "sort" "strconv" "strings" @@ -378,6 +379,13 @@ type FilesystemInfo struct { // Name of the module that produced this FilesystemInfo origionally. (though it may be // re-exported by super images or boot images) ModuleName string + // The property file generated by this module and passed to build_image. + // It's exported here so that system_other can reuse system's property file. + BuildImagePropFile android.Path + // Paths to all the tools referenced inside of the build image property file. + BuildImagePropFileDeps android.Paths + // Packaging specs to be installed on the system_other image, for the initial boot's dexpreopt. + SpecsForSystemOther map[string]android.PackagingSpec } var FilesystemProvider = blueprint.NewProvider[FilesystemInfo]() @@ -484,9 +492,11 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { var mapFile android.Path var outputHermetic android.Path + var buildImagePropFile android.Path + var buildImagePropFileDeps android.Paths switch f.fsType(ctx) { case ext4Type, erofsType, f2fsType: - f.output, outputHermetic = f.buildImageUsingBuildImage(ctx, builder, rootDir, rebasedDir) + f.output, outputHermetic, buildImagePropFile, buildImagePropFileDeps = f.buildImageUsingBuildImage(ctx, builder, rootDir, rebasedDir) mapFile = f.getMapFile(ctx) case compressedCpioType: f.output = f.buildCpioImage(ctx, builder, rootDir, true) @@ -508,17 +518,16 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { android.WriteFileRule(ctx, fileListFile, f.installedFilesList()) fsInfo := FilesystemInfo{ - Output: f.output, - FileListFile: fileListFile, - RootDir: rootDir, - RebasedDir: rebasedDir, - ModuleName: ctx.ModuleName(), - } - if mapFile != nil { - fsInfo.MapFile = mapFile - } - if outputHermetic != nil { - fsInfo.OutputHermetic = outputHermetic + Output: f.output, + OutputHermetic: outputHermetic, + FileListFile: fileListFile, + RootDir: rootDir, + RebasedDir: rebasedDir, + MapFile: mapFile, + ModuleName: ctx.ModuleName(), + BuildImagePropFile: buildImagePropFile, + BuildImagePropFileDeps: buildImagePropFileDeps, + SpecsForSystemOther: f.systemOtherFiles(ctx), } android.SetProvider(ctx, FilesystemProvider, fsInfo) @@ -670,7 +679,7 @@ func (f *filesystem) buildImageUsingBuildImage( builder *android.RuleBuilder, rootDir android.OutputPath, rebasedDir android.OutputPath, -) (android.Path, android.Path) { +) (android.Path, android.Path, android.Path, android.Paths) { // run host_init_verifier // Ideally we should have a concept of pluggable linters that verify the generated image. // While such concept is not implement this will do. @@ -701,7 +710,9 @@ func (f *filesystem) buildImageUsingBuildImage( // Add an additional cmd to create a hermetic img file. This will contain pinned timestamps e.g. propFilePinnedTimestamp := android.PathForModuleOut(ctx, "for_target_files", "prop") - builder.Command().Textf("cat").Input(propFile).Flag(">").Output(propFilePinnedTimestamp).Textf(" && echo use_fixed_timestamp=true >> %s", propFilePinnedTimestamp) + builder.Command().Textf("cat").Input(propFile).Flag(">").Output(propFilePinnedTimestamp). + Textf(" && echo use_fixed_timestamp=true >> %s", propFilePinnedTimestamp). + Textf(" && echo block_list=%s >> %s", f.getMapFile(ctx).String(), propFilePinnedTimestamp) // mapfile will be an implicit output outputHermetic := android.PathForModuleOut(ctx, "for_target_files", f.installFileName()) builder.Command(). @@ -721,7 +732,7 @@ func (f *filesystem) buildImageUsingBuildImage( // rootDir is not deleted. Might be useful for quick inspection. builder.Build("build_filesystem_image", fmt.Sprintf("Creating filesystem %s", f.BaseModuleName())) - return output, outputHermetic + return output, outputHermetic, propFile, toolDeps } func (f *filesystem) buildFileContexts(ctx android.ModuleContext) android.Path { @@ -736,12 +747,9 @@ func (f *filesystem) buildFileContexts(ctx android.ModuleContext) android.Path { func (f *filesystem) buildPropFile(ctx android.ModuleContext) (android.Path, android.Paths) { var deps android.Paths - var propFileString strings.Builder + var lines []string addStr := func(name string, value string) { - propFileString.WriteString(name) - propFileString.WriteRune('=') - propFileString.WriteString(value) - propFileString.WriteRune('\n') + lines = append(lines, fmt.Sprintf("%s=%s", name, value)) } addPath := func(name string, path android.Path) { addStr(name, path.String()) @@ -761,7 +769,6 @@ func (f *filesystem) buildPropFile(ctx android.ModuleContext) (android.Path, and } panic(fmt.Errorf("unsupported fs type %v", t)) } - addStr("block_list", f.getMapFile(ctx).String()) // This will be an implicit output addStr("fs_type", fsTypeStr(f.fsType(ctx))) addStr("mount_point", proptools.StringDefault(f.properties.Mount_point, "/")) @@ -871,8 +878,10 @@ func (f *filesystem) buildPropFile(ctx android.ModuleContext) (android.Path, and addStr("needs_compress", "1") } + sort.Strings(lines) + propFilePreProcessing := android.PathForModuleOut(ctx, "prop_pre_processing") - android.WriteFileRuleVerbatim(ctx, propFilePreProcessing, propFileString.String()) + android.WriteFileRule(ctx, propFilePreProcessing, strings.Join(lines, "\n")) propFile := android.PathForModuleOut(ctx, "prop") ctx.Build(pctx, android.BuildParams{ Rule: textFileProcessorRule, @@ -1065,8 +1074,21 @@ func (f *filesystem) SignedOutputPath() android.Path { // Note that "apex" module installs its contents to "apex"(fake partition) as well // for symbol lookup by imitating "activated" paths. func (f *filesystem) gatherFilteredPackagingSpecs(ctx android.ModuleContext) map[string]android.PackagingSpec { - specs := f.PackagingBase.GatherPackagingSpecsWithFilterAndModifier(ctx, f.filesystemBuilder.FilterPackagingSpec, f.filesystemBuilder.ModifyPackagingSpec) - return specs + return f.PackagingBase.GatherPackagingSpecsWithFilterAndModifier(ctx, f.filesystemBuilder.FilterPackagingSpec, f.filesystemBuilder.ModifyPackagingSpec) +} + +// Dexpreopt files are installed to system_other. Collect the packaingSpecs for the dexpreopt files +// from this partition to export to the system_other partition later. +func (f *filesystem) systemOtherFiles(ctx android.ModuleContext) map[string]android.PackagingSpec { + filter := func(spec android.PackagingSpec) bool { + // For some reason system_other packaging specs don't set the partition field. + return strings.HasPrefix(spec.RelPathInPackage(), "system_other/") + } + modifier := func(spec *android.PackagingSpec) { + spec.SetRelPathInPackage(strings.TrimPrefix(spec.RelPathInPackage(), "system_other/")) + spec.SetPartition("system_other") + } + return f.PackagingBase.GatherPackagingSpecsWithFilterAndModifier(ctx, filter, modifier) } func sha1sum(values []string) string { diff --git a/filesystem/super_image.go b/filesystem/super_image.go index 4419a2fbf..533246220 100644 --- a/filesystem/super_image.go +++ b/filesystem/super_image.go @@ -18,6 +18,7 @@ import ( "fmt" "path/filepath" "regexp" + "slices" "strconv" "strings" @@ -55,6 +56,9 @@ type SuperImageProperties struct { Sparse *bool // information about how partitions within the super partition are grouped together Partition_groups []PartitionGroupsInfo + // Name of the system_other partition filesystem module. This module will be installed to + // the "b" slot of the system partition in a/b partition builds. + System_other_partition *string // whether dynamic partitions is used Use_dynamic_partitions *bool Virtual_ab struct { @@ -127,6 +131,12 @@ type superImageDepTagType struct { var subImageDepTag superImageDepTagType +type systemOtherDepTagType struct { + blueprint.BaseDependencyTag +} + +var systemOtherDepTag systemOtherDepTagType + func (s *superImage) DepsMutator(ctx android.BottomUpMutatorContext) { addDependencyIfDefined := func(dep *string) { if dep != nil { @@ -143,6 +153,9 @@ func (s *superImage) DepsMutator(ctx android.BottomUpMutatorContext) { addDependencyIfDefined(s.partitionProps.Vendor_dlkm_partition) addDependencyIfDefined(s.partitionProps.Odm_partition) addDependencyIfDefined(s.partitionProps.Odm_dlkm_partition) + if s.properties.System_other_partition != nil { + ctx.AddDependency(ctx.Module(), systemOtherDepTag, *s.properties.System_other_partition) + } } func (s *superImage) GenerateAndroidBuildActions(ctx android.ModuleContext) { @@ -299,6 +312,20 @@ func (s *superImage) buildMiscInfo(ctx android.ModuleContext) (android.Path, and } } + if s.properties.System_other_partition != nil { + if !slices.Contains(partitionList, "system") { + ctx.PropertyErrorf("system_other_partition", "Must have a system partition to use a system_other partition") + } + systemOther := ctx.GetDirectDepProxyWithTag(*s.properties.System_other_partition, systemOtherDepTag) + systemOtherFiles := android.OutputFilesForModule(ctx, systemOther, "") + if len(systemOtherFiles) != 1 { + ctx.PropertyErrorf("system_other_partition", "Expected 1 output file from module %q", *&s.properties.System_other_partition) + } else { + addStr("system_other_image", systemOtherFiles[0].String()) + deps = append(deps, systemOtherFiles[0]) + } + } + // Delay the error message until execution time because on aosp-main-future-without-vendor, // BUILDING_VENDOR_IMAGE is false so we don't get the vendor image, but it's still listed in // BOARD_GOOGLE_DYNAMIC_PARTITIONS_PARTITION_LIST. diff --git a/filesystem/system_other.go b/filesystem/system_other.go new file mode 100644 index 000000000..28fe1ce49 --- /dev/null +++ b/filesystem/system_other.go @@ -0,0 +1,137 @@ +// 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 filesystem + +import ( + "android/soong/android" + "path/filepath" + "strings" + + "github.com/google/blueprint" + "github.com/google/blueprint/proptools" +) + +type SystemOtherImageProperties struct { + // The system_other image always requires a reference to the system image. The system_other + // partition gets built into the system partition's "b" slot in a/b partition builds. Thus, it + // copies most of its configuration from the system image, such as filesystem type, avb signing + // info, etc. Including it here does not automatically mean that it will pick up the system + // image's dexpropt files, it must also be listed in Preinstall_dexpreopt_files_from for that. + System_image *string + + // This system_other partition will include all the dexpreopt files from the apps on these + // partitions. + Preinstall_dexpreopt_files_from []string +} + +type systemOtherImage struct { + android.ModuleBase + android.DefaultableModuleBase + properties SystemOtherImageProperties +} + +// The system_other image is the default contents of the "b" slot of the system image. +// It contains the dexpreopt files of all the apps on the device, for a faster first boot. +// Afterwards, at runtime, it will be used as a regular b slot for OTA updates, and the initial +// dexpreopt files will be deleted. +func SystemOtherImageFactory() android.Module { + module := &systemOtherImage{} + module.AddProperties(&module.properties) + android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon) + android.InitDefaultableModule(module) + return module +} + +type systemImageDeptag struct { + blueprint.BaseDependencyTag +} + +var systemImageDependencyTag = systemImageDeptag{} + +type dexpreoptDeptag struct { + blueprint.BaseDependencyTag +} + +var dexpreoptDependencyTag = dexpreoptDeptag{} + +func (m *systemOtherImage) DepsMutator(ctx android.BottomUpMutatorContext) { + if proptools.String(m.properties.System_image) == "" { + ctx.ModuleErrorf("system_image property must be set") + return + } + ctx.AddDependency(ctx.Module(), systemImageDependencyTag, *m.properties.System_image) + ctx.AddDependency(ctx.Module(), dexpreoptDependencyTag, m.properties.Preinstall_dexpreopt_files_from...) +} + +func (m *systemOtherImage) GenerateAndroidBuildActions(ctx android.ModuleContext) { + systemImage := ctx.GetDirectDepProxyWithTag(*m.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 + } + + output := android.PathForModuleOut(ctx, "system_other.img") + stagingDir := android.PathForModuleOut(ctx, "staging_dir") + + builder := android.NewRuleBuilder(pctx, ctx) + builder.Command().Textf("rm -rf %s && mkdir -p %s", stagingDir, stagingDir) + + specs := make(map[string]android.PackagingSpec) + for _, otherPartition := range m.properties.Preinstall_dexpreopt_files_from { + dexModule := ctx.GetDirectDepProxyWithTag(otherPartition, dexpreoptDependencyTag) + fsInfo, ok := android.OtherModuleProvider(ctx, dexModule, FilesystemProvider) + if !ok { + ctx.PropertyErrorf("preinstall_dexpreopt_files_from", "Expected module %q to provide FilesystemProvider", otherPartition) + return + } + // Merge all the packaging specs into 1 map + for k := range fsInfo.SpecsForSystemOther { + if _, ok := specs[k]; ok { + ctx.ModuleErrorf("Packaging spec %s given by two different partitions", k) + continue + } + specs[k] = fsInfo.SpecsForSystemOther[k] + } + } + + // TOOD: CopySpecsToDir only exists on PackagingBase, but doesn't use any fields from it. Clean this up. + (&android.PackagingBase{}).CopySpecsToDir(ctx, builder, specs, stagingDir) + + if len(m.properties.Preinstall_dexpreopt_files_from) > 0 { + builder.Command().Textf("touch %s", filepath.Join(stagingDir.String(), "system-other-odex-marker")) + } + + // Most of the time, if build_image were to call a host tool, it accepts the path to the + // host tool in a field in the prop file. However, it doesn't have that option for fec, which + // it expects to just be on the PATH. Add fec to the PATH. + fec := ctx.Config().HostToolPath(ctx, "fec") + pathToolDirs := []string{filepath.Dir(fec.String())} + + builder.Command(). + Textf("PATH=%s:$PATH", strings.Join(pathToolDirs, ":")). + BuiltTool("build_image"). + Text(stagingDir.String()). // input directory + Input(systemInfo.BuildImagePropFile). + Implicits(systemInfo.BuildImagePropFileDeps). + Implicit(fec). + Output(output). + Text(stagingDir.String()) + + builder.Build("build_system_other", "build system other") + + ctx.SetOutputFiles(android.Paths{output}, "") + ctx.CheckbuildFile(output) +} diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go index 7f5a0682b..d2f00cd26 100644 --- a/fsgen/filesystem_creator.go +++ b/fsgen/filesystem_creator.go @@ -128,6 +128,10 @@ func (f *filesystemCreator) createInternalModules(ctx android.LoadHookContext) { f.properties.Unsupported_partition_types = append(f.properties.Unsupported_partition_types, partitionType) } } + finalSoongGeneratedPartitionNames := make([]string, 0, len(finalSoongGeneratedPartitions)) + for _, partitionType := range finalSoongGeneratedPartitions { + finalSoongGeneratedPartitionNames = append(finalSoongGeneratedPartitionNames, generatedModuleNameForPartition(ctx.Config(), partitionType)) + } // Create android_info.prop f.createAndroidInfo(ctx) @@ -156,6 +160,24 @@ func (f *filesystemCreator) createInternalModules(ctx android.LoadHookContext) { } } + var systemOtherImageName string + if buildingSystemOtherImage(partitionVars) { + systemModule := generatedModuleNameForPartition(ctx.Config(), "system") + systemOtherImageName = generatedModuleNameForPartition(ctx.Config(), "system_other") + ctx.CreateModule( + filesystem.SystemOtherImageFactory, + &filesystem.SystemOtherImageProperties{ + System_image: &systemModule, + Preinstall_dexpreopt_files_from: finalSoongGeneratedPartitionNames, + }, + &struct { + Name *string + }{ + Name: proptools.StringPtr(systemOtherImageName), + }, + ) + } + 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) @@ -163,7 +185,7 @@ func (f *filesystemCreator) createInternalModules(ctx android.LoadHookContext) { var superImageSubpartitions []string if buildingSuperImage(partitionVars) { - superImageSubpartitions = createSuperImage(ctx, finalSoongGeneratedPartitions, partitionVars) + superImageSubpartitions = createSuperImage(ctx, finalSoongGeneratedPartitions, partitionVars, systemOtherImageName) f.properties.Super_image = ":" + generatedModuleNameForPartition(ctx.Config(), "super") } @@ -183,6 +205,12 @@ func generatedModuleNameForPartition(cfg android.Config, partitionType string) s return generatedModuleName(cfg, fmt.Sprintf("%s_image", partitionType)) } +func buildingSystemOtherImage(partitionVars android.PartitionVariables) bool { + // TODO: Recreate this logic from make instead of just depending on the final result variable: + // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/board_config.mk;l=429;drc=15a0df840e7093f65518003ab80cf24a3d9e8e6a + return partitionVars.BuildingSystemOtherImage +} + func (f *filesystemCreator) createBootloaderFilegroup(ctx android.LoadHookContext) (string, bool) { bootloaderPath := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.PrebuiltBootloader if len(bootloaderPath) == 0 { diff --git a/fsgen/super_img.go b/fsgen/super_img.go index 5c23868b6..e3536888e 100644 --- a/fsgen/super_img.go +++ b/fsgen/super_img.go @@ -27,7 +27,12 @@ func buildingSuperImage(partitionVars android.PartitionVariables) bool { return partitionVars.ProductBuildSuperPartition } -func createSuperImage(ctx android.LoadHookContext, partitions []string, partitionVars android.PartitionVariables) []string { +func createSuperImage( + ctx android.LoadHookContext, + partitions []string, + partitionVars android.PartitionVariables, + systemOtherImageName string, +) []string { baseProps := &struct { Name *string }{ @@ -79,6 +84,10 @@ func createSuperImage(ctx android.LoadHookContext, partitions []string, partitio } superImageProps.Partition_groups = partitionGroupsInfo + if systemOtherImageName != "" { + superImageProps.System_other_partition = proptools.StringPtr(systemOtherImageName) + } + var superImageSubpartitions []string partitionNameProps := &filesystem.SuperImagePartitionNameProperties{} if android.InList("system", partitions) { diff --git a/fsgen/vbmeta_partitions.go b/fsgen/vbmeta_partitions.go index a75f59ce8..e3dc41679 100644 --- a/fsgen/vbmeta_partitions.go +++ b/fsgen/vbmeta_partitions.go @@ -154,8 +154,9 @@ func createVbmetaPartitions(ctx android.LoadHookContext, generatedPartitionTypes // Already handled by a chained vbmeta partition continue } - if strings.Contains(partitionType, "ramdisk") || strings.Contains(partitionType, "boot") || partitionType == "userdata" { + if strings.Contains(partitionType, "ramdisk") || strings.Contains(partitionType, "boot") || partitionType == "userdata" || partitionType == "recovery" { // ramdisk and userdata are never signed with avb information + // recovery partition is skipped in adding the partition descriptor into vbmeta.img. // boot partitions just have the avb footer, and don't have a corresponding vbmeta // partition. continue diff --git a/java/aar.go b/java/aar.go index b982b9571..3479f9376 100644 --- a/java/aar.go +++ b/java/aar.go @@ -1040,7 +1040,7 @@ func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) } prebuiltJniPackages := android.Paths{} - ctx.VisitDirectDeps(func(module android.Module) { + ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) { if info, ok := android.OtherModuleProvider(ctx, module, JniPackageProvider); ok { prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...) } diff --git a/java/app_import_test.go b/java/app_import_test.go index a28c28b18..2ec7ed47a 100644 --- a/java/app_import_test.go +++ b/java/app_import_test.go @@ -59,6 +59,45 @@ func TestAndroidAppImport(t *testing.T) { android.AssertStringEquals(t, "Invalid args", "/system/app/foo/foo.apk", rule.Args["install_path"]) } +func TestAndroidAppImportWithDefaults(t *testing.T) { + ctx, _ := testJava(t, ` + android_app_import { + name: "foo", + defaults: ["foo_defaults"], + } + + java_defaults { + name: "foo_defaults", + apk: "prebuilts/apk/app.apk", + certificate: "platform", + dex_preopt: { + enabled: true, + }, + } + `) + + variant := ctx.ModuleForTests("foo", "android_common") + + // Check dexpreopt outputs. + if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil || + variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.odex").Rule == nil { + t.Errorf("can't find dexpreopt outputs") + } + + // Check cert signing flag. + signedApk := variant.Output("signed/foo.apk") + signingFlag := signedApk.Args["certificates"] + expected := "build/make/target/product/security/platform.x509.pem build/make/target/product/security/platform.pk8" + if expected != signingFlag { + t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag) + } + rule := variant.Rule("genProvenanceMetaData") + android.AssertStringEquals(t, "Invalid input", "prebuilts/apk/app.apk", rule.Inputs[0].String()) + android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto", rule.Output.String()) + android.AssertStringEquals(t, "Invalid args", "foo", rule.Args["module_name"]) + android.AssertStringEquals(t, "Invalid args", "/system/app/foo/foo.apk", rule.Args["install_path"]) +} + func TestAndroidAppImport_NoDexPreopt(t *testing.T) { ctx, _ := testJava(t, ` android_app_import { diff --git a/java/base.go b/java/base.go index e551432e9..b55c93852 100644 --- a/java/base.go +++ b/java/base.go @@ -1336,6 +1336,12 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath kotlincFlags := j.properties.Kotlincflags CheckKotlincFlags(ctx, kotlincFlags) + // Available kotlin versions can be found at + // https://github.com/JetBrains/kotlin/blob/master/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt#L560 + // in the `LanguageVersion` class. + // For now, avoid targeting language versions directly, as we'd like to kee our source + // code version aligned as much as possible. Ideally, after defaulting to "2", we + // can remove the "1.9" option entirely, or at least make it emit a warning. kotlin_lang_version := proptools.StringDefault(j.properties.Kotlin_lang_version, "1.9") if kotlin_lang_version == "1.9" { kotlincFlags = append(kotlincFlags, "-language-version 1.9") @@ -1343,7 +1349,6 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath kotlincFlags = append(kotlincFlags, "-Xsuppress-version-warnings", "-Xconsistent-data-class-copy-visibility") } else { ctx.PropertyErrorf("kotlin_lang_version", "Must be one of `1.9` or `2`") - } // Workaround for KT-46512 @@ -1979,7 +1984,7 @@ func (j *Module) useCompose(ctx android.BaseModuleContext) bool { } func collectDepProguardSpecInfo(ctx android.ModuleContext) (transitiveProguardFlags, transitiveUnconditionalExportedFlags []depset.DepSet[android.Path]) { - ctx.VisitDirectDeps(func(m android.Module) { + ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) { depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider) depTag := ctx.OtherModuleDependencyTag(m) diff --git a/java/dex.go b/java/dex.go index bc142909e..00a0537e8 100644 --- a/java/dex.go +++ b/java/dex.go @@ -378,7 +378,7 @@ func (d *dexer) r8Flags(ctx android.ModuleContext, dexParams *compileDexParams, r8Flags = append(r8Flags, "--keep-runtime-invisible-annotations") } - if BoolDefault(opt.Proguard_compatibility, true) { + if BoolDefault(opt.Proguard_compatibility, !ctx.Config().UseR8FullModeByDefault()) { r8Flags = append(r8Flags, "--force-proguard-compatibility") } diff --git a/java/droiddoc.go b/java/droiddoc.go index 49674b98a..225f201a9 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -19,6 +19,7 @@ import ( "path/filepath" "strings" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" "android/soong/android" @@ -874,6 +875,13 @@ type ExportedDroiddocDirProperties struct { Path *string } +type ExportedDroiddocDirInfo struct { + Deps android.Paths + Dir android.Path +} + +var ExportedDroiddocDirInfoProvider = blueprint.NewProvider[ExportedDroiddocDirInfo]() + type ExportedDroiddocDir struct { android.ModuleBase @@ -897,6 +905,11 @@ func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleCont path := String(d.properties.Path) d.dir = android.PathForModuleSrc(ctx, path) d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")}) + + android.SetProvider(ctx, ExportedDroiddocDirInfoProvider, ExportedDroiddocDirInfo{ + Dir: d.dir, + Deps: d.deps, + }) } // Defaults diff --git a/java/droidstubs.go b/java/droidstubs.go index fa1fb8649..e0c2e637c 100644 --- a/java/droidstubs.go +++ b/java/droidstubs.go @@ -20,6 +20,7 @@ import ( "regexp" "strings" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" "android/soong/android" @@ -27,6 +28,18 @@ import ( "android/soong/remoteexec" ) +type StubsArtifactsInfo struct { + ApiVersionsXml android.WritablePath +} + +type DroidStubsInfo struct { + CurrentApiTimestamp android.Path + EverythingArtifacts StubsArtifactsInfo + ExportableArtifacts StubsArtifactsInfo +} + +var DroidStubsInfoProvider = blueprint.NewProvider[DroidStubsInfo]() + // The values allowed for Droidstubs' Api_levels_sdk_type var allowedApiLevelSdkTypes = []string{"public", "system", "module-lib", "system-server"} @@ -498,9 +511,9 @@ func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.Ru } func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) { - ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) { - if t, ok := m.(*ExportedDroiddocDir); ok { - cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps) + ctx.VisitDirectDepsProxyWithTag(metalavaMergeAnnotationsDirTag, func(m android.ModuleProxy) { + if t, ok := android.OtherModuleProvider(ctx, m, ExportedDroiddocDirInfoProvider); ok { + cmd.FlagWithArg("--merge-qualifier-annotations ", t.Dir.String()).Implicits(t.Deps) } else { ctx.PropertyErrorf("merge_annotations_dirs", "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m)) @@ -509,9 +522,9 @@ func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.R } func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) { - ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) { - if t, ok := m.(*ExportedDroiddocDir); ok { - cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps) + ctx.VisitDirectDepsProxyWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.ModuleProxy) { + if t, ok := android.OtherModuleProvider(ctx, m, ExportedDroiddocDirInfoProvider); ok { + cmd.FlagWithArg("--merge-inclusion-annotations ", t.Dir.String()).Implicits(t.Deps) } else { ctx.PropertyErrorf("merge_inclusion_annotations_dirs", "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m)) @@ -525,12 +538,12 @@ func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *a d.apiLevelsGenerationFlags(ctx, cmd, stubsType, apiVersionsXml) apiVersions = apiVersionsXml } else { - ctx.VisitDirectDepsWithTag(metalavaAPILevelsModuleTag, func(m android.Module) { - if s, ok := m.(*Droidstubs); ok { + ctx.VisitDirectDepsProxyWithTag(metalavaAPILevelsModuleTag, func(m android.ModuleProxy) { + if s, ok := android.OtherModuleProvider(ctx, m, DroidStubsInfoProvider); ok { if stubsType == Everything { - apiVersions = s.everythingArtifacts.apiVersionsXml + apiVersions = s.EverythingArtifacts.ApiVersionsXml } else if stubsType == Exportable { - apiVersions = s.exportableArtifacts.apiVersionsXml + apiVersions = s.ExportableArtifacts.ApiVersionsXml } else { ctx.ModuleErrorf("%s stubs type does not generate api-versions.xml file", stubsType.String()) } @@ -603,18 +616,18 @@ func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *an var dirs []string var extensions_dir string - ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) { - if t, ok := m.(*ExportedDroiddocDir); ok { - extRegex := regexp.MustCompile(t.dir.String() + extensionsPattern) + ctx.VisitDirectDepsProxyWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.ModuleProxy) { + if t, ok := android.OtherModuleProvider(ctx, m, ExportedDroiddocDirInfoProvider); ok { + extRegex := regexp.MustCompile(t.Dir.String() + extensionsPattern) // Grab the first extensions_dir and we find while scanning ExportedDroiddocDir.deps; // ideally this should be read from prebuiltApis.properties.Extensions_* - for _, dep := range t.deps { + for _, dep := range t.Deps { // Check to see if it matches an extension first. depBase := dep.Base() if extRegex.MatchString(dep.String()) && d.properties.Extensions_info_file != nil { if extensions_dir == "" { - extensions_dir = t.dir.String() + "/extensions" + extensions_dir = t.Dir.String() + "/extensions" } cmd.Implicit(dep) } else if depBase == filename { @@ -622,23 +635,17 @@ func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *an cmd.Implicit(dep) } else if depBase == AndroidPlusUpdatableJar && d.properties.Extensions_info_file != nil { // The output api-versions.xml has been requested to include information on SDK - // extensions. That means it also needs to include - // so - // The module-lib and system-server directories should use `android-plus-updatable.jar` - // instead of `android.jar`. See AndroidPlusUpdatableJar for more information. - cmd.Implicit(dep) - } else if filename != "android.jar" && depBase == "android.jar" { - // Metalava implicitly searches these patterns: - // prebuilts/tools/common/api-versions/android-{version:level}/android.jar - // prebuilts/sdk/{version:level}/public/android.jar - // Add android.jar files from the api_levels_annotations_dirs directories to try - // to satisfy these patterns. If Metalava can't find a match for an API level - // between 1 and 28 in at least one pattern it will fail. + // extensions, i.e. updatable Apis. That means it also needs to include the history of + // those updatable APIs. Usually, they would be included in the `android.jar` file but + // unfortunately, the `module-lib` and `system-server` cannot as it would lead to build + // cycles. So, the module-lib and system-server directories contain an + // `android-plus-updatable.jar` that should be used instead of `android.jar`. See + // AndroidPlusUpdatableJar for more information. cmd.Implicit(dep) } } - dirs = append(dirs, t.dir.String()) + dirs = append(dirs, t.Dir.String()) } else { ctx.PropertyErrorf("api_levels_annotations_dirs", "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m)) @@ -650,7 +657,7 @@ func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *an for _, sdkDir := range sdkDirs { for _, dir := range dirs { addPattern := func(jarFilename string) { - cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/{version:level}/%s/%s", dir, sdkDir, jarFilename)) + cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/{version:major.minor?}/%s/%s", dir, sdkDir, jarFilename)) } if sdkDir == "module-lib" || sdkDir == "system-server" { @@ -665,6 +672,10 @@ func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *an addPattern(filename) } + + if extensions_dir != "" { + cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/{version:extension}/%s/{module}.jar", extensions_dir, sdkDir)) + } } if d.properties.Extensions_info_file != nil { @@ -673,7 +684,6 @@ func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *an } info_file := android.PathForModuleSrc(ctx, *d.properties.Extensions_info_file) cmd.Implicit(info_file) - cmd.FlagWithArg("--sdk-extensions-root ", extensions_dir) cmd.FlagWithArg("--sdk-extensions-info ", info_file.String()) } } @@ -1340,6 +1350,16 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { rule.Build("nullabilityWarningsCheck", "nullability warnings check") } + android.SetProvider(ctx, DroidStubsInfoProvider, DroidStubsInfo{ + CurrentApiTimestamp: d.CurrentApiTimestamp(), + EverythingArtifacts: StubsArtifactsInfo{ + ApiVersionsXml: d.everythingArtifacts.apiVersionsXml, + }, + ExportableArtifacts: StubsArtifactsInfo{ + ApiVersionsXml: d.exportableArtifacts.apiVersionsXml, + }, + }) + d.setOutputFiles(ctx) } diff --git a/java/droidstubs_test.go b/java/droidstubs_test.go index 37740ae43..75a0a3175 100644 --- a/java/droidstubs_test.go +++ b/java/droidstubs_test.go @@ -88,7 +88,7 @@ func TestDroidstubs(t *testing.T) { cmdline := String(sboxProto.Commands[0].Command) android.AssertStringContainsEquals(t, "api-versions generation flag", cmdline, "--generate-api-levels", c.generate_xml) if c.expectedJarFilename != "" { - expected := "--android-jar-pattern ./{version:level}/public/" + c.expectedJarFilename + expected := "--android-jar-pattern ./{version:major.minor?}/public/" + c.expectedJarFilename if !strings.Contains(cmdline, expected) { t.Errorf("For %q, expected metalava argument %q, but was not found %q", c.moduleName, expected, cmdline) } @@ -142,8 +142,8 @@ func TestPublicDroidstubs(t *testing.T) { patterns := getAndroidJarPatternsForDroidstubs(t, "public") android.AssertArrayString(t, "order of patterns", []string{ - "--android-jar-pattern somedir/{version:level}/public/android.jar", - "--android-jar-pattern someotherdir/{version:level}/public/android.jar", + "--android-jar-pattern somedir/{version:major.minor?}/public/android.jar", + "--android-jar-pattern someotherdir/{version:major.minor?}/public/android.jar", }, patterns) } @@ -151,10 +151,10 @@ func TestSystemDroidstubs(t *testing.T) { patterns := getAndroidJarPatternsForDroidstubs(t, "system") android.AssertArrayString(t, "order of patterns", []string{ - "--android-jar-pattern somedir/{version:level}/system/android.jar", - "--android-jar-pattern someotherdir/{version:level}/system/android.jar", - "--android-jar-pattern somedir/{version:level}/public/android.jar", - "--android-jar-pattern someotherdir/{version:level}/public/android.jar", + "--android-jar-pattern somedir/{version:major.minor?}/system/android.jar", + "--android-jar-pattern someotherdir/{version:major.minor?}/system/android.jar", + "--android-jar-pattern somedir/{version:major.minor?}/public/android.jar", + "--android-jar-pattern someotherdir/{version:major.minor?}/public/android.jar", }, patterns) } @@ -162,12 +162,12 @@ func TestModuleLibDroidstubs(t *testing.T) { patterns := getAndroidJarPatternsForDroidstubs(t, "module-lib") android.AssertArrayString(t, "order of patterns", []string{ - "--android-jar-pattern somedir/{version:level}/module-lib/android.jar", - "--android-jar-pattern someotherdir/{version:level}/module-lib/android.jar", - "--android-jar-pattern somedir/{version:level}/system/android.jar", - "--android-jar-pattern someotherdir/{version:level}/system/android.jar", - "--android-jar-pattern somedir/{version:level}/public/android.jar", - "--android-jar-pattern someotherdir/{version:level}/public/android.jar", + "--android-jar-pattern somedir/{version:major.minor?}/module-lib/android.jar", + "--android-jar-pattern someotherdir/{version:major.minor?}/module-lib/android.jar", + "--android-jar-pattern somedir/{version:major.minor?}/system/android.jar", + "--android-jar-pattern someotherdir/{version:major.minor?}/system/android.jar", + "--android-jar-pattern somedir/{version:major.minor?}/public/android.jar", + "--android-jar-pattern someotherdir/{version:major.minor?}/public/android.jar", }, patterns) } @@ -175,14 +175,14 @@ func TestSystemServerDroidstubs(t *testing.T) { patterns := getAndroidJarPatternsForDroidstubs(t, "system-server") android.AssertArrayString(t, "order of patterns", []string{ - "--android-jar-pattern somedir/{version:level}/system-server/android.jar", - "--android-jar-pattern someotherdir/{version:level}/system-server/android.jar", - "--android-jar-pattern somedir/{version:level}/module-lib/android.jar", - "--android-jar-pattern someotherdir/{version:level}/module-lib/android.jar", - "--android-jar-pattern somedir/{version:level}/system/android.jar", - "--android-jar-pattern someotherdir/{version:level}/system/android.jar", - "--android-jar-pattern somedir/{version:level}/public/android.jar", - "--android-jar-pattern someotherdir/{version:level}/public/android.jar", + "--android-jar-pattern somedir/{version:major.minor?}/system-server/android.jar", + "--android-jar-pattern someotherdir/{version:major.minor?}/system-server/android.jar", + "--android-jar-pattern somedir/{version:major.minor?}/module-lib/android.jar", + "--android-jar-pattern someotherdir/{version:major.minor?}/module-lib/android.jar", + "--android-jar-pattern somedir/{version:major.minor?}/system/android.jar", + "--android-jar-pattern someotherdir/{version:major.minor?}/system/android.jar", + "--android-jar-pattern somedir/{version:major.minor?}/public/android.jar", + "--android-jar-pattern someotherdir/{version:major.minor?}/public/android.jar", }, patterns) } @@ -303,7 +303,7 @@ func TestDroidstubsWithSdkExtensions(t *testing.T) { m := ctx.ModuleForTests("baz-stubs", "android_common") manifest := m.Output("metalava.sbox.textproto") cmdline := String(android.RuleBuilderSboxProtoForTests(t, ctx, manifest).Commands[0].Command) - android.AssertStringDoesContain(t, "sdk-extensions-root present", cmdline, "--sdk-extensions-root sdk/extensions") + android.AssertStringDoesContain(t, "android-jar-pattern present", cmdline, "--android-jar-pattern sdk/extensions/{version:extension}/public/{module}.jar") android.AssertStringDoesContain(t, "sdk-extensions-info present", cmdline, "--sdk-extensions-info sdk/extensions/info.txt") } diff --git a/java/java.go b/java/java.go index f2c2af120..fafe9f964 100644 --- a/java/java.go +++ b/java/java.go @@ -1961,13 +1961,13 @@ func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Set the jniLibs of this binary. // These will be added to `LOCAL_REQUIRED_MODULES`, and the kati packaging system will // install these alongside the java binary. - ctx.VisitDirectDepsWithTag(jniInstallTag, func(jni android.Module) { + ctx.VisitDirectDepsProxyWithTag(jniInstallTag, func(jni android.ModuleProxy) { // Use the BaseModuleName of the dependency (without any prebuilt_ prefix) - bmn, _ := jni.(interface{ BaseModuleName() string }) - j.androidMkNamesOfJniLibs = append(j.androidMkNamesOfJniLibs, bmn.BaseModuleName()+":"+jni.Target().Arch.ArchType.Bitness()) + commonInfo, _ := android.OtherModuleProvider(ctx, jni, android.CommonModuleInfoKey) + j.androidMkNamesOfJniLibs = append(j.androidMkNamesOfJniLibs, commonInfo.BaseModuleName+":"+commonInfo.Target.Arch.ArchType.Bitness()) }) // Check that native libraries are not listed in `required`. Prompt users to use `jni_libs` instead. - ctx.VisitDirectDepsWithTag(android.RequiredDepTag, func(dep android.Module) { + ctx.VisitDirectDepsProxyWithTag(android.RequiredDepTag, func(dep android.ModuleProxy) { if _, hasSharedLibraryInfo := android.OtherModuleProvider(ctx, dep, cc.SharedLibraryInfoProvider); hasSharedLibraryInfo { ctx.ModuleErrorf("cc_library %s is no longer supported in `required` of java_binary modules. Please use jni_libs instead.", dep.Name()) } @@ -2358,7 +2358,7 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { var bootclassPaths android.Paths var staticLibs android.Paths var systemModulesPaths android.Paths - ctx.VisitDirectDeps(func(dep android.Module) { + ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) { tag := ctx.OtherModuleDependencyTag(dep) switch tag { case javaApiContributionTag: @@ -2387,8 +2387,8 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { systemModulesPaths = append(systemModulesPaths, sm.HeaderJars...) } case metalavaCurrentApiTimestampTag: - if currentApiTimestampProvider, ok := dep.(currentApiTimestampProvider); ok { - al.validationPaths = append(al.validationPaths, currentApiTimestampProvider.CurrentApiTimestamp()) + if currentApiTimestampProvider, ok := android.OtherModuleProvider(ctx, dep, DroidStubsInfoProvider); ok { + al.validationPaths = append(al.validationPaths, currentApiTimestampProvider.CurrentApiTimestamp) } case aconfigDeclarationTag: if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok { @@ -3361,6 +3361,8 @@ func DefaultsFactory() android.Module { &bootclasspathFragmentProperties{}, &SourceOnlyBootclasspathProperties{}, &ravenwoodTestProperties{}, + &AndroidAppImportProperties{}, + &UsesLibraryProperties{}, ) android.InitDefaultsModule(module) diff --git a/scripts/gen_build_prop.py b/scripts/gen_build_prop.py index 430e6134a..355f33d6c 100644 --- a/scripts/gen_build_prop.py +++ b/scripts/gen_build_prop.py @@ -308,7 +308,15 @@ def append_additional_system_props(args): props.append(f"ro.sanitize.{sanitize_target}=true") # Sets the default value of ro.postinstall.fstab.prefix to /system. - # Device board config should override the value to /product when needed by: + # + # Device board configs can override this to /product to use a + # product-specific fstab.postinstall file (installed to + # /product/etc/fstab.postinstall). If not overridden, the + # system/extras/cppreopts/fstab.postinstall file (installed to + # /system/etc/fstab.postinstall) will be used. + # Note: The default fstab.postinstall is generic and may be slower + # because it tries different mount options line by line to ensure + # compatibility across various devices. # # PRODUCT_PRODUCT_PROPERTIES += ro.postinstall.fstab.prefix=/product # diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go index 6c9a1ebb9..110ddee89 100644 --- a/ui/build/paths/config.go +++ b/ui/build/paths/config.go @@ -42,7 +42,7 @@ var Allowed = PathConfig{ } // This tool is specifically disallowed and calling it will result in an -// "executable no found" error. +// "executable not found" error. var Forbidden = PathConfig{ Symlink: false, Log: true, @@ -122,6 +122,10 @@ var Configuration = map[string]PathConfig{ "ld.bfd": Forbidden, "ld.gold": Forbidden, "pkg-config": Forbidden, + "python": Forbidden, + "python2": Forbidden, + "python2.7": Forbidden, + "python3": Forbidden, // These are toybox tools that only work on Linux. "pgrep": LinuxOnlyPrebuilt, |