summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/Android.bp2
-rw-r--r--java/androidmk.go14
-rw-r--r--java/androidmk_test.go149
-rwxr-xr-xjava/app.go27
-rw-r--r--java/app_set.go9
-rw-r--r--java/base.go56
-rw-r--r--java/bootclasspath_fragment.go56
-rw-r--r--java/config/config.go7
-rw-r--r--java/dexpreopt_bootjars.go80
-rw-r--r--java/dexpreopt_config_test.go35
-rw-r--r--java/dexpreopt_config_testing.go768
-rw-r--r--java/java.go1
-rw-r--r--java/java_test.go4
-rw-r--r--java/lint.go19
-rw-r--r--java/platform_bootclasspath.go4
-rw-r--r--java/robolectric.go4
-rw-r--r--java/rro.go7
-rw-r--r--java/rro_test.go4
-rw-r--r--java/sdk_library.go36
-rw-r--r--java/sdk_library_test.go75
-rw-r--r--java/testing.go1
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 {