diff options
Diffstat (limited to 'java')
| -rw-r--r-- | java/Android.bp | 2 | ||||
| -rw-r--r-- | java/androidmk.go | 14 | ||||
| -rw-r--r-- | java/androidmk_test.go | 149 | ||||
| -rwxr-xr-x | java/app.go | 27 | ||||
| -rw-r--r-- | java/app_set.go | 9 | ||||
| -rw-r--r-- | java/base.go | 56 | ||||
| -rw-r--r-- | java/bootclasspath_fragment.go | 56 | ||||
| -rw-r--r-- | java/config/config.go | 7 | ||||
| -rw-r--r-- | java/dexpreopt_bootjars.go | 80 | ||||
| -rw-r--r-- | java/dexpreopt_config_test.go | 35 | ||||
| -rw-r--r-- | java/dexpreopt_config_testing.go | 768 | ||||
| -rw-r--r-- | java/java.go | 1 | ||||
| -rw-r--r-- | java/java_test.go | 4 | ||||
| -rw-r--r-- | java/lint.go | 19 | ||||
| -rw-r--r-- | java/platform_bootclasspath.go | 4 | ||||
| -rw-r--r-- | java/robolectric.go | 4 | ||||
| -rw-r--r-- | java/rro.go | 7 | ||||
| -rw-r--r-- | java/rro_test.go | 4 | ||||
| -rw-r--r-- | java/sdk_library.go | 36 | ||||
| -rw-r--r-- | java/sdk_library_test.go | 75 | ||||
| -rw-r--r-- | java/testing.go | 1 |
21 files changed, 1257 insertions, 101 deletions
diff --git a/java/Android.bp b/java/Android.bp index 8510e045c..0bf7a0b26 100644 --- a/java/Android.bp +++ b/java/Android.bp @@ -43,6 +43,7 @@ bootstrap_go_package { "dexpreopt_bootjars.go", "dexpreopt_check.go", "dexpreopt_config.go", + "dexpreopt_config_testing.go", "droiddoc.go", "droidstubs.go", "fuzz.go", @@ -87,6 +88,7 @@ bootstrap_go_package { "dex_test.go", "dexpreopt_test.go", "dexpreopt_bootjars_test.go", + "dexpreopt_config_test.go", "droiddoc_test.go", "droidstubs_test.go", "genrule_test.go", diff --git a/java/androidmk.go b/java/androidmk.go index 75ac0e72d..cd86880b4 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -17,6 +17,7 @@ package java import ( "fmt" "io" + "strings" "android/soong/android" ) @@ -398,6 +399,19 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries { } else { for _, jniLib := range app.jniLibs { entries.AddStrings("LOCAL_SOONG_JNI_LIBS_"+jniLib.target.Arch.ArchType.String(), jniLib.name) + var partitionTag string + + // Mimic the creation of partition_tag in build/make, + // which defaults to an empty string when the partition is system. + // Otherwise, capitalize with a leading _ + if jniLib.partition == "system" { + partitionTag = "" + } else { + split := strings.Split(jniLib.partition, "/") + partitionTag = "_" + strings.ToUpper(split[len(split)-1]) + } + entries.AddStrings("LOCAL_SOONG_JNI_LIBS_PARTITION_"+jniLib.target.Arch.ArchType.String(), + jniLib.name+":"+partitionTag) } } diff --git a/java/androidmk_test.go b/java/androidmk_test.go index 197da4f38..1232cd1ee 100644 --- a/java/androidmk_test.go +++ b/java/androidmk_test.go @@ -19,6 +19,9 @@ import ( "testing" "android/soong/android" + "android/soong/cc" + + "github.com/google/blueprint/proptools" ) func TestRequired(t *testing.T) { @@ -252,3 +255,149 @@ func TestGetOverriddenPackages(t *testing.T) { android.AssertDeepEquals(t, "overrides property", expected.overrides, actual) } } + +func TestJniPartition(t *testing.T) { + bp := ` + cc_library { + name: "libjni_system", + system_shared_libs: [], + sdk_version: "current", + stl: "none", + } + + cc_library { + name: "libjni_system_ext", + system_shared_libs: [], + sdk_version: "current", + stl: "none", + system_ext_specific: true, + } + + cc_library { + name: "libjni_odm", + system_shared_libs: [], + sdk_version: "current", + stl: "none", + device_specific: true, + } + + cc_library { + name: "libjni_product", + system_shared_libs: [], + sdk_version: "current", + stl: "none", + product_specific: true, + } + + cc_library { + name: "libjni_vendor", + system_shared_libs: [], + sdk_version: "current", + stl: "none", + soc_specific: true, + } + + android_app { + name: "test_app_system_jni_system", + privileged: true, + platform_apis: true, + certificate: "platform", + jni_libs: ["libjni_system"], + } + + android_app { + name: "test_app_system_jni_system_ext", + privileged: true, + platform_apis: true, + certificate: "platform", + jni_libs: ["libjni_system_ext"], + } + + android_app { + name: "test_app_system_ext_jni_system", + privileged: true, + platform_apis: true, + certificate: "platform", + jni_libs: ["libjni_system"], + system_ext_specific: true + } + + android_app { + name: "test_app_system_ext_jni_system_ext", + sdk_version: "core_platform", + jni_libs: ["libjni_system_ext"], + system_ext_specific: true + } + + android_app { + name: "test_app_product_jni_product", + sdk_version: "core_platform", + jni_libs: ["libjni_product"], + product_specific: true + } + + android_app { + name: "test_app_vendor_jni_odm", + sdk_version: "core_platform", + jni_libs: ["libjni_odm"], + soc_specific: true + } + + android_app { + name: "test_app_odm_jni_vendor", + sdk_version: "core_platform", + jni_libs: ["libjni_vendor"], + device_specific: true + } + android_app { + name: "test_app_system_jni_multiple", + privileged: true, + platform_apis: true, + certificate: "platform", + jni_libs: ["libjni_system", "libjni_system_ext"], + } + android_app { + name: "test_app_vendor_jni_multiple", + sdk_version: "core_platform", + jni_libs: ["libjni_odm", "libjni_vendor"], + soc_specific: true + } + ` + arch := "arm64" + ctx := android.GroupFixturePreparers( + PrepareForTestWithJavaDefaultModules, + cc.PrepareForTestWithCcDefaultModules, + android.PrepareForTestWithAndroidMk, + android.FixtureModifyConfig(func(config android.Config) { + config.TestProductVariables.DeviceArch = proptools.StringPtr(arch) + }), + ). + RunTestWithBp(t, bp) + testCases := []struct { + name string + partitionNames []string + partitionTags []string + }{ + {"test_app_system_jni_system", []string{"libjni_system"}, []string{""}}, + {"test_app_system_jni_system_ext", []string{"libjni_system_ext"}, []string{"_SYSTEM_EXT"}}, + {"test_app_system_ext_jni_system", []string{"libjni_system"}, []string{""}}, + {"test_app_system_ext_jni_system_ext", []string{"libjni_system_ext"}, []string{"_SYSTEM_EXT"}}, + {"test_app_product_jni_product", []string{"libjni_product"}, []string{"_PRODUCT"}}, + {"test_app_vendor_jni_odm", []string{"libjni_odm"}, []string{"_ODM"}}, + {"test_app_odm_jni_vendor", []string{"libjni_vendor"}, []string{"_VENDOR"}}, + {"test_app_system_jni_multiple", []string{"libjni_system", "libjni_system_ext"}, []string{"", "_SYSTEM_EXT"}}, + {"test_app_vendor_jni_multiple", []string{"libjni_odm", "libjni_vendor"}, []string{"_ODM", "_VENDOR"}}, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + mod := ctx.ModuleForTests(test.name, "android_common").Module() + entry := android.AndroidMkEntriesForTest(t, ctx.TestContext, mod)[0] + for i := range test.partitionNames { + actual := entry.EntryMap["LOCAL_SOONG_JNI_LIBS_PARTITION_"+arch][i] + expected := test.partitionNames[i] + ":" + test.partitionTags[i] + android.AssertStringEquals(t, "Expected and actual differ", expected, actual) + } + }) + } +} diff --git a/java/app.go b/java/app.go index 1955e2a73..bbd9d2db1 100755 --- a/java/app.go +++ b/java/app.go @@ -798,6 +798,7 @@ func collectAppDeps(ctx android.ModuleContext, app appDepsInterface, target: module.Target(), coverageFile: dep.CoverageOutputFile(), unstrippedFile: dep.UnstrippedOutputFile(), + partition: dep.Partition(), }) } else { ctx.ModuleErrorf("dependency %q missing output file", otherName) @@ -1489,6 +1490,20 @@ type bazelAndroidAppAttributes struct { Certificate_name *string } +// ParseCertificateToAttribute splits the certificate prop into a certificate +// label attribute or a certificate_name string attribute. +func ParseCertificateToAttribute(ctx android.TopDownMutatorContext, certificate *string) (*string, *bazel.Label) { + var certificateLabel *bazel.Label + certificateName := proptools.StringDefault(certificate, "") + certModule := android.SrcIsModule(certificateName) + if certModule != "" { + c := android.BazelLabelForModuleDepSingle(ctx, certificateName) + certificateLabel = &c + certificate = nil + } + return certificate, certificateLabel +} + // ConvertWithBp2build is used to convert android_app to Bazel. func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) { commonAttrs, depLabels := a.convertLibraryAttrsBp2Build(ctx) @@ -1498,15 +1513,7 @@ func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) { aapt := a.convertAaptAttrsWithBp2Build(ctx) - var certificate *bazel.Label - certificateNamePtr := a.overridableAppProperties.Certificate - certificateName := proptools.StringDefault(certificateNamePtr, "") - certModule := android.SrcIsModule(certificateName) - if certModule != "" { - c := android.BazelLabelForModuleDepSingle(ctx, certificateName) - certificate = &c - certificateNamePtr = nil - } + certificateName, certificate := ParseCertificateToAttribute(ctx, a.overridableAppProperties.Certificate) attrs := &bazelAndroidAppAttributes{ commonAttrs, aapt, @@ -1514,7 +1521,7 @@ func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) { // TODO(b/209576404): handle package name override by product variable PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES a.overridableAppProperties.Package_name, certificate, - certificateNamePtr, + certificateName, } props := bazel.BazelTargetModuleProperties{ diff --git a/java/app_set.go b/java/app_set.go index 694b1670e..d99fadb34 100644 --- a/java/app_set.go +++ b/java/app_set.go @@ -90,10 +90,11 @@ func (as *AndroidAppSet) APKCertsFile() android.Path { } var TargetCpuAbi = map[string]string{ - "arm": "ARMEABI_V7A", - "arm64": "ARM64_V8A", - "x86": "X86", - "x86_64": "X86_64", + "arm": "ARMEABI_V7A", + "arm64": "ARM64_V8A", + "riscv64": "RISCV64", + "x86": "X86", + "x86_64": "X86_64", } func SupportedAbis(ctx android.ModuleContext) []string { diff --git a/java/base.go b/java/base.go index 656a08010..ab5a7d9a2 100644 --- a/java/base.go +++ b/java/base.go @@ -447,9 +447,11 @@ type Module struct { // installed file for hostdex copy hostdexInstallFile android.InstallPath - // list of .java files and srcjars that was passed to javac - compiledJavaSrcs android.Paths - compiledSrcJars android.Paths + // list of unique .java and .kt source files + uniqueSrcFiles android.Paths + + // list of srcjars that was passed to javac + compiledSrcJars android.Paths // manifest file to use instead of properties.Manifest overrideManifest android.OptionalPath @@ -893,7 +895,7 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB epEnabled := j.properties.Errorprone.Enabled if (ctx.Config().RunErrorProne() && epEnabled == nil) || Bool(epEnabled) { - if config.ErrorProneClasspath == nil && ctx.Config().TestProductVariables == nil { + if config.ErrorProneClasspath == nil && !ctx.Config().RunningInsideUnitTest() { ctx.ModuleErrorf("cannot build with Error Prone, missing external/error_prone?") } @@ -1078,15 +1080,26 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { jarName := ctx.ModuleName() + ".jar" - javaSrcFiles := srcFiles.FilterByExt(".java") - var uniqueSrcFiles android.Paths + var uniqueJavaFiles android.Paths set := make(map[string]bool) - for _, v := range javaSrcFiles { + for _, v := range srcFiles.FilterByExt(".java") { if _, found := set[v.String()]; !found { set[v.String()] = true - uniqueSrcFiles = append(uniqueSrcFiles, v) + uniqueJavaFiles = append(uniqueJavaFiles, v) } } + var uniqueKtFiles android.Paths + for _, v := range srcFiles.FilterByExt(".kt") { + if _, found := set[v.String()]; !found { + set[v.String()] = true + uniqueKtFiles = append(uniqueKtFiles, v) + } + } + + var uniqueSrcFiles android.Paths + uniqueSrcFiles = append(uniqueSrcFiles, uniqueJavaFiles...) + uniqueSrcFiles = append(uniqueSrcFiles, uniqueKtFiles...) + j.uniqueSrcFiles = uniqueSrcFiles // We don't currently run annotation processors in turbine, which means we can't use turbine // generated header jars when an annotation processor that generates API is enabled. One @@ -1094,7 +1107,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { // is used to run all of the annotation processors. disableTurbine := deps.disableTurbine - // Collect .java files for AIDEGen + // Collect .java and .kt files for AIDEGen j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, uniqueSrcFiles.Strings()...) var kotlinJars android.Paths @@ -1132,12 +1145,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { flags.kotlincFlags += "$kotlincFlags" } - var kotlinSrcFiles android.Paths - kotlinSrcFiles = append(kotlinSrcFiles, uniqueSrcFiles...) - kotlinSrcFiles = append(kotlinSrcFiles, srcFiles.FilterByExt(".kt")...) - - // Collect .kt files for AIDEGen - j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, srcFiles.FilterByExt(".kt").Strings()...) + // Collect common .kt files for AIDEGen j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, kotlinCommonSrcFiles.Strings()...) flags.classpath = append(flags.classpath, deps.kotlinStdlib...) @@ -1150,7 +1158,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { // Use kapt for annotation processing kaptSrcJar := android.PathForModuleOut(ctx, "kapt", "kapt-sources.jar") kaptResJar := android.PathForModuleOut(ctx, "kapt", "kapt-res.jar") - kotlinKapt(ctx, kaptSrcJar, kaptResJar, kotlinSrcFiles, kotlinCommonSrcFiles, srcJars, flags) + kotlinKapt(ctx, kaptSrcJar, kaptResJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags) srcJars = append(srcJars, kaptSrcJar) kotlinJars = append(kotlinJars, kaptResJar) // Disable annotation processing in javac, it's already been handled by kapt @@ -1160,7 +1168,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName) kotlinHeaderJar := android.PathForModuleOut(ctx, "kotlin_headers", jarName) - kotlinCompile(ctx, kotlinJar, kotlinHeaderJar, kotlinSrcFiles, kotlinCommonSrcFiles, srcJars, flags) + kotlinCompile(ctx, kotlinJar, kotlinHeaderJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags) if ctx.Failed() { return } @@ -1185,8 +1193,6 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { jars := append(android.Paths(nil), kotlinJars...) - // Store the list of .java files that was passed to javac - j.compiledJavaSrcs = uniqueSrcFiles j.compiledSrcJars = srcJars enableSharding := false @@ -1201,12 +1207,12 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { // with sharding enabled. See: b/77284273. } headerJarFileWithoutDepsOrJarjar, j.headerJarFile = - j.compileJavaHeader(ctx, uniqueSrcFiles, srcJars, deps, flags, jarName, kotlinHeaderJars) + j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, kotlinHeaderJars) if ctx.Failed() { return } } - if len(uniqueSrcFiles) > 0 || len(srcJars) > 0 { + if len(uniqueJavaFiles) > 0 || len(srcJars) > 0 { hasErrorproneableFiles := false for _, ext := range j.sourceExtensions { if ext != ".proto" && ext != ".aidl" { @@ -1231,7 +1237,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { errorproneFlags := enableErrorproneFlags(flags) errorprone := android.PathForModuleOut(ctx, "errorprone", jarName) - transformJavaToClasses(ctx, errorprone, -1, uniqueSrcFiles, srcJars, errorproneFlags, nil, + transformJavaToClasses(ctx, errorprone, -1, uniqueJavaFiles, srcJars, errorproneFlags, nil, "errorprone", "errorprone") extraJarDeps = append(extraJarDeps, errorprone) @@ -1243,8 +1249,8 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { } shardSize := int(*(j.properties.Javac_shard_size)) var shardSrcs []android.Paths - if len(uniqueSrcFiles) > 0 { - shardSrcs = android.ShardPaths(uniqueSrcFiles, shardSize) + if len(uniqueJavaFiles) > 0 { + shardSrcs = android.ShardPaths(uniqueJavaFiles, shardSize) for idx, shardSrc := range shardSrcs { classes := j.compileJavaClasses(ctx, jarName, idx, shardSrc, nil, flags, extraJarDeps) @@ -1257,7 +1263,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { jars = append(jars, classes) } } else { - classes := j.compileJavaClasses(ctx, jarName, -1, uniqueSrcFiles, srcJars, flags, extraJarDeps) + classes := j.compileJavaClasses(ctx, jarName, -1, uniqueJavaFiles, srcJars, flags, extraJarDeps) jars = append(jars, classes) } if ctx.Failed() { diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index f5b5f995b..3a28c5910 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -264,7 +264,7 @@ type commonBootclasspathFragment interface { // // If it could not create the files then it will return nil. Otherwise, it will return a map from // android.ArchType to the predefined paths of the boot image files. - produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageFilesByArch + produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs } var _ commonBootclasspathFragment = (*BootclasspathFragmentModule)(nil) @@ -583,23 +583,24 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo // Perform hidden API processing. hiddenAPIOutput := b.generateHiddenAPIBuildActions(ctx, contents, fragments) - var bootImageFilesByArch bootImageFilesByArch + var bootImageFiles bootImageOutputs if imageConfig != nil { // Delegate the production of the boot image files to a module type specific method. common := ctx.Module().(commonBootclasspathFragment) - bootImageFilesByArch = common.produceBootImageFiles(ctx, imageConfig) + bootImageFiles = common.produceBootImageFiles(ctx, imageConfig) if shouldCopyBootFilesToPredefinedLocations(ctx, imageConfig) { // Zip the boot image files up, if available. This will generate the zip file in a // predefined location. - buildBootImageZipInPredefinedLocation(ctx, imageConfig, bootImageFilesByArch) + buildBootImageZipInPredefinedLocation(ctx, imageConfig, bootImageFiles.byArch) // Copy the dex jars of this fragment's content modules to their predefined locations. copyBootJarsToPredefinedLocations(ctx, hiddenAPIOutput.EncodedBootDexFilesByModule, imageConfig.dexPathsByModule) } - for _, variant := range imageConfig.apexVariants() { - arch := variant.target.Arch.ArchType.String() + for _, variant := range bootImageFiles.variants { + archType := variant.config.target.Arch.ArchType + arch := archType.String() for _, install := range variant.deviceInstalls { // Remove the "/" prefix because the path should be relative to $ANDROID_PRODUCT_OUT. installDir := strings.TrimPrefix(filepath.Dir(install.To), "/") @@ -620,7 +621,7 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo // A prebuilt fragment cannot contribute to an apex. if !android.IsModulePrebuilt(ctx.Module()) { // Provide the apex content info. - b.provideApexContentInfo(ctx, imageConfig, hiddenAPIOutput, bootImageFilesByArch) + b.provideApexContentInfo(ctx, imageConfig, hiddenAPIOutput, bootImageFiles) } } else { // Versioned fragments are not needed by make. @@ -663,7 +664,7 @@ func shouldCopyBootFilesToPredefinedLocations(ctx android.ModuleContext, imageCo // provideApexContentInfo creates, initializes and stores the apex content info for use by other // modules. -func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleContext, imageConfig *bootImageConfig, hiddenAPIOutput *HiddenAPIOutput, bootImageFilesByArch bootImageFilesByArch) { +func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleContext, imageConfig *bootImageConfig, hiddenAPIOutput *HiddenAPIOutput, bootImageFiles bootImageOutputs) { // Construct the apex content info from the config. info := BootclasspathFragmentApexContentInfo{ // Populate the apex content info with paths to the dex jars. @@ -674,14 +675,14 @@ func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleC info.modules = imageConfig.modules global := dexpreopt.GetGlobalConfig(ctx) if !global.DisableGenerateProfile { - info.profilePathOnHost = imageConfig.profilePathOnHost + info.profilePathOnHost = bootImageFiles.profile info.profileInstallPathInApex = imageConfig.profileInstallPathInApex } info.shouldInstallBootImageInApex = imageConfig.shouldInstallInApex() } - info.bootImageFilesByArch = bootImageFilesByArch + info.bootImageFilesByArch = bootImageFiles.byArch // Make the apex content info available for other modules. ctx.SetProvider(BootclasspathFragmentApexContentInfoProvider, info) @@ -934,9 +935,9 @@ func (b *BootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleC } // produceBootImageFiles builds the boot image files from the source if it is required. -func (b *BootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageFilesByArch { +func (b *BootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs { if SkipDexpreoptBootJars(ctx) { - return nil + return bootImageOutputs{} } // Only generate the boot image if the configuration does not skip it. @@ -948,21 +949,21 @@ func (b *BootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleCo // // If it could not create the files then it will return nil. Otherwise, it will return a map from // android.ArchType to the predefined paths of the boot image files. -func (b *BootclasspathFragmentModule) generateBootImageBuildActions(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageFilesByArch { +func (b *BootclasspathFragmentModule) generateBootImageBuildActions(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs { global := dexpreopt.GetGlobalConfig(ctx) if !shouldBuildBootImages(ctx.Config(), global) { - return nil + return bootImageOutputs{} } // Bootclasspath fragment modules that are for the platform do not produce a boot image. apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) if apexInfo.IsForPlatform() { - return nil + return bootImageOutputs{} } // Bootclasspath fragment modules that are versioned do not produce a boot image. if android.IsModuleInVersionedSdk(ctx.Module()) { - return nil + return bootImageOutputs{} } // Build a profile for the image config and then use that to build the boot image. @@ -972,11 +973,11 @@ func (b *BootclasspathFragmentModule) generateBootImageBuildActions(ctx android. buildBootImageVariantsForBuildOs(ctx, imageConfig, profile) // Build boot image files for the android variants. - androidBootImageFilesByArch := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile) + bootImageFiles := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile) // Return the boot image files for the android variants for inclusion in an APEX and to be zipped // up for the dist. - return androidBootImageFilesByArch + return bootImageFiles } func (b *BootclasspathFragmentModule) AndroidMkEntries() []android.AndroidMkEntries { @@ -1277,14 +1278,14 @@ func (module *PrebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx an } // produceBootImageFiles extracts the boot image files from the APEX if available. -func (module *PrebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageFilesByArch { +func (module *PrebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs { if !shouldCopyBootFilesToPredefinedLocations(ctx, imageConfig) { - return nil + return bootImageOutputs{} } di := android.FindDeapexerProviderForModule(ctx) if di == nil { - return nil // An error has been reported by FindDeapexerProviderForModule. + return bootImageOutputs{} // An error has been reported by FindDeapexerProviderForModule. } profile := (android.WritablePath)(nil) @@ -1302,8 +1303,17 @@ func (module *PrebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx and // If the boot image files for the android variants are in the prebuilt apex, we must use those // rather than building new ones because those boot image files are going to be used on device. files := bootImageFilesByArch{} + bootImageFiles := bootImageOutputs{ + byArch: files, + profile: profile, + } for _, variant := range imageConfig.apexVariants() { arch := variant.target.Arch.ArchType + bootImageFiles.variants = append(bootImageFiles.variants, bootImageVariantOutputs{ + variant, + // No device installs needed when installed in APEX. + nil, + }) for _, toPath := range variant.imagesDeps { apexRelativePath := apexRootRelativePathToBootImageFile(arch, toPath.Base()) // Get the path to the file that the deapexer extracted from the prebuilt apex file. @@ -1321,11 +1331,11 @@ func (module *PrebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx and }) } } - return files + return bootImageFiles } else { if profile == nil { ctx.ModuleErrorf("Unable to produce boot image files: neither boot image files nor profiles exists in the prebuilt apex") - return nil + return bootImageOutputs{} } // Build boot image files for the android variants from the dex files provided by the contents // of this module. diff --git a/java/config/config.go b/java/config/config.go index ea44aaa08..a84c315d5 100644 --- a/java/config/config.go +++ b/java/config/config.go @@ -132,12 +132,7 @@ func init() { if override := ctx.Config().Getenv("OVERRIDE_JLINK_VERSION_NUMBER"); override != "" { return override } - switch ctx.Config().Getenv("EXPERIMENTAL_USE_OPENJDK17_TOOLCHAIN") { - case "true": - return "17" - default: - return "11" - } + return "17" }) pctx.SourcePathVariable("JavaToolchain", "${JavaHome}/bin") diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index 4e416fc82..b3faae895 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -228,6 +228,11 @@ func init() { } // Target-independent description of a boot image. +// +// WARNING: All fields in this struct should be initialized in the genBootImageConfigs function. +// Failure to do so can lead to data races if there is no synchronization enforced ordering between +// the writer and the reader. Fields which break this rule are marked as deprecated and should be +// removed and replaced with something else, e.g. providers. type bootImageConfig struct { // If this image is an extension, the image that it extends. extends *bootImageConfig @@ -268,14 +273,15 @@ type bootImageConfig struct { zip android.WritablePath // Rules which should be used in make to install the outputs. + // + // Deprecated: Not initialized correctly, see struct comment. profileInstalls android.RuleBuilderInstalls // Path to the license metadata file for the module that built the profile. + // + // Deprecated: Not initialized correctly, see struct comment. profileLicenseMetadataFile android.OptionalPath - // Path to the image profile file on host (or empty, if profile is not generated). - profilePathOnHost android.Path - // Target-dependent fields. variants []*bootImageVariant @@ -284,6 +290,8 @@ type bootImageConfig struct { } // Target-dependent description of a boot image. +// +// WARNING: The warning comment on bootImageConfig applies here too. type bootImageVariant struct { *bootImageConfig @@ -314,14 +322,23 @@ type bootImageVariant struct { primaryImagesDeps android.Paths // Rules which should be used in make to install the outputs on host. - installs android.RuleBuilderInstalls - vdexInstalls android.RuleBuilderInstalls - unstrippedInstalls android.RuleBuilderInstalls + // + // Deprecated: Not initialized correctly, see struct comment. + installs android.RuleBuilderInstalls - // Rules which should be used in make to install the outputs on device. - deviceInstalls android.RuleBuilderInstalls + // Rules which should be used in make to install the vdex outputs on host. + // + // Deprecated: Not initialized correctly, see struct comment. + vdexInstalls android.RuleBuilderInstalls + + // Rules which should be used in make to install the unstripped outputs on host. + // + // Deprecated: Not initialized correctly, see struct comment. + unstrippedInstalls android.RuleBuilderInstalls // Path to the license metadata file for the module that built the image. + // + // Deprecated: Not initialized correctly, see struct comment. licenseMetadataFile android.OptionalPath } @@ -548,7 +565,7 @@ func copyBootJarsToPredefinedLocations(ctx android.ModuleContext, srcBootDexJars // boot image files. // // The paths are returned because they are needed elsewhere in Soong, e.g. for populating an APEX. -func buildBootImageVariantsForAndroidOs(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath) bootImageFilesByArch { +func buildBootImageVariantsForAndroidOs(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath) bootImageOutputs { return buildBootImageForOsType(ctx, image, profile, android.Android) } @@ -563,21 +580,38 @@ func buildBootImageVariantsForBuildOs(ctx android.ModuleContext, image *bootImag buildBootImageForOsType(ctx, image, profile, ctx.Config().BuildOS) } +// bootImageOutputs encapsulates information about boot images that were created/obtained by +// commonBootclasspathFragment.produceBootImageFiles. +type bootImageOutputs struct { + // Map from arch to the paths to the boot image files created/obtained for that arch. + byArch bootImageFilesByArch + + variants []bootImageVariantOutputs + + // The path to the profile file created/obtained for the boot image. + profile android.WritablePath +} + // buildBootImageForOsType takes a bootImageConfig, a profile file and an android.OsType // boot image files are required for and it creates rules to build the boot image // files for all the required architectures for them. // // It returns a map from android.ArchType to the predefined paths of the boot image files. -func buildBootImageForOsType(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath, requiredOsType android.OsType) bootImageFilesByArch { +func buildBootImageForOsType(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath, requiredOsType android.OsType) bootImageOutputs { filesByArch := bootImageFilesByArch{} + imageOutputs := bootImageOutputs{ + byArch: filesByArch, + profile: profile, + } for _, variant := range image.variants { if variant.target.Os == requiredOsType { - buildBootImageVariant(ctx, variant, profile) + variantOutputs := buildBootImageVariant(ctx, variant, profile) + imageOutputs.variants = append(imageOutputs.variants, variantOutputs) filesByArch[variant.target.Arch.ArchType] = variant.imagesDeps.Paths() } } - return filesByArch + return imageOutputs } // buildBootImageZipInPredefinedLocation generates a zip file containing all the boot image files. @@ -605,8 +639,13 @@ func buildBootImageZipInPredefinedLocation(ctx android.ModuleContext, image *boo rule.Build("zip_"+image.name, "zip "+image.name+" image") } +type bootImageVariantOutputs struct { + config *bootImageVariant + deviceInstalls android.RuleBuilderInstalls +} + // Generate boot image build rules for a specific target. -func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, profile android.Path) { +func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, profile android.Path) bootImageVariantOutputs { globalSoong := dexpreopt.GetGlobalSoongConfig(ctx) global := dexpreopt.GetGlobalConfig(ctx) @@ -764,11 +803,20 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p rule.Build(image.name+"JarsDexpreopt_"+image.target.String(), "dexpreopt "+image.name+" jars "+arch.String()) // save output and installed files for makevars + // TODO - these are always the same and so should be initialized in genBootImageConfigs image.installs = rule.Installs() image.vdexInstalls = vdexInstalls image.unstrippedInstalls = unstrippedInstalls - image.deviceInstalls = deviceInstalls - image.licenseMetadataFile = android.OptionalPathForPath(ctx.LicenseMetadataFile()) + + // Only set the licenseMetadataFile from the active module. + if isActiveModule(ctx.Module()) { + image.licenseMetadataFile = android.OptionalPathForPath(ctx.LicenseMetadataFile()) + } + + return bootImageVariantOutputs{ + image, + deviceInstalls, + } } const failureMessage = `ERROR: Dex2oat failed to compile a boot image. @@ -824,8 +872,6 @@ func bootImageProfileRule(ctx android.ModuleContext, image *bootImageConfig) and rule.Build("bootJarsProfile", "profile boot jars") - image.profilePathOnHost = profile - return profile } diff --git a/java/dexpreopt_config_test.go b/java/dexpreopt_config_test.go new file mode 100644 index 000000000..b704d09d2 --- /dev/null +++ b/java/dexpreopt_config_test.go @@ -0,0 +1,35 @@ +// Copyright 2022 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 java + +import ( + "runtime" + "testing" + + "android/soong/android" +) + +func TestBootImageConfig(t *testing.T) { + if runtime.GOOS != "linux" { + t.Skipf("Skipping as boot image config test is only supported on linux not %s", runtime.GOOS) + } + + result := android.GroupFixturePreparers( + PrepareForBootImageConfigTest, + ).RunTest(t) + + CheckArtBootImageConfig(t, result) + CheckFrameworkBootImageConfig(t, result) +} diff --git a/java/dexpreopt_config_testing.go b/java/dexpreopt_config_testing.go new file mode 100644 index 000000000..1c236d8af --- /dev/null +++ b/java/dexpreopt_config_testing.go @@ -0,0 +1,768 @@ +// Copyright 2022 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. + +// Testing support for dexpreopt config. +// +// The bootImageConfig/bootImageVariant structs returned by genBootImageConfigs are used in many +// places in the build and are currently mutated in a number of those locations. This provides +// comprehensive tests of the fields in those structs to ensure that they have been initialized +// correctly and where relevant, mutated correctly. +// +// This is used in TestBootImageConfig to verify that the + +package java + +import ( + "fmt" + "strings" + "testing" + + "android/soong/android" +) + +// PrepareForBootImageConfigTest is the minimal set of preparers that are needed to be able to use +// the Check*BootImageConfig methods define here. +var PrepareForBootImageConfigTest = android.GroupFixturePreparers( + android.PrepareForTestWithArchMutator, + android.PrepareForTestAccessingMakeVars, + FixtureConfigureBootJars("com.android.art:core1", "com.android.art:core2", "platform:framework"), +) + +// normalizedInstall represents a android.RuleBuilderInstall that has been normalized to remove +// test specific parts of the From path. +type normalizedInstall struct { + from string + to string +} + +// normalizeInstalls converts a slice of android.RuleBuilderInstall into a slice of +// normalizedInstall to allow them to be compared using android.AssertDeepEquals. +func normalizeInstalls(installs android.RuleBuilderInstalls) []normalizedInstall { + var normalized []normalizedInstall + for _, install := range installs { + normalized = append(normalized, normalizedInstall{ + from: install.From.RelativeToTop().String(), + to: install.To, + }) + } + return normalized +} + +// assertInstallsEqual normalized the android.RuleBuilderInstalls and compares against the expected +// normalizedInstalls. +func assertInstallsEqual(t *testing.T, message string, expected []normalizedInstall, actual android.RuleBuilderInstalls) { + t.Helper() + normalizedActual := normalizeInstalls(actual) + android.AssertDeepEquals(t, message, expected, normalizedActual) +} + +// expectedConfig encapsulates the expected properties that will be set in a bootImageConfig +// +// Each field <x> in here is compared against the corresponding field <x> in bootImageConfig. +type expectedConfig struct { + name string + stem string + dir string + symbolsDir string + installDirOnDevice string + installDirOnHost string + profileInstallPathInApex string + modules android.ConfiguredJarList + dexPaths []string + dexPathsDeps []string + zip string + variants []*expectedVariant + + // Mutated fields + profileInstalls []normalizedInstall + profileLicenseMetadataFile string +} + +// expectedVariant encapsulates the expected properties that will be set in a bootImageVariant +// +// Each field <x> in here is compared against the corresponding field <x> in bootImageVariant +// except for archType which is compared against the target.Arch.ArchType field in bootImageVariant. +type expectedVariant struct { + archType android.ArchType + dexLocations []string + dexLocationsDeps []string + imagePathOnHost string + imagePathOnDevice string + imagesDeps []string + primaryImages string + primaryImagesDeps []string + + // Mutated fields + installs []normalizedInstall + vdexInstalls []normalizedInstall + unstrippedInstalls []normalizedInstall + licenseMetadataFile string +} + +// CheckArtBootImageConfig checks the status of the fields of the bootImageConfig and +// bootImageVariant structures that are returned from artBootImageConfig. +// +// This is before any fields are mutated. +func CheckArtBootImageConfig(t *testing.T, result *android.TestResult) { + checkArtBootImageConfig(t, result, false, "") +} + +// getArtImageConfig gets the ART bootImageConfig that was created during the test. +func getArtImageConfig(result *android.TestResult) *bootImageConfig { + pathCtx := &android.TestPathContext{TestResult: result} + imageConfig := artBootImageConfig(pathCtx) + return imageConfig +} + +// checkArtBootImageConfig checks the ART boot image. +// +// mutated is true if this is called after fields in the image have been mutated by the ART +// bootclasspath_fragment and false otherwise. +func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated bool, expectedLicenseMetadataFile string) { + imageConfig := getArtImageConfig(result) + + expected := &expectedConfig{ + name: "art", + stem: "boot", + dir: "out/soong/test_device/dex_artjars", + symbolsDir: "out/soong/test_device/dex_artjars_unstripped", + installDirOnDevice: "system/framework", + installDirOnHost: "apex/art_boot_images/javalib", + profileInstallPathInApex: "etc/boot-image.prof", + modules: android.CreateTestConfiguredJarList([]string{"com.android.art:core1", "com.android.art:core2"}), + dexPaths: []string{"out/soong/test_device/dex_artjars_input/core1.jar", "out/soong/test_device/dex_artjars_input/core2.jar"}, + dexPathsDeps: []string{"out/soong/test_device/dex_artjars_input/core1.jar", "out/soong/test_device/dex_artjars_input/core2.jar"}, + zip: "out/soong/test_device/dex_artjars/art.zip", + variants: []*expectedVariant{ + { + archType: android.Arm64, + dexLocations: []string{"/apex/com.android.art/javalib/core1.jar", "/apex/com.android.art/javalib/core2.jar"}, + dexLocationsDeps: []string{"/apex/com.android.art/javalib/core1.jar", "/apex/com.android.art/javalib/core2.jar"}, + imagePathOnHost: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art", + imagePathOnDevice: "/system/framework/arm64/boot.art", + imagesDeps: []string{ + "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art", + "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.oat", + "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex", + "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.art", + "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat", + "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex", + }, + installs: []normalizedInstall{ + { + from: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art", + to: "/apex/art_boot_images/javalib/arm64/boot.art", + }, + { + from: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.oat", + to: "/apex/art_boot_images/javalib/arm64/boot.oat", + }, + { + from: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.art", + to: "/apex/art_boot_images/javalib/arm64/boot-core2.art", + }, + { + from: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat", + to: "/apex/art_boot_images/javalib/arm64/boot-core2.oat", + }, + }, + vdexInstalls: []normalizedInstall{ + { + from: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex", + to: "/apex/art_boot_images/javalib/arm64/boot.vdex", + }, + { + from: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex", + to: "/apex/art_boot_images/javalib/arm64/boot-core2.vdex", + }, + }, + unstrippedInstalls: []normalizedInstall{ + { + from: "out/soong/test_device/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot.oat", + to: "/apex/art_boot_images/javalib/arm64/boot.oat", + }, + { + from: "out/soong/test_device/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot-core2.oat", + to: "/apex/art_boot_images/javalib/arm64/boot-core2.oat", + }, + }, + licenseMetadataFile: expectedLicenseMetadataFile, + }, + { + archType: android.Arm, + dexLocations: []string{"/apex/com.android.art/javalib/core1.jar", "/apex/com.android.art/javalib/core2.jar"}, + dexLocationsDeps: []string{"/apex/com.android.art/javalib/core1.jar", "/apex/com.android.art/javalib/core2.jar"}, + imagePathOnHost: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art", + imagePathOnDevice: "/system/framework/arm/boot.art", + imagesDeps: []string{ + "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art", + "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat", + "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex", + "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.art", + "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat", + "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex", + }, + installs: []normalizedInstall{ + { + from: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art", + to: "/apex/art_boot_images/javalib/arm/boot.art", + }, + { + from: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat", + to: "/apex/art_boot_images/javalib/arm/boot.oat", + }, + { + from: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.art", + to: "/apex/art_boot_images/javalib/arm/boot-core2.art", + }, + { + from: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat", + to: "/apex/art_boot_images/javalib/arm/boot-core2.oat", + }, + }, + vdexInstalls: []normalizedInstall{ + { + from: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex", + to: "/apex/art_boot_images/javalib/arm/boot.vdex", + }, + { + from: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex", + to: "/apex/art_boot_images/javalib/arm/boot-core2.vdex", + }, + }, + unstrippedInstalls: []normalizedInstall{ + { + from: "out/soong/test_device/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot.oat", + to: "/apex/art_boot_images/javalib/arm/boot.oat", + }, + { + from: "out/soong/test_device/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot-core2.oat", + to: "/apex/art_boot_images/javalib/arm/boot-core2.oat", + }, + }, + licenseMetadataFile: expectedLicenseMetadataFile, + }, + { + archType: android.X86_64, + dexLocations: []string{"host/linux-x86/apex/com.android.art/javalib/core1.jar", "host/linux-x86/apex/com.android.art/javalib/core2.jar"}, + dexLocationsDeps: []string{"host/linux-x86/apex/com.android.art/javalib/core1.jar", "host/linux-x86/apex/com.android.art/javalib/core2.jar"}, + imagePathOnHost: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art", + imagePathOnDevice: "/system/framework/x86_64/boot.art", + imagesDeps: []string{ + "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art", + "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat", + "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.vdex", + "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.art", + "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat", + "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.vdex", + }, + installs: []normalizedInstall{ + { + from: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art", + to: "/apex/art_boot_images/javalib/x86_64/boot.art", + }, { + from: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat", + to: "/apex/art_boot_images/javalib/x86_64/boot.oat", + }, + { + from: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.art", + to: "/apex/art_boot_images/javalib/x86_64/boot-core2.art", + }, { + from: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat", + to: "/apex/art_boot_images/javalib/x86_64/boot-core2.oat", + }, + }, + vdexInstalls: []normalizedInstall{ + { + from: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.vdex", + to: "/apex/art_boot_images/javalib/x86_64/boot.vdex", + }, + { + from: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.vdex", + to: "/apex/art_boot_images/javalib/x86_64/boot-core2.vdex", + }, + }, + unstrippedInstalls: []normalizedInstall{ + { + from: "out/soong/test_device/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat", + to: "/apex/art_boot_images/javalib/x86_64/boot.oat", + }, + { + from: "out/soong/test_device/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat", + to: "/apex/art_boot_images/javalib/x86_64/boot-core2.oat", + }, + }, + licenseMetadataFile: expectedLicenseMetadataFile, + }, + { + archType: android.X86, + dexLocations: []string{"host/linux-x86/apex/com.android.art/javalib/core1.jar", "host/linux-x86/apex/com.android.art/javalib/core2.jar"}, + dexLocationsDeps: []string{"host/linux-x86/apex/com.android.art/javalib/core1.jar", "host/linux-x86/apex/com.android.art/javalib/core2.jar"}, + imagePathOnHost: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art", + imagePathOnDevice: "/system/framework/x86/boot.art", + imagesDeps: []string{ + "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art", + "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat", + "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.vdex", + "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.art", + "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat", + "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex", + }, + installs: []normalizedInstall{ + { + from: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art", + to: "/apex/art_boot_images/javalib/x86/boot.art", + }, { + from: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat", + to: "/apex/art_boot_images/javalib/x86/boot.oat", + }, + { + from: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.art", + to: "/apex/art_boot_images/javalib/x86/boot-core2.art", + }, { + from: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat", + to: "/apex/art_boot_images/javalib/x86/boot-core2.oat", + }, + }, + vdexInstalls: []normalizedInstall{ + { + from: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.vdex", + to: "/apex/art_boot_images/javalib/x86/boot.vdex", + }, + { + from: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex", + to: "/apex/art_boot_images/javalib/x86/boot-core2.vdex", + }, + }, + unstrippedInstalls: []normalizedInstall{ + { + from: "out/soong/test_device/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat", + to: "/apex/art_boot_images/javalib/x86/boot.oat", + }, + { + from: "out/soong/test_device/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat", + to: "/apex/art_boot_images/javalib/x86/boot-core2.oat", + }, + }, + licenseMetadataFile: expectedLicenseMetadataFile, + }, + }, + } + + checkBootImageConfig(t, imageConfig, mutated, expected) +} + +// getFrameworkImageConfig gets the framework bootImageConfig that was created during the test. +func getFrameworkImageConfig(result *android.TestResult) *bootImageConfig { + pathCtx := &android.TestPathContext{TestResult: result} + imageConfig := defaultBootImageConfig(pathCtx) + return imageConfig +} + +// CheckFrameworkBootImageConfig checks the status of the fields of the bootImageConfig and +// bootImageVariant structures that are returned from defaultBootImageConfig. +// +// This is before any fields are mutated. +func CheckFrameworkBootImageConfig(t *testing.T, result *android.TestResult) { + checkFrameworkBootImageConfig(t, result, false, "") +} + +// checkFrameworkBootImageConfig checks the framework boot image. +// +// mutated is true if this is called after fields in the image have been mutated by the +// platform_bootclasspath and false otherwise. +func checkFrameworkBootImageConfig(t *testing.T, result *android.TestResult, mutated bool, expectedLicenseMetadataFile string) { + imageConfig := getFrameworkImageConfig(result) + + expected := &expectedConfig{ + name: "boot", + stem: "boot", + dir: "out/soong/test_device/dex_bootjars", + symbolsDir: "out/soong/test_device/dex_bootjars_unstripped", + installDirOnDevice: "system/framework", + installDirOnHost: "system/framework", + profileInstallPathInApex: "", + modules: android.CreateTestConfiguredJarList([]string{"platform:framework"}), + dexPaths: []string{"out/soong/test_device/dex_bootjars_input/framework.jar"}, + dexPathsDeps: []string{"out/soong/test_device/dex_artjars_input/core1.jar", "out/soong/test_device/dex_artjars_input/core2.jar", "out/soong/test_device/dex_bootjars_input/framework.jar"}, + zip: "out/soong/test_device/dex_bootjars/boot.zip", + variants: []*expectedVariant{ + { + archType: android.Arm64, + dexLocations: []string{"/system/framework/framework.jar"}, + dexLocationsDeps: []string{ + "/apex/com.android.art/javalib/core1.jar", + "/apex/com.android.art/javalib/core2.jar", + "/system/framework/framework.jar", + }, + imagePathOnHost: "out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.art", + imagePathOnDevice: "/system/framework/arm64/boot-framework.art", + imagesDeps: []string{ + "out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.art", + "out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.oat", + "out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.vdex", + }, + primaryImages: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art", + primaryImagesDeps: []string{ + "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art", + "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.oat", + "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex", + "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.art", + "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat", + "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex", + }, + installs: []normalizedInstall{ + { + from: "out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.art", + to: "/system/framework/arm64/boot-framework.art", + }, + { + from: "out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.oat", + to: "/system/framework/arm64/boot-framework.oat", + }, + }, + vdexInstalls: []normalizedInstall{ + { + from: "out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.vdex", + to: "/system/framework/arm64/boot-framework.vdex", + }, + }, + unstrippedInstalls: []normalizedInstall{ + { + from: "out/soong/test_device/dex_bootjars_unstripped/android/system/framework/arm64/boot-framework.oat", + to: "/system/framework/arm64/boot-framework.oat", + }, + }, + licenseMetadataFile: expectedLicenseMetadataFile, + }, + { + archType: android.Arm, + dexLocations: []string{"/system/framework/framework.jar"}, + dexLocationsDeps: []string{ + "/apex/com.android.art/javalib/core1.jar", + "/apex/com.android.art/javalib/core2.jar", + "/system/framework/framework.jar", + }, + imagePathOnHost: "out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.art", + imagePathOnDevice: "/system/framework/arm/boot-framework.art", + imagesDeps: []string{ + "out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.art", + "out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.oat", + "out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.vdex", + }, + primaryImages: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art", + primaryImagesDeps: []string{ + "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art", + "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat", + "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex", + "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.art", + "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat", + "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex", + }, + installs: []normalizedInstall{ + { + from: "out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.art", + to: "/system/framework/arm/boot-framework.art", + }, + { + from: "out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.oat", + to: "/system/framework/arm/boot-framework.oat", + }, + }, + vdexInstalls: []normalizedInstall{ + { + from: "out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.vdex", + to: "/system/framework/arm/boot-framework.vdex", + }, + }, + unstrippedInstalls: []normalizedInstall{ + { + from: "out/soong/test_device/dex_bootjars_unstripped/android/system/framework/arm/boot-framework.oat", + to: "/system/framework/arm/boot-framework.oat", + }, + }, + licenseMetadataFile: expectedLicenseMetadataFile, + }, + { + archType: android.X86_64, + dexLocations: []string{"host/linux-x86/system/framework/framework.jar"}, + dexLocationsDeps: []string{ + "host/linux-x86/apex/com.android.art/javalib/core1.jar", + "host/linux-x86/apex/com.android.art/javalib/core2.jar", + "host/linux-x86/system/framework/framework.jar", + }, + imagePathOnHost: "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.art", + imagePathOnDevice: "/system/framework/x86_64/boot-framework.art", + imagesDeps: []string{ + "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.art", + "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.oat", + "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.vdex", + }, + primaryImages: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art", + primaryImagesDeps: []string{ + "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art", + "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat", + "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.vdex", + "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.art", + "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat", + "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.vdex", + }, + installs: []normalizedInstall{ + { + from: "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.art", + to: "/system/framework/x86_64/boot-framework.art", + }, + { + from: "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.oat", + to: "/system/framework/x86_64/boot-framework.oat", + }, + }, + vdexInstalls: []normalizedInstall{ + { + from: "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.vdex", + to: "/system/framework/x86_64/boot-framework.vdex", + }, + }, + unstrippedInstalls: []normalizedInstall{ + { + from: "out/soong/test_device/dex_bootjars_unstripped/linux_glibc/system/framework/x86_64/boot-framework.oat", + to: "/system/framework/x86_64/boot-framework.oat", + }, + }, + licenseMetadataFile: expectedLicenseMetadataFile, + }, + { + archType: android.X86, + dexLocations: []string{"host/linux-x86/system/framework/framework.jar"}, + dexLocationsDeps: []string{ + "host/linux-x86/apex/com.android.art/javalib/core1.jar", + "host/linux-x86/apex/com.android.art/javalib/core2.jar", + "host/linux-x86/system/framework/framework.jar", + }, + imagePathOnHost: "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art", + imagePathOnDevice: "/system/framework/x86/boot-framework.art", + imagesDeps: []string{ + "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art", + "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.oat", + "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.vdex", + }, + primaryImages: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art", + primaryImagesDeps: []string{ + "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art", + "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat", + "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.vdex", + "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.art", + "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat", + "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex", + }, + installs: []normalizedInstall{ + { + from: "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art", + to: "/system/framework/x86/boot-framework.art", + }, + { + from: "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.oat", + to: "/system/framework/x86/boot-framework.oat", + }, + }, + vdexInstalls: []normalizedInstall{ + { + from: "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.vdex", + to: "/system/framework/x86/boot-framework.vdex", + }, + }, + unstrippedInstalls: []normalizedInstall{ + { + from: "out/soong/test_device/dex_bootjars_unstripped/linux_glibc/system/framework/x86/boot-framework.oat", + to: "/system/framework/x86/boot-framework.oat", + }, + }, + licenseMetadataFile: expectedLicenseMetadataFile, + }, + }, + profileInstalls: []normalizedInstall{ + {from: "out/soong/test_device/dex_bootjars/boot.bprof", to: "/system/etc/boot-image.bprof"}, + {from: "out/soong/test_device/dex_bootjars/boot.prof", to: "/system/etc/boot-image.prof"}, + }, + profileLicenseMetadataFile: expectedLicenseMetadataFile, + } + + checkBootImageConfig(t, imageConfig, mutated, expected) +} + +// clearMutatedFields clears fields in the expectedConfig that correspond to fields in the +// bootImageConfig/bootImageVariant structs which are mutated outside the call to +// genBootImageConfigs. +// +// This allows the resulting expectedConfig struct to be compared against the values of those boot +// image structs immediately the call to genBootImageConfigs. If this is not called then the +// expectedConfig struct will expect the boot image structs to have been mutated by the ART +// bootclasspath_fragment and the platform_bootclasspath. +func clearMutatedFields(expected *expectedConfig) { + expected.profileInstalls = nil + expected.profileLicenseMetadataFile = "" + for _, variant := range expected.variants { + variant.installs = nil + variant.vdexInstalls = nil + variant.unstrippedInstalls = nil + variant.licenseMetadataFile = "" + } +} + +// checkBootImageConfig checks a boot image against the expected contents. +// +// If mutated is false then this will clear any mutated fields in the expected contents back to the +// zero value so that they will match the unmodified values in the boot image. +// +// It runs the checks in an image specific subtest of the current test. +func checkBootImageConfig(t *testing.T, imageConfig *bootImageConfig, mutated bool, expected *expectedConfig) { + if !mutated { + clearMutatedFields(expected) + } + + t.Run(imageConfig.name, func(t *testing.T) { + nestedCheckBootImageConfig(t, imageConfig, expected) + }) +} + +// nestedCheckBootImageConfig does the work of comparing the image against the expected values and +// is run in an image specific subtest. +func nestedCheckBootImageConfig(t *testing.T, imageConfig *bootImageConfig, expected *expectedConfig) { + android.AssertStringEquals(t, "name", expected.name, imageConfig.name) + android.AssertStringEquals(t, "stem", expected.stem, imageConfig.stem) + android.AssertPathRelativeToTopEquals(t, "dir", expected.dir, imageConfig.dir) + android.AssertPathRelativeToTopEquals(t, "symbolsDir", expected.symbolsDir, imageConfig.symbolsDir) + android.AssertStringEquals(t, "installDirOnDevice", expected.installDirOnDevice, imageConfig.installDirOnDevice) + android.AssertStringEquals(t, "installDirOnHost", expected.installDirOnHost, imageConfig.installDirOnHost) + android.AssertStringEquals(t, "profileInstallPathInApex", expected.profileInstallPathInApex, imageConfig.profileInstallPathInApex) + android.AssertDeepEquals(t, "modules", expected.modules, imageConfig.modules) + android.AssertPathsRelativeToTopEquals(t, "dexPaths", expected.dexPaths, imageConfig.dexPaths.Paths()) + android.AssertPathsRelativeToTopEquals(t, "dexPathsDeps", expected.dexPathsDeps, imageConfig.dexPathsDeps.Paths()) + // dexPathsByModule is just a different representation of the other information in the config. + android.AssertPathRelativeToTopEquals(t, "zip", expected.zip, imageConfig.zip) + assertInstallsEqual(t, "profileInstalls", expected.profileInstalls, imageConfig.profileInstalls) + android.AssertStringEquals(t, "profileLicenseMetadataFile", expected.profileLicenseMetadataFile, imageConfig.profileLicenseMetadataFile.RelativeToTop().String()) + + android.AssertIntEquals(t, "variant count", 4, len(imageConfig.variants)) + for i, variant := range imageConfig.variants { + expectedVariant := expected.variants[i] + t.Run(variant.target.Arch.ArchType.String(), func(t *testing.T) { + android.AssertDeepEquals(t, "archType", expectedVariant.archType, variant.target.Arch.ArchType) + android.AssertDeepEquals(t, "dexLocations", expectedVariant.dexLocations, variant.dexLocations) + android.AssertDeepEquals(t, "dexLocationsDeps", expectedVariant.dexLocationsDeps, variant.dexLocationsDeps) + android.AssertPathRelativeToTopEquals(t, "imagePathOnHost", expectedVariant.imagePathOnHost, variant.imagePathOnHost) + android.AssertStringEquals(t, "imagePathOnDevice", expectedVariant.imagePathOnDevice, variant.imagePathOnDevice) + android.AssertPathsRelativeToTopEquals(t, "imagesDeps", expectedVariant.imagesDeps, variant.imagesDeps.Paths()) + android.AssertPathRelativeToTopEquals(t, "primaryImages", expectedVariant.primaryImages, variant.primaryImages) + android.AssertPathsRelativeToTopEquals(t, "primaryImagesDeps", expectedVariant.primaryImagesDeps, variant.primaryImagesDeps) + assertInstallsEqual(t, "installs", expectedVariant.installs, variant.installs) + assertInstallsEqual(t, "vdexInstalls", expectedVariant.vdexInstalls, variant.vdexInstalls) + assertInstallsEqual(t, "unstrippedInstalls", expectedVariant.unstrippedInstalls, variant.unstrippedInstalls) + android.AssertStringEquals(t, "licenseMetadataFile", expectedVariant.licenseMetadataFile, variant.licenseMetadataFile.RelativeToTop().String()) + }) + } +} + +// CheckMutatedArtBootImageConfig checks the mutated fields in the bootImageConfig/Variant for ART. +func CheckMutatedArtBootImageConfig(t *testing.T, result *android.TestResult, expectedLicenseMetadataFile string) { + checkArtBootImageConfig(t, result, true, expectedLicenseMetadataFile) + + // Check the dexpreopt make vars. Do it in here as it depends on the expected license metadata + // file at the moment and it + checkDexpreoptMakeVars(t, result, expectedLicenseMetadataFile) +} + +// CheckMutatedFrameworkBootImageConfig checks the mutated fields in the bootImageConfig/Variant for framework. +func CheckMutatedFrameworkBootImageConfig(t *testing.T, result *android.TestResult, expectedLicenseMetadataFile string) { + checkFrameworkBootImageConfig(t, result, true, expectedLicenseMetadataFile) +} + +// checkDexpreoptMakeVars checks the DEXPREOPT_ prefixed make vars produced by dexpreoptBootJars +// singleton. +func checkDexpreoptMakeVars(t *testing.T, result *android.TestResult, expectedLicenseMetadataFile string) { + vars := result.MakeVarsForTesting(func(variable android.MakeVarVariable) bool { + return strings.HasPrefix(variable.Name(), "DEXPREOPT_") + }) + + out := &strings.Builder{} + for _, v := range vars { + fmt.Fprintf(out, "%s=%s\n", v.Name(), android.StringRelativeToTop(result.Config, v.Value())) + } + format := ` +DEXPREOPT_BOOTCLASSPATH_DEX_FILES=out/soong/test_device/dex_artjars_input/core1.jar out/soong/test_device/dex_artjars_input/core2.jar out/soong/test_device/dex_bootjars_input/framework.jar +DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS=/apex/com.android.art/javalib/core1.jar /apex/com.android.art/javalib/core2.jar /system/framework/framework.jar +DEXPREOPT_BOOT_JARS_MODULES=platform:framework +DEXPREOPT_GEN=out/host/linux-x86/bin/dexpreopt_gen +DEXPREOPT_IMAGE_BUILT_INSTALLED_art_arm=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art:/apex/art_boot_images/javalib/arm/boot.art out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat:/apex/art_boot_images/javalib/arm/boot.oat out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.art:/apex/art_boot_images/javalib/arm/boot-core2.art out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat:/apex/art_boot_images/javalib/arm/boot-core2.oat +DEXPREOPT_IMAGE_BUILT_INSTALLED_art_arm64=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art:/apex/art_boot_images/javalib/arm64/boot.art out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.oat:/apex/art_boot_images/javalib/arm64/boot.oat out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.art:/apex/art_boot_images/javalib/arm64/boot-core2.art out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat:/apex/art_boot_images/javalib/arm64/boot-core2.oat +DEXPREOPT_IMAGE_BUILT_INSTALLED_art_host_x86=out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art:/apex/art_boot_images/javalib/x86/boot.art out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat:/apex/art_boot_images/javalib/x86/boot.oat out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.art:/apex/art_boot_images/javalib/x86/boot-core2.art out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat:/apex/art_boot_images/javalib/x86/boot-core2.oat +DEXPREOPT_IMAGE_BUILT_INSTALLED_art_host_x86_64=out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art:/apex/art_boot_images/javalib/x86_64/boot.art out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat:/apex/art_boot_images/javalib/x86_64/boot.oat out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.art:/apex/art_boot_images/javalib/x86_64/boot-core2.art out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat:/apex/art_boot_images/javalib/x86_64/boot-core2.oat +DEXPREOPT_IMAGE_BUILT_INSTALLED_boot_arm=out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.art:/system/framework/arm/boot-framework.art out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.oat:/system/framework/arm/boot-framework.oat +DEXPREOPT_IMAGE_BUILT_INSTALLED_boot_arm64=out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.art:/system/framework/arm64/boot-framework.art out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.oat:/system/framework/arm64/boot-framework.oat +DEXPREOPT_IMAGE_BUILT_INSTALLED_boot_host_x86=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art:/system/framework/x86/boot-framework.art out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.oat:/system/framework/x86/boot-framework.oat +DEXPREOPT_IMAGE_BUILT_INSTALLED_boot_host_x86_64=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.art:/system/framework/x86_64/boot-framework.art out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.oat:/system/framework/x86_64/boot-framework.oat +DEXPREOPT_IMAGE_DEPS_art_arm=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.art out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex +DEXPREOPT_IMAGE_DEPS_art_arm64=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.oat out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.art out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex +DEXPREOPT_IMAGE_DEPS_art_host_x86=out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.vdex out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.art out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex +DEXPREOPT_IMAGE_DEPS_art_host_x86_64=out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.vdex out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.art out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.vdex +DEXPREOPT_IMAGE_DEPS_boot_arm=out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.art out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.oat out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.vdex +DEXPREOPT_IMAGE_DEPS_boot_arm64=out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.art out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.oat out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.vdex +DEXPREOPT_IMAGE_DEPS_boot_host_x86=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.oat out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.vdex +DEXPREOPT_IMAGE_DEPS_boot_host_x86_64=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.art out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.oat out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.vdex +DEXPREOPT_IMAGE_LICENSE_METADATA_art_arm=%[1]s +DEXPREOPT_IMAGE_LICENSE_METADATA_art_arm64=%[1]s +DEXPREOPT_IMAGE_LICENSE_METADATA_art_host_x86=%[1]s +DEXPREOPT_IMAGE_LICENSE_METADATA_art_host_x86_64=%[1]s +DEXPREOPT_IMAGE_LICENSE_METADATA_boot_arm=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic +DEXPREOPT_IMAGE_LICENSE_METADATA_boot_arm64=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic +DEXPREOPT_IMAGE_LICENSE_METADATA_boot_host_x86=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic +DEXPREOPT_IMAGE_LICENSE_METADATA_boot_host_x86_64=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic +DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICEart=/system/framework/boot.art +DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICEboot=/system/framework/boot.art:/system/framework/boot-framework.art +DEXPREOPT_IMAGE_LOCATIONS_ON_HOSTart=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/boot.art +DEXPREOPT_IMAGE_LOCATIONS_ON_HOSTboot=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/boot.art:out/soong/test_device/dex_bootjars/android/system/framework/boot-framework.art +DEXPREOPT_IMAGE_NAMES=art boot +DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED=out/soong/test_device/dex_bootjars/boot.bprof:/system/etc/boot-image.bprof out/soong/test_device/dex_bootjars/boot.prof:/system/etc/boot-image.prof +DEXPREOPT_IMAGE_PROFILE_LICENSE_METADATA=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic +DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_arm=out/soong/test_device/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot.oat:/apex/art_boot_images/javalib/arm/boot.oat out/soong/test_device/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot-core2.oat:/apex/art_boot_images/javalib/arm/boot-core2.oat +DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_arm64=out/soong/test_device/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot.oat:/apex/art_boot_images/javalib/arm64/boot.oat out/soong/test_device/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot-core2.oat:/apex/art_boot_images/javalib/arm64/boot-core2.oat +DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_host_x86=out/soong/test_device/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat:/apex/art_boot_images/javalib/x86/boot.oat out/soong/test_device/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat:/apex/art_boot_images/javalib/x86/boot-core2.oat +DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_host_x86_64=out/soong/test_device/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat:/apex/art_boot_images/javalib/x86_64/boot.oat out/soong/test_device/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat:/apex/art_boot_images/javalib/x86_64/boot-core2.oat +DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_boot_arm=out/soong/test_device/dex_bootjars_unstripped/android/system/framework/arm/boot-framework.oat:/system/framework/arm/boot-framework.oat +DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_boot_arm64=out/soong/test_device/dex_bootjars_unstripped/android/system/framework/arm64/boot-framework.oat:/system/framework/arm64/boot-framework.oat +DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_boot_host_x86=out/soong/test_device/dex_bootjars_unstripped/linux_glibc/system/framework/x86/boot-framework.oat:/system/framework/x86/boot-framework.oat +DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_boot_host_x86_64=out/soong/test_device/dex_bootjars_unstripped/linux_glibc/system/framework/x86_64/boot-framework.oat:/system/framework/x86_64/boot-framework.oat +DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_arm=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex:/apex/art_boot_images/javalib/arm/boot.vdex out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex:/apex/art_boot_images/javalib/arm/boot-core2.vdex +DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_arm64=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex:/apex/art_boot_images/javalib/arm64/boot.vdex out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex:/apex/art_boot_images/javalib/arm64/boot-core2.vdex +DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_host_x86=out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.vdex:/apex/art_boot_images/javalib/x86/boot.vdex out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex:/apex/art_boot_images/javalib/x86/boot-core2.vdex +DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_host_x86_64=out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.vdex:/apex/art_boot_images/javalib/x86_64/boot.vdex out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.vdex:/apex/art_boot_images/javalib/x86_64/boot-core2.vdex +DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_boot_arm=out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.vdex:/system/framework/arm/boot-framework.vdex +DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_boot_arm64=out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.vdex:/system/framework/arm64/boot-framework.vdex +DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_boot_host_x86=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.vdex:/system/framework/x86/boot-framework.vdex +DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_boot_host_x86_64=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.vdex:/system/framework/x86_64/boot-framework.vdex +DEXPREOPT_IMAGE_ZIP_art=out/soong/test_device/dex_artjars/art.zip +DEXPREOPT_IMAGE_ZIP_boot=out/soong/test_device/dex_bootjars/boot.zip +DEXPREOPT_IMAGE_art_arm=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art +DEXPREOPT_IMAGE_art_arm64=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art +DEXPREOPT_IMAGE_art_host_x86=out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art +DEXPREOPT_IMAGE_art_host_x86_64=out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art +DEXPREOPT_IMAGE_boot_arm=out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.art +DEXPREOPT_IMAGE_boot_arm64=out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.art +DEXPREOPT_IMAGE_boot_host_x86=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art +DEXPREOPT_IMAGE_boot_host_x86_64=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.art +` + expected := strings.TrimSpace(fmt.Sprintf(format, expectedLicenseMetadataFile)) + actual := strings.TrimSpace(out.String()) + android.AssertStringEquals(t, "vars", expected, actual) +} diff --git a/java/java.go b/java/java.go index fc2af3b17..5091d26a2 100644 --- a/java/java.go +++ b/java/java.go @@ -421,6 +421,7 @@ type jniLib struct { target android.Target coverageFile android.OptionalPath unstrippedFile android.Path + partition string } func sdkDeps(ctx android.BottomUpMutatorContext, sdkContext android.SdkContext, d dexer) { diff --git a/java/java_test.go b/java/java_test.go index 7f0cea718..d2373e349 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -588,8 +588,8 @@ func TestPrebuilts(t *testing.T) { sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs", "android_common").Rule("combineJar").Output fooLibrary := fooModule.Module().(*Library) - assertDeepEquals(t, "foo java sources incorrect", - []string{"a.java"}, fooLibrary.compiledJavaSrcs.Strings()) + assertDeepEquals(t, "foo unique sources incorrect", + []string{"a.java"}, fooLibrary.uniqueSrcFiles.Strings()) assertDeepEquals(t, "foo java source jars incorrect", []string{".intermediates/stubs-source/android_common/stubs-source-stubs.srcjar"}, diff --git a/java/lint.go b/java/lint.go index 931820d74..fcd6d31ff 100644 --- a/java/lint.go +++ b/java/lint.go @@ -473,20 +473,23 @@ func (l *linter) lint(ctx android.ModuleContext) { cmd.FlagWithOutput("--write-reference-baseline ", baseline) - cmd.Text("|| (").Text("if [ -e").Input(text).Text("]; then cat").Input(text).Text("; fi; exit 7)") - - rule.Command().Text("rm -rf").Flag(lintPaths.cacheDir.String()).Flag(lintPaths.homeDir.String()) - - // The HTML output contains a date, remove it to make the output deterministic. - rule.Command().Text(`sed -i.tmp -e 's|Check performed at .*\(</nav>\)|\1|'`).Output(html) + cmd.Text("; EXITCODE=$?; ") // The sources in the sandbox may have been modified by --apply-suggestions, zip them up and - // export them out of the sandbox. - rule.Command().BuiltTool("soong_zip"). + // export them out of the sandbox. Do this before exiting so that the suggestions exit even after + // a fatal error. + cmd.BuiltTool("soong_zip"). FlagWithOutput("-o ", android.PathForModuleOut(ctx, "lint", "suggested-fixes.zip")). FlagWithArg("-C ", cmd.PathForInput(android.PathForSource(ctx))). FlagWithInput("-r ", srcsList) + cmd.Text("; if [ $EXITCODE != 0 ]; then if [ -e").Input(text).Text("]; then cat").Input(text).Text("; fi; exit $EXITCODE; fi") + + rule.Command().Text("rm -rf").Flag(lintPaths.cacheDir.String()).Flag(lintPaths.homeDir.String()) + + // The HTML output contains a date, remove it to make the output deterministic. + rule.Command().Text(`sed -i.tmp -e 's|Check performed at .*\(</nav>\)|\1|'`).Output(html) + rule.Build("lint", "lint") l.outputs = lintOutputs{ diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go index 24f8253ae..f0de7a4d8 100644 --- a/java/platform_bootclasspath.go +++ b/java/platform_bootclasspath.go @@ -436,10 +436,10 @@ func (b *platformBootclasspathModule) generateBootImageBuildActions(ctx android. profile := bootImageProfileRule(ctx, imageConfig) // Build boot image files for the android variants. - androidBootImageFilesByArch := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile) + androidBootImageFiles := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile) // Zip the android variant boot image files up. - buildBootImageZipInPredefinedLocation(ctx, imageConfig, androidBootImageFilesByArch) + buildBootImageZipInPredefinedLocation(ctx, imageConfig, androidBootImageFiles.byArch) // Build boot image files for the host variants. There are use directly by ART host side tests. buildBootImageVariantsForBuildOs(ctx, imageConfig, profile) diff --git a/java/robolectric.go b/java/robolectric.go index 7f2981fa8..b6116ec9d 100644 --- a/java/robolectric.go +++ b/java/robolectric.go @@ -188,9 +188,9 @@ func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext) // TODO: this could all be removed if tradefed was used as the test runner, it will find everything // annotated as a test and run it. - for _, src := range r.compiledJavaSrcs { + for _, src := range r.uniqueSrcFiles { s := src.Rel() - if !strings.HasSuffix(s, "Test.java") { + if !strings.HasSuffix(s, "Test.java") && !strings.HasSuffix(s, "Test.kt") { continue } else if strings.HasSuffix(s, "/BaseRobolectricTest.java") { continue diff --git a/java/rro.go b/java/rro.go index cd8c635ff..9d0667cf0 100644 --- a/java/rro.go +++ b/java/rro.go @@ -142,6 +142,10 @@ func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleC aaptLinkFlags = append(aaptLinkFlags, "--rename-overlay-target-package "+*r.overridableProperties.Target_package_name) } + if r.overridableProperties.Category != nil { + aaptLinkFlags = append(aaptLinkFlags, + "--rename-overlay-category "+*r.overridableProperties.Category) + } r.aapt.buildActions(ctx, r, nil, nil, false, aaptLinkFlags...) // Sign the built package @@ -220,6 +224,9 @@ type OverridableRuntimeResourceOverlayProperties struct { // the target package name of this overlay app. The target package name in the manifest file is used if one was not given. Target_package_name *string + + // the rro category of this overlay. The category in the manifest file is used if one was not given. + Category *string } type OverrideRuntimeResourceOverlay struct { diff --git a/java/rro_test.go b/java/rro_test.go index 00ba5ba11..8067a4703 100644 --- a/java/rro_test.go +++ b/java/rro_test.go @@ -201,6 +201,7 @@ func TestOverrideRuntimeResourceOverlay(t *testing.T) { base: "foo_overlay", package_name: "com.android.bar.overlay", target_package_name: "com.android.bar", + category: "mycategory", } `) @@ -212,6 +213,7 @@ func TestOverrideRuntimeResourceOverlay(t *testing.T) { targetVariant string packageFlag string targetPackageFlag string + categoryFlag string }{ { variantName: "android_common", @@ -228,6 +230,7 @@ func TestOverrideRuntimeResourceOverlay(t *testing.T) { targetVariant: "android_common_bar", packageFlag: "com.android.bar.overlay", targetPackageFlag: "com.android.bar", + categoryFlag: "mycategory", }, } for _, expected := range expectedVariants { @@ -249,6 +252,7 @@ func TestOverrideRuntimeResourceOverlay(t *testing.T) { checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag) checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", "") checkAapt2LinkFlag(t, aapt2Flags, "rename-overlay-target-package", expected.targetPackageFlag) + checkAapt2LinkFlag(t, aapt2Flags, "rename-overlay-category", expected.categoryFlag) } } diff --git a/java/sdk_library.go b/java/sdk_library.go index 59ffff5c9..fad1df77c 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -65,8 +65,27 @@ type apiScope struct { name string // The api scope that this scope extends. + // + // This organizes the scopes into an extension hierarchy. + // + // If set this means that the API provided by this scope includes the API provided by the scope + // set in this field. extends *apiScope + // The next api scope that a library that uses this scope can access. + // + // This organizes the scopes into an access hierarchy. + // + // If set this means that a library that can access this API can also access the API provided by + // the scope set in this field. + // + // A module that sets sdk_version: "<scope>_current" should have access to the <scope> API of + // every java_sdk_library that it depends on. If the library does not provide an API for <scope> + // then it will traverse up this access hierarchy to find an API that it does provide. + // + // If this is not set then it defaults to the scope set in extends. + canAccess *apiScope + // The legacy enabled status for a specific scope can be dependent on other // properties that have been specified on the library so it is provided by // a function that can determine the status by examining those properties. @@ -107,7 +126,7 @@ type apiScope struct { // The scope specific prefix to add to the api file base of "current.txt" or "removed.txt". apiFilePrefix string - // The scope specific prefix to add to the sdk library module name to construct a scope specific + // The scope specific suffix to add to the sdk library module name to construct a scope specific // module name. moduleSuffix string @@ -193,6 +212,11 @@ func initApiScope(scope *apiScope) *apiScope { } } + // By default, a library that can access a scope can also access the scope it extends. + if scope.canAccess == nil { + scope.canAccess = scope.extends + } + // Escape any special characters in the arguments. This is needed because droidstubs // passes these directly to the shell command. scope.droidstubsArgs = proptools.ShellEscapeList(scopeSpecificArgs) @@ -310,6 +334,14 @@ var ( apiScopeSystemServer = initApiScope(&apiScope{ name: "system-server", extends: apiScopePublic, + + // The system-server scope can access the module-lib scope. + // + // A module that provides a system-server API is appended to the standard bootclasspath that is + // used by the system server. So, it should be able to access module-lib APIs provided by + // libraries on the bootclasspath. + canAccess: apiScopeModuleLib, + // The system-server scope is disabled by default in legacy mode. // // Enabling this would break existing usages. @@ -926,7 +958,7 @@ func (c *commonToSdkLibraryAndImport) findScopePaths(scope *apiScope) *scopePath // If this does not support the requested api scope then find the closest available // scope it does support. Returns nil if no such scope is available. func (c *commonToSdkLibraryAndImport) findClosestScopePath(scope *apiScope) *scopePaths { - for s := scope; s != nil; s = s.extends { + for s := scope; s != nil; s = s.canAccess { if paths := c.findScopePaths(s); paths != nil { return paths } diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go index ea7b2f74f..096bca8a1 100644 --- a/java/sdk_library_test.go +++ b/java/sdk_library_test.go @@ -18,6 +18,7 @@ import ( "fmt" "path/filepath" "regexp" + "strings" "testing" "android/soong/android" @@ -699,6 +700,80 @@ func TestJavaSdkLibrary_SystemServer(t *testing.T) { `) } +func TestJavaSdkLibrary_SystemServer_AccessToStubScopeLibs(t *testing.T) { + result := android.GroupFixturePreparers( + prepareForJavaTest, + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("foo-public", "foo-system", "foo-module-lib", "foo-system-server"), + ).RunTestWithBp(t, ` + java_sdk_library { + name: "foo-public", + srcs: ["a.java"], + api_packages: ["foo"], + public: { + enabled: true, + }, + } + + java_sdk_library { + name: "foo-system", + srcs: ["a.java"], + api_packages: ["foo"], + system: { + enabled: true, + }, + } + + java_sdk_library { + name: "foo-module-lib", + srcs: ["a.java"], + api_packages: ["foo"], + system: { + enabled: true, + }, + module_lib: { + enabled: true, + }, + } + + java_sdk_library { + name: "foo-system-server", + srcs: ["a.java"], + api_packages: ["foo"], + system_server: { + enabled: true, + }, + } + + java_library { + name: "bar", + srcs: ["a.java"], + libs: ["foo-public", "foo-system", "foo-module-lib", "foo-system-server"], + sdk_version: "system_server_current", + } + `) + + stubsPath := func(name string, scope *apiScope) string { + name = scope.stubsLibraryModuleName(name) + return fmt.Sprintf("out/soong/.intermediates/%[1]s/android_common/turbine-combined/%[1]s.jar", name) + } + + // The bar library should depend on the highest (where system server is highest and public is + // lowest) API scopes provided by each of the foo-* modules. The highest API scope provided by the + // foo-<x> module is <x>. + barLibrary := result.ModuleForTests("bar", "android_common").Rule("javac") + stubLibraries := []string{ + stubsPath("foo-public", apiScopePublic), + stubsPath("foo-system", apiScopeSystem), + stubsPath("foo-module-lib", apiScopeModuleLib), + stubsPath("foo-system-server", apiScopeSystemServer), + } + expectedPattern := fmt.Sprintf(`^-classpath .*:\Q%s\E$`, strings.Join(stubLibraries, ":")) + if expected, actual := expectedPattern, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { + t.Errorf("expected pattern %q to match %#q", expected, actual) + } +} + func TestJavaSdkLibrary_MissingScope(t *testing.T) { prepareForJavaTest. ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`requires api scope module-lib from foo but it only has \[\] available`)). diff --git a/java/testing.go b/java/testing.go index 1f411913b..49430ee05 100644 --- a/java/testing.go +++ b/java/testing.go @@ -393,6 +393,7 @@ func gatherRequiredDepsForTest() string { aidl: { export_include_dirs: ["framework/aidl"], }, + compile_dex: true, } android_app { |