Merge tag 'android-16.0.0_r1' of https://android.googlesource.com/platform/build/soong into HEAD
Android 16.0.0 release 1
Change-Id: Ide1ec574e3f9743d18ee70b928056bb7fe248f80
diff --git a/java/Android.bp b/java/Android.bp
index 885e682..99d9c38 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -51,6 +51,7 @@
"gen.go",
"generated_java_library.go",
"genrule.go",
+ "genrule_combiner.go",
"hiddenapi.go",
"hiddenapi_modular.go",
"hiddenapi_monolithic.go",
@@ -77,6 +78,7 @@
"system_modules.go",
"systemserver_classpath_fragment.go",
"testing.go",
+ "tracereferences.go",
"tradefed.go",
],
testSrcs: [
@@ -95,6 +97,7 @@
"droiddoc_test.go",
"droidstubs_test.go",
"fuzz_test.go",
+ "genrule_combiner_test.go",
"genrule_test.go",
"generated_java_library_test.go",
"hiddenapi_singleton_test.go",
diff --git a/java/aar.go b/java/aar.go
index 7322b09..86c6bfa 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -217,13 +217,9 @@
}
func (a *aapt) useResourceProcessorBusyBox(ctx android.BaseModuleContext) bool {
- return BoolDefault(a.aaptProperties.Use_resource_processor, ctx.Config().UseResourceProcessorByDefault()) &&
+ return BoolDefault(a.aaptProperties.Use_resource_processor, true) &&
// TODO(b/331641946): remove this when ResourceProcessorBusyBox supports generating shared libraries.
- !slices.Contains(a.aaptProperties.Aaptflags, "--shared-lib") &&
- // Use the legacy resource processor in kythe builds.
- // The legacy resource processor creates an R.srcjar, which kythe can use for generating crossrefs.
- // TODO(b/354854007): Re-enable BusyBox in kythe builds
- !ctx.Config().EmitXrefRules()
+ !slices.Contains(a.aaptProperties.Aaptflags, "--shared-lib")
}
func (a *aapt) filterProduct() string {
@@ -391,8 +387,9 @@
versionName = proptools.NinjaEscape(versionName)
linkFlags = append(linkFlags, "--version-name ", versionName)
}
-
- linkFlags, compileFlags = android.FilterList(linkFlags, []string{"--legacy"})
+ // Split the flags by prefix, as --png-compression-level has the "=value" suffix.
+ linkFlags, compileFlags = android.FilterListByPrefix(linkFlags,
+ []string{"--legacy", "--png-compression-level"})
// Always set --pseudo-localize, it will be stripped out later for release
// builds that don't want it.
@@ -878,13 +875,15 @@
rroDirsDepSetBuilder := depset.NewBuilder[rroDir](depset.TOPOLOGICAL)
manifestsDepSetBuilder := depset.NewBuilder[android.Path](depset.TOPOLOGICAL)
- ctx.VisitDirectDeps(func(module android.Module) {
+ ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
depTag := ctx.OtherModuleDependencyTag(module)
var exportPackage android.Path
- aarDep, _ := module.(AndroidLibraryDependency)
- if aarDep != nil {
- exportPackage = aarDep.ExportPackage()
+ var aarDep *AndroidLibraryDependencyInfo
+ javaInfo, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider)
+ if ok && javaInfo.AndroidLibraryDependencyInfo != nil {
+ aarDep = javaInfo.AndroidLibraryDependencyInfo
+ exportPackage = aarDep.ExportPackage
}
switch depTag {
@@ -892,7 +891,7 @@
// Nothing, instrumentationForTag is treated as libTag for javac but not for aapt2.
case sdkLibTag, libTag, rroDepTag:
if exportPackage != nil {
- sharedResourcesNodeDepSets = append(sharedResourcesNodeDepSets, aarDep.ResourcesNodeDepSet())
+ sharedResourcesNodeDepSets = append(sharedResourcesNodeDepSets, aarDep.ResourcesNodeDepSet)
sharedLibs = append(sharedLibs, exportPackage)
}
case frameworkResTag, omniromResTag:
@@ -901,9 +900,9 @@
}
case staticLibTag:
if exportPackage != nil {
- staticResourcesNodeDepSets = append(staticResourcesNodeDepSets, aarDep.ResourcesNodeDepSet())
- rroDirsDepSetBuilder.Transitive(aarDep.RRODirsDepSet())
- manifestsDepSetBuilder.Transitive(aarDep.ManifestsDepSet())
+ staticResourcesNodeDepSets = append(staticResourcesNodeDepSets, aarDep.ResourcesNodeDepSet)
+ rroDirsDepSetBuilder.Transitive(aarDep.RRODirsDepSet)
+ manifestsDepSetBuilder.Transitive(aarDep.ManifestsDepSet)
}
}
@@ -939,6 +938,18 @@
return staticResourcesNodes, sharedResourcesNodes, staticRRODirs, staticManifests, sharedLibs, flags
}
+type AndroidLibraryInfo struct {
+ // Empty for now
+}
+
+var AndroidLibraryInfoProvider = blueprint.NewProvider[AndroidLibraryInfo]()
+
+type AARImportInfo struct {
+ // Empty for now
+}
+
+var AARImportInfoProvider = blueprint.NewProvider[AARImportInfo]()
+
type AndroidLibrary struct {
Library
aapt
@@ -1025,7 +1036,7 @@
extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
}
- a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
+ javaInfo := a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
a.aarFile = android.PathForModuleOut(ctx, ctx.ModuleName()+".aar")
var res android.Paths
@@ -1034,7 +1045,7 @@
}
prebuiltJniPackages := android.Paths{}
- ctx.VisitDirectDeps(func(module android.Module) {
+ ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
if info, ok := android.OtherModuleProvider(ctx, module, JniPackageProvider); ok {
prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...)
}
@@ -1049,7 +1060,16 @@
AconfigTextFiles: aconfigTextFilePaths,
})
+ android.SetProvider(ctx, AndroidLibraryInfoProvider, AndroidLibraryInfo{})
+
+ if javaInfo != nil {
+ setExtraJavaInfo(ctx, a, javaInfo)
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+ }
+
a.setOutputFiles(ctx)
+
+ buildComplianceMetadata(ctx)
}
func (a *AndroidLibrary) setOutputFiles(ctx android.ModuleContext) {
@@ -1445,7 +1465,7 @@
var transitiveStaticLibsImplementationJars []depset.DepSet[android.Path]
var transitiveStaticLibsResourceJars []depset.DepSet[android.Path]
- ctx.VisitDirectDeps(func(module android.Module) {
+ ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
tag := ctx.OtherModuleDependencyTag(module)
switch tag {
@@ -1467,12 +1487,7 @@
completeStaticLibsResourceJars := depset.New(depset.PREORDER, nil, transitiveStaticLibsResourceJars)
var implementationJarFile android.Path
- var combineJars android.Paths
- if ctx.Config().UseTransitiveJarsInClasspath() {
- combineJars = completeStaticLibsImplementationJars.ToList()
- } else {
- combineJars = append(android.Paths{classpathFile}, staticJars...)
- }
+ combineJars := completeStaticLibsImplementationJars.ToList()
if len(combineJars) > 1 {
implementationJarOutputPath := android.PathForModuleOut(ctx, "combined", jarName)
@@ -1483,12 +1498,8 @@
}
var resourceJarFile android.Path
- var resourceJars android.Paths
- if ctx.Config().UseTransitiveJarsInClasspath() {
- resourceJars = completeStaticLibsResourceJars.ToList()
- } else {
- resourceJars = staticResourceJars
- }
+ resourceJars := completeStaticLibsResourceJars.ToList()
+
if len(resourceJars) > 1 {
combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName)
TransformJarsToJar(ctx, combinedJar, "for resources", resourceJars, android.OptionalPath{},
@@ -1499,12 +1510,8 @@
}
// merge implementation jar with resources if necessary
- var implementationAndResourcesJars android.Paths
- if ctx.Config().UseTransitiveJarsInClasspath() {
- implementationAndResourcesJars = append(slices.Clone(resourceJars), combineJars...)
- } else {
- implementationAndResourcesJars = android.PathsIfNonNil(resourceJarFile, implementationJarFile)
- }
+ implementationAndResourcesJars := append(slices.Clone(resourceJars), combineJars...)
+
var implementationAndResourcesJar android.Path
if len(implementationAndResourcesJars) > 1 {
combinedJar := android.PathForModuleOut(ctx, "withres", jarName)
@@ -1519,12 +1526,7 @@
// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
a.implementationAndResourcesJarFile = implementationAndResourcesJar.WithoutRel()
- var headerJars android.Paths
- if ctx.Config().UseTransitiveJarsInClasspath() {
- headerJars = completeStaticLibsHeaderJars.ToList()
- } else {
- headerJars = append(android.Paths{classpathFile}, staticHeaderJars...)
- }
+ headerJars := completeStaticLibsHeaderJars.ToList()
if len(headerJars) > 1 {
headerJarFile := android.PathForModuleOut(ctx, "turbine-combined", jarName)
TransformJarsToJar(ctx, headerJarFile, "combine header jars", headerJars, android.OptionalPath{}, false, nil, nil)
@@ -1533,14 +1535,9 @@
a.headerJarFile = headerJars[0]
}
- if ctx.Config().UseTransitiveJarsInClasspath() {
- ctx.CheckbuildFile(classpathFile)
- } else {
- ctx.CheckbuildFile(a.headerJarFile)
- ctx.CheckbuildFile(a.implementationJarFile)
- }
+ ctx.CheckbuildFile(classpathFile)
- android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
+ javaInfo := &JavaInfo{
HeaderJars: android.PathsIfNonNil(a.headerJarFile),
LocalHeaderJars: android.PathsIfNonNil(classpathFile),
TransitiveStaticLibsHeaderJars: completeStaticLibsHeaderJars,
@@ -1553,7 +1550,9 @@
ImplementationJars: android.PathsIfNonNil(a.implementationJarFile),
StubsLinkType: Implementation,
// TransitiveAconfigFiles: // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
- })
+ }
+ setExtraJavaInfo(ctx, a, javaInfo)
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
if proptools.Bool(a.properties.Extract_jni) {
for _, t := range ctx.MultiTargets() {
@@ -1580,8 +1579,12 @@
JniPackages: a.jniPackages,
})
+ android.SetProvider(ctx, AARImportInfoProvider, AARImportInfo{})
+
ctx.SetOutputFiles([]android.Path{a.implementationAndResourcesJarFile}, "")
ctx.SetOutputFiles([]android.Path{a.aarPath}, ".aar")
+
+ buildComplianceMetadata(ctx)
}
func (a *AARImport) HeaderJars() android.Paths {
@@ -1609,14 +1612,21 @@
var _ android.ApexModule = (*AARImport)(nil)
// Implements android.ApexModule
-func (a *AARImport) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
- return a.depIsInSameApex(ctx, dep)
+func (m *AARImport) GetDepInSameApexChecker() android.DepInSameApexChecker {
+ return AARImportDepInSameApexChecker{}
+}
+
+type AARImportDepInSameApexChecker struct {
+ android.BaseDepInSameApexChecker
+}
+
+func (m AARImportDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
+ return depIsInSameApex(tag)
}
// Implements android.ApexModule
-func (a *AARImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
- sdkVersion android.ApiLevel) error {
- return nil
+func (a *AARImport) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
+ return android.MinApiLevel
}
var _ android.PrebuiltInterface = (*AARImport)(nil)
@@ -1646,5 +1656,5 @@
}
func (a *AARImport) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
- dpInfo.Jars = append(dpInfo.Jars, a.headerJarFile.String(), a.rJar.String())
+ dpInfo.Jars = append(dpInfo.Jars, a.implementationJarFile.String(), a.rJar.String())
}
diff --git a/java/aar_test.go b/java/aar_test.go
index aa4f0af..088ad6c 100644
--- a/java/aar_test.go
+++ b/java/aar_test.go
@@ -21,6 +21,7 @@
)
func TestAarImportProducesJniPackages(t *testing.T) {
+ t.Parallel()
ctx := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, `
@@ -50,8 +51,9 @@
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
+ t.Parallel()
appMod := ctx.Module(tc.name, "android_common")
- appTestMod := ctx.ModuleForTests(tc.name, "android_common")
+ appTestMod := ctx.ModuleForTests(t, tc.name, "android_common")
info, ok := android.OtherModuleProvider(ctx, appMod, JniPackageProvider)
if !ok {
@@ -84,6 +86,7 @@
}
func TestLibraryFlagsPackages(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
).RunTestWithBp(t, `
@@ -114,7 +117,7 @@
}
`)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
// android_library module depends on aconfig_declarations listed in flags_packages
android.AssertBoolEquals(t, "foo expected to depend on bar", true,
@@ -133,6 +136,7 @@
}
func TestAndroidLibraryOutputFilesRel(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, `
@@ -155,9 +159,9 @@
}
`)
- foo := result.ModuleForTests("foo", "android_common")
- bar := result.ModuleForTests("bar", "android_common")
- baz := result.ModuleForTests("baz", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
+ bar := result.ModuleForTests(t, "bar", "android_common")
+ baz := result.ModuleForTests(t, "baz", "android_common")
fooOutputPaths := foo.OutputFiles(result.TestContext, t, "")
barOutputPaths := bar.OutputFiles(result.TestContext, t, "")
diff --git a/java/android_manifest_test.go b/java/android_manifest_test.go
index 7c91884..ce227b9 100644
--- a/java/android_manifest_test.go
+++ b/java/android_manifest_test.go
@@ -21,6 +21,7 @@
)
func TestManifestMerger(t *testing.T) {
+ t.Parallel()
bp := `
android_app {
name: "app",
@@ -80,7 +81,7 @@
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, bp)
- manifestMergerRule := result.ModuleForTests("app", "android_common").Rule("manifestMerger")
+ manifestMergerRule := result.ModuleForTests(t, "app", "android_common").Rule("manifestMerger")
android.AssertPathRelativeToTopEquals(t, "main manifest",
"out/soong/.intermediates/app/android_common/manifest_fixer/AndroidManifest.xml",
manifestMergerRule.Input)
@@ -100,6 +101,7 @@
}
func TestManifestValuesApplicationIdSetsPackageName(t *testing.T) {
+ t.Parallel()
bp := `
android_test {
name: "test",
@@ -127,7 +129,7 @@
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, bp)
- manifestMergerRule := result.ModuleForTests("test", "android_common").Rule("manifestMerger")
+ manifestMergerRule := result.ModuleForTests(t, "test", "android_common").Rule("manifestMerger")
android.AssertStringMatches(t,
"manifest merger args",
manifestMergerRule.Args["args"],
diff --git a/java/androidmk.go b/java/androidmk.go
index eb33589..e9b1f64 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -23,13 +23,12 @@
"github.com/google/blueprint/proptools"
)
-func (library *Library) AndroidMkEntriesHostDex() android.AndroidMkEntries {
- hostDexNeeded := Bool(library.deviceProperties.Hostdex) && !library.Host()
- if library.hideApexVariantFromMake {
- hostDexNeeded = false
- }
+func (library *Library) hostDexNeeded() bool {
+ return Bool(library.deviceProperties.Hostdex) && !library.Host() && !library.hideApexVariantFromMake
+}
- if hostDexNeeded {
+func (library *Library) AndroidMkEntriesHostDex() android.AndroidMkEntries {
+ if library.hostDexNeeded() {
var output android.Path
if library.dexJarFile.IsSet() {
output = library.dexJarFile.Path()
@@ -71,11 +70,7 @@
if library.hideApexVariantFromMake {
// For a java library built for an APEX, we don't need a Make module for itself. Otherwise, it
// will conflict with the platform variant because they have the same module name in the
- // makefile. However, we need to add its dexpreopt outputs as sub-modules, if it is preopted.
- dexpreoptEntries := library.dexpreopter.AndroidMkEntriesForApex()
- if len(dexpreoptEntries) > 0 {
- entriesList = append(entriesList, dexpreoptEntries...)
- }
+ // makefile.
entriesList = append(entriesList, android.AndroidMkEntries{Disabled: true})
} else if !library.ApexModuleBase.AvailableFor(android.AvailableToPlatform) {
// Platform variant. If not available for the platform, we don't need Make module.
@@ -125,6 +120,14 @@
}
},
},
+ ExtraFooters: []android.AndroidMkExtraFootersFunc{
+ func(w io.Writer, name, prefix, moduleDir string) {
+ if library.apiXmlFile != nil {
+ fmt.Fprintf(w, "$(call declare-1p-target,%s,)\n", library.apiXmlFile.String())
+ fmt.Fprintf(w, "$(eval $(call copy-one-file,%s,$(TARGET_OUT_COMMON_INTERMEDIATES)/%s))\n", library.apiXmlFile.String(), library.apiXmlFile.Base())
+ }
+ },
+ },
})
}
@@ -555,73 +558,11 @@
},
ExtraFooters: []android.AndroidMkExtraFootersFunc{
func(w io.Writer, name, prefix, moduleDir string) {
- if dstubs.apiFile != nil {
- fmt.Fprintf(w, ".PHONY: %s %s.txt\n", dstubs.Name(), dstubs.Name())
- fmt.Fprintf(w, "%s %s.txt: %s\n", dstubs.Name(), dstubs.Name(), dstubs.apiFile)
- }
- if dstubs.removedApiFile != nil {
- fmt.Fprintf(w, ".PHONY: %s %s.txt\n", dstubs.Name(), dstubs.Name())
- fmt.Fprintf(w, "%s %s.txt: %s\n", dstubs.Name(), dstubs.Name(), dstubs.removedApiFile)
- }
- if dstubs.checkCurrentApiTimestamp != nil {
- fmt.Fprintln(w, ".PHONY:", dstubs.Name()+"-check-current-api")
- fmt.Fprintln(w, dstubs.Name()+"-check-current-api:",
- dstubs.checkCurrentApiTimestamp.String())
-
- fmt.Fprintln(w, ".PHONY: checkapi")
- fmt.Fprintln(w, "checkapi:",
- dstubs.checkCurrentApiTimestamp.String())
-
- fmt.Fprintln(w, ".PHONY: droidcore")
- fmt.Fprintln(w, "droidcore: checkapi")
- }
- if dstubs.updateCurrentApiTimestamp != nil {
- fmt.Fprintln(w, ".PHONY:", dstubs.Name()+"-update-current-api")
- fmt.Fprintln(w, dstubs.Name()+"-update-current-api:",
- dstubs.updateCurrentApiTimestamp.String())
-
- fmt.Fprintln(w, ".PHONY: update-api")
- fmt.Fprintln(w, "update-api:",
- dstubs.updateCurrentApiTimestamp.String())
- }
- if dstubs.checkLastReleasedApiTimestamp != nil {
- fmt.Fprintln(w, ".PHONY:", dstubs.Name()+"-check-last-released-api")
- fmt.Fprintln(w, dstubs.Name()+"-check-last-released-api:",
- dstubs.checkLastReleasedApiTimestamp.String())
-
- fmt.Fprintln(w, ".PHONY: checkapi")
- fmt.Fprintln(w, "checkapi:",
- dstubs.checkLastReleasedApiTimestamp.String())
-
- fmt.Fprintln(w, ".PHONY: droidcore")
- fmt.Fprintln(w, "droidcore: checkapi")
- }
if dstubs.apiLintTimestamp != nil {
- fmt.Fprintln(w, ".PHONY:", dstubs.Name()+"-api-lint")
- fmt.Fprintln(w, dstubs.Name()+"-api-lint:",
- dstubs.apiLintTimestamp.String())
-
- fmt.Fprintln(w, ".PHONY: checkapi")
- fmt.Fprintln(w, "checkapi:",
- dstubs.Name()+"-api-lint")
-
- fmt.Fprintln(w, ".PHONY: droidcore")
- fmt.Fprintln(w, "droidcore: checkapi")
-
if dstubs.apiLintReport != nil {
- fmt.Fprintf(w, "$(call dist-for-goals,%s,%s:%s)\n", dstubs.Name()+"-api-lint",
- dstubs.apiLintReport.String(), "apilint/"+dstubs.Name()+"-lint-report.txt")
fmt.Fprintf(w, "$(call declare-0p-target,%s)\n", dstubs.apiLintReport.String())
}
}
- if dstubs.checkNullabilityWarningsTimestamp != nil {
- fmt.Fprintln(w, ".PHONY:", dstubs.Name()+"-check-nullability-warnings")
- fmt.Fprintln(w, dstubs.Name()+"-check-nullability-warnings:",
- dstubs.checkNullabilityWarningsTimestamp.String())
-
- fmt.Fprintln(w, ".PHONY:", "droidcore")
- fmt.Fprintln(w, "droidcore: ", dstubs.Name()+"-check-nullability-warnings")
- }
},
},
}}
diff --git a/java/androidmk_test.go b/java/androidmk_test.go
index 1d98b18..b4b13b1 100644
--- a/java/androidmk_test.go
+++ b/java/androidmk_test.go
@@ -23,6 +23,7 @@
)
func TestRequired(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -31,7 +32,7 @@
}
`)
- mod := ctx.ModuleForTests("foo", "android_common").Module()
+ mod := ctx.ModuleForTests(t, "foo", "android_common").Module()
entries := android.AndroidMkEntriesForTest(t, ctx, mod)[0]
expected := []string{"libfoo"}
@@ -42,6 +43,7 @@
}
func TestHostdex(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -50,7 +52,7 @@
}
`)
- mod := ctx.ModuleForTests("foo", "android_common").Module()
+ mod := ctx.ModuleForTests(t, "foo", "android_common").Module()
entriesList := android.AndroidMkEntriesForTest(t, ctx, mod)
if len(entriesList) != 2 {
t.Errorf("two entries are expected, but got %d", len(entriesList))
@@ -72,6 +74,7 @@
}
func TestHostdexRequired(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -81,7 +84,7 @@
}
`)
- mod := ctx.ModuleForTests("foo", "android_common").Module()
+ mod := ctx.ModuleForTests(t, "foo", "android_common").Module()
entriesList := android.AndroidMkEntriesForTest(t, ctx, mod)
if len(entriesList) != 2 {
t.Errorf("two entries are expected, but got %d", len(entriesList))
@@ -103,6 +106,7 @@
}
func TestHostdexSpecificRequired(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -116,7 +120,7 @@
}
`)
- mod := ctx.ModuleForTests("foo", "android_common").Module()
+ mod := ctx.ModuleForTests(t, "foo", "android_common").Module()
entriesList := android.AndroidMkEntriesForTest(t, ctx, mod)
if len(entriesList) != 2 {
t.Errorf("two entries are expected, but got %d", len(entriesList))
@@ -136,6 +140,7 @@
}
func TestJavaSdkLibrary_RequireXmlPermissionFile(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -153,7 +158,7 @@
`)
// Verify the existence of internal modules
- result.ModuleForTests("foo-shared_library.xml", "android_common")
+ result.ModuleForTests(t, "foo-shared_library.xml", "android_common")
testCases := []struct {
moduleName string
@@ -163,7 +168,7 @@
{"foo-no_shared_library", []string{"foo-no_shared_library.impl"}},
}
for _, tc := range testCases {
- mod := result.ModuleForTests(tc.moduleName, "android_common").Module()
+ mod := result.ModuleForTests(t, tc.moduleName, "android_common").Module()
entries := android.AndroidMkEntriesForTest(t, result.TestContext, mod)[0]
actual := entries.EntryMap["LOCAL_REQUIRED_MODULES"]
if !reflect.DeepEqual(tc.expected, actual) {
@@ -173,6 +178,7 @@
}
func TestImportSoongDexJar(t *testing.T) {
+ t.Parallel()
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
java_import {
name: "my-java-import",
@@ -191,6 +197,7 @@
}
func TestAndroidTestHelperApp_LocalDisableTestConfig(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_test_helper_app {
name: "foo",
@@ -198,7 +205,7 @@
}
`)
- mod := ctx.ModuleForTests("foo", "android_common").Module()
+ mod := ctx.ModuleForTests(t, "foo", "android_common").Module()
entries := android.AndroidMkEntriesForTest(t, ctx, mod)[0]
expected := []string{"true"}
@@ -209,6 +216,7 @@
}
func TestGetOverriddenPackages(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(
t, `
android_app {
@@ -246,7 +254,7 @@
}
for _, expected := range expectedVariants {
- mod := ctx.ModuleForTests(expected.name, expected.variantName).Module()
+ mod := ctx.ModuleForTests(t, expected.name, expected.variantName).Module()
entries := android.AndroidMkEntriesForTest(t, ctx, mod)[0]
actual := entries.EntryMap["LOCAL_OVERRIDES_PACKAGES"]
@@ -255,6 +263,7 @@
}
func TestJniAsRequiredDeps(t *testing.T) {
+ t.Parallel()
ctx := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
cc.PrepareForTestWithCcDefaultModules,
@@ -295,7 +304,7 @@
}
for _, tc := range testcases {
- mod := ctx.ModuleForTests(tc.name, "android_common").Module()
+ mod := ctx.ModuleForTests(t, tc.name, "android_common").Module()
entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, mod)[0]
required := entries.EntryMap["LOCAL_REQUIRED_MODULES"]
android.AssertDeepEquals(t, "unexpected required deps", tc.expected, required)
diff --git a/java/app.go b/java/app.go
index 64ecc55..a3414f6 100644
--- a/java/app.go
+++ b/java/app.go
@@ -70,6 +70,19 @@
// EmbeddedJNILibs is the list of paths to JNI libraries that were embedded in the APK.
EmbeddedJNILibs android.Paths
+
+ MergedManifestFile android.Path
+
+ Prebuilt bool
+ AppSet bool
+ Privileged bool
+ OutputFile android.Path
+ InstallApkName string
+ JacocoReportClassesFile android.Path
+ Certificate Certificate
+ PrivAppAllowlist android.OptionalPath
+ OverriddenManifestPackageName *string
+ ApkCertsFile android.Path
}
var AppInfoProvider = blueprint.NewProvider[*AppInfo]()
@@ -399,9 +412,23 @@
android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
TestOnly: true,
})
- android.SetProvider(ctx, AppInfoProvider, &AppInfo{
+ appInfo := &AppInfo{
Updatable: Bool(a.appProperties.Updatable),
TestHelperApp: true,
+ }
+ setCommonAppInfo(appInfo, a)
+ android.SetProvider(ctx, AppInfoProvider, appInfo)
+
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests")
+ if len(a.appTestHelperAppProperties.Test_suites) > 0 {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, a.appTestHelperAppProperties.Test_suites...)
+ } else {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
+ }
+
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: a.appTestHelperAppProperties.Test_suites,
})
}
@@ -418,13 +445,28 @@
embeddedJniLibs = append(embeddedJniLibs, jni.path)
}
}
- android.SetProvider(ctx, AppInfoProvider, &AppInfo{
- Updatable: Bool(a.appProperties.Updatable),
- TestHelperApp: false,
- EmbeddedJNILibs: embeddedJniLibs,
- })
+ overriddenName := a.OverriddenManifestPackageName()
+ appInfo := &AppInfo{
+ Updatable: Bool(a.appProperties.Updatable),
+ TestHelperApp: false,
+ EmbeddedJNILibs: embeddedJniLibs,
+ MergedManifestFile: a.mergedManifest,
+ OverriddenManifestPackageName: &overriddenName,
+ }
+ setCommonAppInfo(appInfo, a)
+ android.SetProvider(ctx, AppInfoProvider, appInfo)
a.requiredModuleNames = a.getRequiredModuleNames(ctx)
+
+ if a.dexer.proguardDictionary.Valid() {
+ android.SetProvider(ctx, ProguardProvider, ProguardInfo{
+ ModuleName: ctx.ModuleName(),
+ Class: "APPS",
+ ProguardDictionary: a.dexer.proguardDictionary.Path(),
+ ProguardUsageZip: a.dexer.proguardUsageZip.Path(),
+ ClassesJar: a.implementationAndResourcesJar,
+ })
+ }
}
func (a *AndroidApp) getRequiredModuleNames(ctx android.ModuleContext) []string {
@@ -487,18 +529,28 @@
// This check is enforced for "updatable" APKs (including APK-in-APEX).
func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
// It's enough to check direct JNI deps' sdk_version because all transitive deps from JNI deps are checked in cc.checkLinkType()
- ctx.VisitDirectDeps(func(m android.Module) {
+ ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
if !IsJniDepTag(ctx.OtherModuleDependencyTag(m)) {
return
}
- dep, _ := m.(*cc.Module)
+ if _, ok := android.OtherModuleProvider(ctx, m, cc.CcInfoProvider); !ok {
+ panic(fmt.Errorf("jni dependency is not a cc module: %v", m))
+ }
+ commonInfo, ok := android.OtherModuleProvider(ctx, m, android.CommonModuleInfoProvider)
+ if !ok {
+ panic(fmt.Errorf("jni dependency doesn't have CommonModuleInfo provider: %v", m))
+ }
// The domain of cc.sdk_version is "current" and <number>
// We can rely on android.SdkSpec to convert it to <number> so that "current" is
// handled properly regardless of sdk finalization.
- jniSdkVersion, err := android.SdkSpecFrom(ctx, dep.MinSdkVersion()).EffectiveVersion(ctx)
+ ver := ""
+ if !commonInfo.MinSdkVersion.IsPlatform {
+ ver = commonInfo.MinSdkVersion.ApiLevel.String()
+ }
+ jniSdkVersion, err := android.SdkSpecFrom(ctx, ver).EffectiveVersion(ctx)
if err != nil || minSdkVersion.LessThan(jniSdkVersion) {
- ctx.OtherModuleErrorf(dep, "min_sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)",
- dep.MinSdkVersion(), minSdkVersion, ctx.ModuleName())
+ ctx.OtherModuleErrorf(m, "min_sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)",
+ ver, minSdkVersion, ctx.ModuleName())
return
}
@@ -561,10 +613,10 @@
}
func getAconfigFilePaths(ctx android.ModuleContext) (aconfigTextFilePaths android.Paths) {
- ctx.VisitDirectDeps(func(dep android.Module) {
+ ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) {
tag := ctx.OtherModuleDependencyTag(dep)
switch tag {
- case staticLibTag:
+ case staticLibTag, rroDepTag:
if flagPackages, ok := android.OtherModuleProvider(ctx, dep, FlagsPackagesProvider); ok {
aconfigTextFilePaths = append(aconfigTextFilePaths, flagPackages.AconfigTextFiles...)
}
@@ -640,7 +692,7 @@
}
// Use non final ids if we are doing optimized shrinking and are using R8.
- nonFinalIds := a.dexProperties.optimizedResourceShrinkingEnabled(ctx) && a.dexer.effectiveOptimizeEnabled()
+ nonFinalIds := a.dexProperties.optimizedResourceShrinkingEnabled(ctx) && a.dexer.effectiveOptimizeEnabled(ctx)
aconfigTextFilePaths := getAconfigFilePaths(ctx)
@@ -667,7 +719,7 @@
func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) {
var staticLibProguardFlagFiles android.Paths
- ctx.VisitDirectDeps(func(m android.Module) {
+ ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider)
staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.UnconditionallyExportedProguardFlags.ToList()...)
if ctx.OtherModuleDependencyTag(m) == staticLibTag {
@@ -704,7 +756,7 @@
return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
}
-func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path) {
+func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path, *JavaInfo) {
a.dexpreopter.installPath = a.installPath(ctx)
a.dexpreopter.isApp = true
if a.dexProperties.Uncompress_dex == nil {
@@ -719,6 +771,7 @@
var packageResources = a.exportPackage
+ javaInfo := &JavaInfo{}
if ctx.ModuleName() != "framework-res" && ctx.ModuleName() != "omnirom-res" {
if a.dexProperties.resourceShrinkingEnabled(ctx) {
protoFile := android.PathForModuleOut(ctx, packageResources.Base()+".proto.apk")
@@ -742,7 +795,7 @@
extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
}
- a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
+ javaInfo = a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
if a.dexProperties.resourceShrinkingEnabled(ctx) {
binaryResources := android.PathForModuleOut(ctx, packageResources.Base()+".binary.out.apk")
aapt2Convert(ctx, binaryResources, a.dexer.resourcesOutput.Path(), "binary")
@@ -750,7 +803,7 @@
}
}
- return a.dexJarFile.PathOrNil(), packageResources
+ return a.dexJarFile.PathOrNil(), packageResources, javaInfo
}
func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath {
@@ -960,7 +1013,7 @@
a.linter.resources = a.aapt.resourceFiles
a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
- dexJarFile, packageResources := a.dexBuildActions(ctx)
+ dexJarFile, packageResources, javaInfo := a.dexBuildActions(ctx)
// No need to check the SDK version of the JNI deps unless we embed them
checkNativeSdkVersion := a.shouldEmbedJnis(ctx) && !Bool(a.appProperties.Jni_uses_platform_apis)
@@ -1076,7 +1129,28 @@
},
)
+ if javaInfo != nil {
+ javaInfo.OutputFile = a.outputFile
+ setExtraJavaInfo(ctx, a, javaInfo)
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+ }
+
+ android.SetProvider(ctx, android.ApexBundleDepsDataProvider, android.ApexBundleDepsData{
+ FlatListPath: a.FlatListPath(),
+ Updatable: a.Updatable(),
+ })
+
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Class = []string{"APPS"}
+ if !a.embeddedJniLibs {
+ for _, jniLib := range a.jniLibs {
+ moduleInfoJSON.ExtraRequired = append(moduleInfoJSON.ExtraRequired, jniLib.name)
+ }
+ }
+
a.setOutputFiles(ctx)
+
+ buildComplianceMetadata(ctx)
}
func (a *AndroidApp) setOutputFiles(ctx android.ModuleContext) {
@@ -1108,29 +1182,35 @@
app.SdkVersion(ctx).Kind != android.SdkCorePlatform && !app.RequiresStableAPIs(ctx)
}
jniLib, prebuiltJniPackages := collectJniDeps(ctx, shouldCollectRecursiveNativeDeps,
- checkNativeSdkVersion, func(parent, child android.Module) bool {
+ checkNativeSdkVersion, func(parent, child android.ModuleProxy) bool {
apkInApex := ctx.Module().(android.ApexModule).NotInPlatform()
- childLinkable, _ := child.(cc.LinkableInterface)
- parentLinkable, _ := parent.(cc.LinkableInterface)
- useStubsOfDep := childLinkable.IsStubs()
- if apkInApex && parentLinkable != nil {
+ childLinkable, _ := android.OtherModuleProvider(ctx, child, cc.LinkableInfoProvider)
+ parentIsLinkable := false
+ if android.EqualModules(ctx.Module(), parent) {
+ parentLinkable, _ := ctx.Module().(cc.LinkableInterface)
+ parentIsLinkable = parentLinkable != nil
+ } else {
+ _, parentIsLinkable = android.OtherModuleProvider(ctx, parent, cc.LinkableInfoProvider)
+ }
+ useStubsOfDep := childLinkable.IsStubs
+ if apkInApex && parentIsLinkable {
// APK-in-APEX
// If the parent is a linkable interface, use stubs if the dependency edge crosses an apex boundary.
- useStubsOfDep = useStubsOfDep || (childLinkable.HasStubsVariants() && cc.ShouldUseStubForApex(ctx, parent, child))
+ useStubsOfDep = useStubsOfDep || (childLinkable.HasStubsVariants && cc.ShouldUseStubForApex(ctx, parent, child))
}
- return !childLinkable.IsNdk(ctx.Config()) && !useStubsOfDep
+ return !childLinkable.IsNdk && !useStubsOfDep
})
var certificates []Certificate
var directImplementationDeps android.Paths
var transitiveImplementationDeps []depset.DepSet[android.Path]
- ctx.VisitDirectDeps(func(module android.Module) {
+ ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
otherName := ctx.OtherModuleName(module)
tag := ctx.OtherModuleDependencyTag(module)
if tag == certificateTag {
- if dep, ok := module.(*AndroidAppCertificate); ok {
+ if dep, ok := android.OtherModuleProvider(ctx, module, AndroidAppCertificateInfoProvider); ok {
certificates = append(certificates, dep.Certificate)
} else {
ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName)
@@ -1154,22 +1234,25 @@
func collectJniDeps(ctx android.ModuleContext,
shouldCollectRecursiveNativeDeps bool,
checkNativeSdkVersion bool,
- filter func(parent, child android.Module) bool) ([]jniLib, android.Paths) {
+ filter func(parent, child android.ModuleProxy) bool) ([]jniLib, android.Paths) {
var jniLibs []jniLib
var prebuiltJniPackages android.Paths
seenModulePaths := make(map[string]bool)
- ctx.WalkDeps(func(module android.Module, parent android.Module) bool {
+ ctx.WalkDepsProxy(func(module, parent android.ModuleProxy) bool {
+ if !android.OtherModulePointerProviderOrDefault(ctx, module, android.CommonModuleInfoProvider).Enabled {
+ return false
+ }
otherName := ctx.OtherModuleName(module)
tag := ctx.OtherModuleDependencyTag(module)
if IsJniDepTag(tag) || cc.IsSharedDepTag(tag) {
- if dep, ok := module.(cc.LinkableInterface); ok {
+ if dep, ok := android.OtherModuleProvider(ctx, module, cc.LinkableInfoProvider); ok {
if filter != nil && !filter(parent, module) {
return false
}
- lib := dep.OutputFile()
+ lib := dep.OutputFile
if lib.Valid() {
path := lib.Path()
if seenModulePaths[path.String()] {
@@ -1177,7 +1260,8 @@
}
seenModulePaths[path.String()] = true
- if checkNativeSdkVersion && dep.SdkVersion() == "" {
+ commonInfo := android.OtherModulePointerProviderOrDefault(ctx, module, android.CommonModuleInfoProvider)
+ if checkNativeSdkVersion && commonInfo.SdkVersion == "" {
ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not",
otherName)
}
@@ -1185,11 +1269,11 @@
jniLibs = append(jniLibs, jniLib{
name: ctx.OtherModuleName(module),
path: path,
- target: module.Target(),
- coverageFile: dep.CoverageOutputFile(),
- unstrippedFile: dep.UnstrippedOutputFile(),
- partition: dep.Partition(),
- installPaths: android.OtherModuleProviderOrDefault(ctx, dep, android.InstallFilesProvider).InstallFiles,
+ target: commonInfo.Target,
+ coverageFile: dep.CoverageOutputFile,
+ unstrippedFile: dep.UnstrippedOutputFile,
+ partition: dep.Partition,
+ installPaths: android.OtherModuleProviderOrDefault(ctx, module, android.InstallFilesProvider).InstallFiles,
})
} else if ctx.Config().AllowMissingDependencies() {
ctx.AddMissingDependencies([]string{otherName})
@@ -1214,10 +1298,13 @@
}
func (a *AndroidApp) WalkPayloadDeps(ctx android.BaseModuleContext, do android.PayloadDepsCallback) {
- ctx.WalkDeps(func(child, parent android.Module) bool {
- isExternal := !a.DepIsInSameApex(ctx, child)
- if am, ok := child.(android.ApexModule); ok {
- if !do(ctx, parent, am, isExternal) {
+ ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool {
+ // TODO(ccross): Should this use android.DepIsInSameApex? Right now it is applying the android app
+ // heuristics to every transitive dependency, when it should probably be using the heuristics of the
+ // immediate parent.
+ isExternal := !a.GetDepInSameApexChecker().OutgoingDepIsInSameApex(ctx.OtherModuleDependencyTag(child))
+ if am, ok := android.OtherModuleProvider(ctx, child, android.CommonModuleInfoProvider); ok && am.IsApexModule {
+ if !do(ctx, parent, child, isExternal) {
return false
}
}
@@ -1231,12 +1318,12 @@
}
depsInfo := android.DepNameToDepInfoMap{}
- a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
+ a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from, to android.ModuleProxy, externalDep bool) bool {
depName := to.Name()
// Skip dependencies that are only available to APEXes; they are developed with updatability
// in mind and don't need manual approval.
- if to.(android.ApexModule).NotAvailableForPlatform() {
+ if android.OtherModulePointerProviderOrDefault(ctx, to, android.CommonModuleInfoProvider).NotAvailableForPlatform {
return true
}
@@ -1246,18 +1333,9 @@
depsInfo[depName] = info
} else {
toMinSdkVersion := "(no version)"
- if m, ok := to.(interface {
- MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
- }); ok {
- if v := m.MinSdkVersion(ctx); !v.IsNone() {
- toMinSdkVersion = v.String()
- }
- } else if m, ok := to.(interface{ MinSdkVersion() string }); ok {
- // TODO(b/175678607) eliminate the use of MinSdkVersion returning
- // string
- if v := m.MinSdkVersion(); v != "" {
- toMinSdkVersion = v
- }
+ if info, ok := android.OtherModuleProvider(ctx, to, android.CommonModuleInfoProvider); ok &&
+ !info.MinSdkVersion.IsPlatform && info.MinSdkVersion.ApiLevel != nil {
+ toMinSdkVersion = info.MinSdkVersion.ApiLevel.String()
}
depsInfo[depName] = android.ApexModuleDepInfo{
To: depName,
@@ -1292,11 +1370,19 @@
return a.overridableAppProperties.Certificate.GetOrDefault(ctx, "")
}
-func (a *AndroidApp) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
- if IsJniDepTag(ctx.OtherModuleDependencyTag(dep)) {
+func (m *AndroidApp) GetDepInSameApexChecker() android.DepInSameApexChecker {
+ return AppDepInSameApexChecker{}
+}
+
+type AppDepInSameApexChecker struct {
+ android.BaseDepInSameApexChecker
+}
+
+func (m AppDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
+ if IsJniDepTag(tag) {
return true
}
- return a.Library.DepIsInSameApex(ctx, dep)
+ return depIsInSameApex(tag)
}
func (a *AndroidApp) Privileged() bool {
@@ -1560,6 +1646,9 @@
}
a.generateAndroidBuildActions(ctx)
+ for _, c := range a.testProperties.Test_options.Tradefed_options {
+ configs = append(configs, c)
+ }
for _, module := range a.testProperties.Test_mainline_modules {
configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module})
}
@@ -1573,6 +1662,24 @@
a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_common_data)...)
a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_data)...)
a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_prefer32_data)...)
+ a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Host_common_data)...)
+
+ // Install test deps
+ if !ctx.Config().KatiEnabled() {
+ pathInTestCases := android.PathForModuleInstall(ctx, ctx.Module().Name())
+ if a.testConfig != nil {
+ ctx.InstallFile(pathInTestCases, ctx.Module().Name()+".config", a.testConfig)
+ }
+ dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml")
+ if dynamicConfig.Valid() {
+ ctx.InstallFile(pathInTestCases, ctx.Module().Name()+".dynamic", dynamicConfig.Path())
+ }
+ testDeps := append(a.data, a.extraTestConfigs...)
+ for _, data := range android.SortedUniquePaths(testDeps) {
+ dataPath := android.DataPath{SrcPath: data}
+ ctx.InstallTestData(pathInTestCases, []android.DataPath{dataPath})
+ }
+ }
android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
TestcaseRelDataFiles: testcaseRel(a.data),
@@ -1591,6 +1698,26 @@
TopLevelTarget: true,
})
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests")
+ if a.testConfig != nil {
+ moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, a.testConfig.String())
+ }
+ moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, a.extraTestConfigs.Strings()...)
+ if len(a.testProperties.Test_suites) > 0 {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, a.testProperties.Test_suites...)
+ } else {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
+ }
+
+ if _, ok := testConfig.(android.WritablePath); ok {
+ moduleInfoJSON.AutoTestConfig = []string{"true"}
+ }
+ moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, a.testProperties.Test_mainline_modules...)
+
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: a.testProperties.Test_suites,
+ })
}
func testcaseRel(paths android.Paths) []string {
@@ -1679,7 +1806,7 @@
module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
module.appProperties.AlwaysPackageNativeLibs = true
module.Module.dexpreopter.isTest = true
- module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
+ module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
module.addHostAndDeviceProperties()
module.AddProperties(
@@ -1730,12 +1857,14 @@
// TODO(b/192032291): Disable by default after auditing downstream usage.
module.Module.dexProperties.Optimize.EnabledByDefault = true
+ module.Module.dexProperties.Optimize.Ignore_library_extends_program = proptools.BoolPtr(true)
+ module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
module.Module.properties.Installable = proptools.BoolPtr(true)
module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
module.appProperties.AlwaysPackageNativeLibs = true
module.Module.dexpreopter.isTest = true
- module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
+ module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
module.addHostAndDeviceProperties()
module.AddProperties(
@@ -1762,6 +1891,12 @@
Certificate *string
}
+type AndroidAppCertificateInfo struct {
+ Certificate Certificate
+}
+
+var AndroidAppCertificateInfoProvider = blueprint.NewProvider[AndroidAppCertificateInfo]()
+
// android_app_certificate modules can be referenced by the certificates property of android_app modules to select
// the signing key.
func AndroidAppCertificateFactory() android.Module {
@@ -1777,6 +1912,10 @@
Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"),
Key: android.PathForModuleSrc(ctx, cert+".pk8"),
}
+
+ android.SetProvider(ctx, AndroidAppCertificateInfoProvider, AndroidAppCertificateInfo{
+ Certificate: c.Certificate,
+ })
}
type OverrideAndroidApp struct {
@@ -1931,7 +2070,7 @@
return clcMap
}
- ctx.VisitDirectDeps(func(m android.Module) {
+ ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag)
if !isUsesLibTag {
return
@@ -1939,31 +2078,35 @@
dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m))
+ javaInfo, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider)
+ if !ok {
+ return
+ }
// Skip stub libraries. A dependency on the implementation library has been added earlier,
// so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed
// from implementation libraries by their name, which is different as it has a suffix.
- if comp, ok := m.(SdkLibraryComponentDependency); ok {
- if impl := comp.OptionalSdkLibraryImplementation(); impl != nil && *impl != dep {
+ if comp := javaInfo.SdkLibraryComponentDependencyInfo; comp != nil {
+ if impl := comp.OptionalSdkLibraryImplementation; impl != nil && *impl != dep {
return
}
}
- if lib, ok := m.(UsesLibraryDependency); ok {
+ if lib := javaInfo.UsesLibraryDependencyInfo; lib != nil {
if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok {
// Skip java_sdk_library dependencies that provide stubs, but not an implementation.
// This will be restricted to optional_uses_libs
- if tag == usesLibOptTag && lib.DexJarBuildPath(ctx).PathOrNil() == nil {
+ if tag == usesLibOptTag && javaInfo.DexJarBuildPath.PathOrNil() == nil {
u.shouldDisableDexpreopt = true
return
}
}
libName := dep
- if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil {
- libName = *ulib.ProvidesUsesLib()
+ if ulib := javaInfo.ProvidesUsesLibInfo; ulib != nil && ulib.ProvidesUsesLib != nil {
+ libName = *ulib.ProvidesUsesLib
}
clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional,
- lib.DexJarBuildPath(ctx).PathOrNil(), lib.DexJarInstallPath(),
- lib.ClassLoaderContexts())
+ javaInfo.DexJarBuildPath.PathOrNil(), lib.DexJarInstallPath,
+ lib.ClassLoaderContexts)
} else if ctx.Config().AllowMissingDependencies() {
ctx.AddMissingDependencies([]string{dep})
} else {
@@ -2055,3 +2198,33 @@
classLoaderContexts *dexpreopt.ClassLoaderContextMap) {
u.verifyUsesLibraries(ctx, apk, nil, classLoaderContexts) // for APKs manifest_check does not write output file
}
+
+// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in
+// the same way.
+type androidApp interface {
+ android.Module
+ Privileged() bool
+ InstallApkName() string
+ OutputFile() android.Path
+ JacocoReportClassesFile() android.Path
+ Certificate() Certificate
+ BaseModuleName() string
+ PrivAppAllowlist() android.OptionalPath
+}
+
+var _ androidApp = (*AndroidApp)(nil)
+var _ androidApp = (*AndroidAppImport)(nil)
+var _ androidApp = (*AndroidTestHelperApp)(nil)
+
+func setCommonAppInfo(appInfo *AppInfo, m androidApp) {
+ appInfo.Privileged = m.Privileged()
+ appInfo.OutputFile = m.OutputFile()
+ appInfo.InstallApkName = m.InstallApkName()
+ appInfo.JacocoReportClassesFile = m.JacocoReportClassesFile()
+ appInfo.Certificate = m.Certificate()
+ appInfo.PrivAppAllowlist = m.PrivAppAllowlist()
+}
+
+type AppInfos []AppInfo
+
+var AppInfosProvider = blueprint.NewProvider[AppInfos]()
diff --git a/java/app_import.go b/java/app_import.go
index 8951c7d..9fb13ba 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -43,6 +43,12 @@
Description: "Uncompress embedded JNI libs",
})
+ stripEmbeddedJniLibsUnusedArchRule = pctx.AndroidStaticRule("strip-embedded-jni-libs-from-unused-arch", blueprint.RuleParams{
+ Command: `${config.Zip2ZipCmd} -i $in -o $out -x 'lib/**/*.so' $extraArgs`,
+ CommandDeps: []string{"${config.Zip2ZipCmd}"},
+ Description: "Remove all JNI libs from unused architectures",
+ }, "extraArgs")
+
uncompressDexRule = pctx.AndroidStaticRule("uncompress-dex", blueprint.RuleParams{
Command: `if (zipinfo $in '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then ` +
`${config.Zip2ZipCmd} -i $in -o $out -0 'classes*.dex'` +
@@ -56,6 +62,18 @@
CommandDeps: []string{"build/soong/scripts/check_prebuilt_presigned_apk.py", "${config.Aapt2Cmd}", "${config.ZipAlign}"},
Description: "Check presigned apk",
}, "extraArgs")
+
+ extractApkRule = pctx.AndroidStaticRule("extract-apk", blueprint.RuleParams{
+ Command: "unzip -p $in $extract_apk > $out",
+ Description: "Extract specific sub apk",
+ }, "extract_apk")
+
+ gzipRule = pctx.AndroidStaticRule("gzip",
+ blueprint.RuleParams{
+ Command: "prebuilts/build-tools/path/linux-x86/gzip -9 -c $in > $out",
+ CommandDeps: []string{"prebuilts/build-tools/path/linux-x86/gzip"},
+ Description: "gzip $out",
+ })
)
func RegisterAppImportBuildComponents(ctx android.RegistrationContext) {
@@ -150,10 +168,19 @@
// the prebuilt is Name() without "prebuilt_" prefix
Source_module_name *string
+ // Whether stripping all libraries from unused architectures.
+ Strip_unused_jni_arch *bool
+
// Path to the .prebuilt_info file of the prebuilt app.
// In case of mainline modules, the .prebuilt_info file contains the build_id that was used
// to generate the prebuilt.
Prebuilt_info *string `android:"path"`
+
+ // Path of extracted apk which is extracted from prebuilt apk. Use this extracted to import.
+ Extract_apk proptools.Configurable[string]
+
+ // Compress the output APK using gzip. Defaults to false.
+ Compress_apk proptools.Configurable[bool] `android:"arch_variant,replace_instead_of_append"`
}
func (a *AndroidAppImport) IsInstallable() bool {
@@ -278,6 +305,19 @@
})
}
+func (a *AndroidAppImport) extractSubApk(
+ ctx android.ModuleContext, inputPath android.Path, outputPath android.WritablePath) {
+ extractApkPath := a.properties.Extract_apk.GetOrDefault(ctx, "")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: extractApkRule,
+ Input: inputPath,
+ Output: outputPath,
+ Args: map[string]string{
+ "extract_apk": extractApkPath,
+ },
+ })
+}
+
// Returns whether this module should have the dex file stored uncompressed in the APK.
func (a *AndroidAppImport) shouldUncompressDex(ctx android.ModuleContext) bool {
if ctx.Config().UnbundledBuild() || proptools.Bool(a.properties.Preprocessed) {
@@ -292,8 +332,34 @@
return shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &a.dexpreopter)
}
+func (a *AndroidAppImport) stripEmbeddedJniLibsUnusedArch(
+ ctx android.ModuleContext, inputPath android.Path, outputPath android.WritablePath) {
+ var wantedJniLibSlice []string
+ for _, target := range ctx.MultiTargets() {
+ supported_abis := target.Arch.Abi
+ for _, arch := range supported_abis {
+ wantedJniLibSlice = append(wantedJniLibSlice, " -X 'lib/"+arch+"/*.so'")
+ }
+ }
+ wantedJniLibString := strings.Join(wantedJniLibSlice, " ")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: stripEmbeddedJniLibsUnusedArchRule,
+ Input: inputPath,
+ Output: outputPath,
+ Args: map[string]string{
+ "extraArgs": wantedJniLibString,
+ },
+ })
+}
+
func (a *AndroidAppImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.generateAndroidBuildActions(ctx)
+
+ appInfo := &AppInfo{
+ Prebuilt: true,
+ }
+ setCommonAppInfo(appInfo, a)
+ android.SetProvider(ctx, AppInfoProvider, appInfo)
}
func (a *AndroidAppImport) InstallApkName() string {
@@ -336,10 +402,14 @@
ctx.ModuleErrorf("One and only one of certficate, presigned (implied by preprocessed), and default_dev_cert properties must be set")
}
- // TODO: LOCAL_EXTRACT_APK/LOCAL_EXTRACT_DPI_APK
// TODO: LOCAL_PACKAGE_SPLITS
srcApk := a.prebuilt.SingleSourcePath(ctx)
+ if a.properties.Extract_apk.GetOrDefault(ctx, "") != "" {
+ extract_apk := android.PathForModuleOut(ctx, "extract-apk", ctx.ModuleName()+".apk")
+ a.extractSubApk(ctx, srcApk, extract_apk)
+ srcApk = extract_apk
+ }
// TODO: Install or embed JNI libraries
@@ -347,6 +417,13 @@
jnisUncompressed := android.PathForModuleOut(ctx, "jnis-uncompressed", ctx.ModuleName()+".apk")
a.uncompressEmbeddedJniLibs(ctx, srcApk, jnisUncompressed)
+ // Strip all embedded JNI libs and include only required ones accordingly to the module's compile_multilib
+ if Bool(a.properties.Strip_unused_jni_arch) {
+ jnisStripped := android.PathForModuleOut(ctx, "jnis-stripped", ctx.ModuleName()+".apk")
+ a.stripEmbeddedJniLibsUnusedArch(ctx, jnisUncompressed, jnisStripped)
+ jnisUncompressed = jnisStripped
+ }
+
var pathFragments []string
relInstallPath := String(a.properties.Relative_install_path)
@@ -366,7 +443,9 @@
a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries(ctx)
a.dexpreopter.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
- if a.usesLibrary.shouldDisableDexpreopt {
+
+ // Disable Dexpreopt if Compress_apk is true. It follows the build/make/core/app_prebuilt_internal.mk
+ if a.usesLibrary.shouldDisableDexpreopt || a.properties.Compress_apk.GetOrDefault(ctx, false) {
a.dexpreopter.disableDexpreopt()
}
@@ -385,7 +464,13 @@
jnisUncompressed = dexUncompressed
}
- apkFilename := proptools.StringDefault(a.properties.Filename, a.BaseModuleName()+".apk")
+ defaultApkFilename := a.BaseModuleName()
+ if a.properties.Compress_apk.GetOrDefault(ctx, false) {
+ defaultApkFilename += ".apk.gz"
+ } else {
+ defaultApkFilename += ".apk"
+ }
+ apkFilename := proptools.StringDefault(a.properties.Filename, defaultApkFilename)
// TODO: Handle EXTERNAL
@@ -425,7 +510,16 @@
a.certificate = PresignedCertificate
}
- // TODO: Optionally compress the output apk.
+ if a.properties.Compress_apk.GetOrDefault(ctx, false) {
+ outputFile := android.PathForModuleOut(ctx, "compressed_apk", apkFilename)
+ ctx.Build(pctx, android.BuildParams{
+ Rule: gzipRule,
+ Input: a.outputFile,
+ Output: outputFile,
+ Description: "Compressing " + a.outputFile.Base(),
+ })
+ a.outputFile = outputFile
+ }
if apexInfo.IsForPlatform() {
a.installPath = ctx.InstallFile(installDir, apkFilename, a.outputFile)
@@ -443,6 +537,8 @@
ctx.SetOutputFiles([]android.Path{a.outputFile}, "")
+ buildComplianceMetadata(ctx)
+
// TODO: androidmk converter jni libs
}
@@ -538,7 +634,15 @@
return Bool(a.properties.Privileged)
}
-func (a *AndroidAppImport) DepIsInSameApex(_ android.BaseModuleContext, _ android.Module) bool {
+func (m *AndroidAppImport) GetDepInSameApexChecker() android.DepInSameApexChecker {
+ return AppImportDepInSameApexChecker{}
+}
+
+type AppImportDepInSameApexChecker struct {
+ android.BaseDepInSameApexChecker
+}
+
+func (m AppImportDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
// android_app_import might have extra dependencies via uses_libs property.
// Don't track the dependency as we don't automatically add those libraries
// to the classpath. It should be explicitly added to java_libs property of APEX
@@ -556,10 +660,8 @@
var _ android.ApexModule = (*AndroidAppImport)(nil)
// Implements android.ApexModule
-func (j *AndroidAppImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
- sdkVersion android.ApiLevel) error {
- // Do not check for prebuilts against the min_sdk_version of enclosing APEX
- return nil
+func (m *AndroidAppImport) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
+ return android.MinApiLevel
}
func createVariantGroupType(variants []string, variantGroupName string) reflect.Type {
@@ -682,7 +784,29 @@
func (a *AndroidTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.generateAndroidBuildActions(ctx)
+ a.updateModuleInfoJSON(ctx)
+
a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
+
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: a.testProperties.Test_suites,
+ })
+}
+
+func (a *AndroidTestImport) updateModuleInfoJSON(ctx android.ModuleContext) {
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Class = []string{"APPS"}
+ moduleInfoJSON.CompatibilitySuites = []string{"null-suite"}
+ if len(a.testProperties.Test_suites) > 0 {
+ moduleInfoJSON.CompatibilitySuites = a.testProperties.Test_suites
+ }
+ moduleInfoJSON.SystemSharedLibs = []string{"none"}
+ moduleInfoJSON.Tags = []string{"tests"}
+ moduleInfoJSON.RegisterNameOverride = a.BaseModuleName()
+ testConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "AndroidTest.xml")
+ if testConfig.Valid() {
+ moduleInfoJSON.TestConfig = []string{testConfig.String()}
+ }
}
func (a *AndroidTestImport) InstallInTestcases() bool {
diff --git a/java/app_import_test.go b/java/app_import_test.go
index 54a5e75..2600767 100644
--- a/java/app_import_test.go
+++ b/java/app_import_test.go
@@ -26,6 +26,7 @@
)
func TestAndroidAppImport(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_app_import {
name: "foo",
@@ -37,7 +38,47 @@
}
`)
- variant := ctx.ModuleForTests("foo", "android_common")
+ variant := ctx.ModuleForTests(t, "foo", "android_common")
+
+ // Check dexpreopt outputs.
+ if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil ||
+ variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.odex").Rule == nil {
+ t.Errorf("can't find dexpreopt outputs")
+ }
+
+ // Check cert signing flag.
+ signedApk := variant.Output("signed/foo.apk")
+ signingFlag := signedApk.Args["certificates"]
+ expected := "build/make/target/product/security/platform.x509.pem build/make/target/product/security/platform.pk8"
+ if expected != signingFlag {
+ t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
+ }
+ rule := variant.Rule("genProvenanceMetaData")
+ android.AssertStringEquals(t, "Invalid input", "prebuilts/apk/app.apk", rule.Inputs[0].String())
+ android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto", rule.Output.String())
+ android.AssertStringEquals(t, "Invalid args", "foo", rule.Args["module_name"])
+ android.AssertStringEquals(t, "Invalid args", "/system/app/foo/foo.apk", rule.Args["install_path"])
+}
+
+func TestAndroidAppImportWithDefaults(t *testing.T) {
+ t.Parallel()
+ ctx, _ := testJava(t, `
+ android_app_import {
+ name: "foo",
+ defaults: ["foo_defaults"],
+ }
+
+ java_defaults {
+ name: "foo_defaults",
+ apk: "prebuilts/apk/app.apk",
+ certificate: "platform",
+ dex_preopt: {
+ enabled: true,
+ },
+ }
+ `)
+
+ variant := ctx.ModuleForTests(t, "foo", "android_common")
// Check dexpreopt outputs.
if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil ||
@@ -60,6 +101,7 @@
}
func TestAndroidAppImport_NoDexPreopt(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_app_import {
name: "foo",
@@ -71,7 +113,7 @@
}
`)
- variant := ctx.ModuleForTests("foo", "android_common")
+ variant := ctx.ModuleForTests(t, "foo", "android_common")
// Check dexpreopt outputs. They shouldn't exist.
if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule != nil ||
@@ -87,6 +129,7 @@
}
func TestAndroidAppImport_Presigned(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_app_import {
name: "foo",
@@ -98,7 +141,7 @@
}
`)
- variant := ctx.ModuleForTests("foo", "android_common")
+ variant := ctx.ModuleForTests(t, "foo", "android_common")
// Check dexpreopt outputs.
if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil ||
@@ -121,6 +164,7 @@
}
func TestAndroidAppImport_SigningLineage(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_app_import {
name: "foo",
@@ -137,7 +181,7 @@
}
`)
- variant := ctx.ModuleForTests("foo", "android_common")
+ variant := ctx.ModuleForTests(t, "foo", "android_common")
signedApk := variant.Output("signed/foo.apk")
// Check certificates
@@ -164,6 +208,7 @@
}
func TestAndroidAppImport_SigningLineageFilegroup(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_app_import {
name: "foo",
@@ -178,7 +223,7 @@
}
`)
- variant := ctx.ModuleForTests("foo", "android_common")
+ variant := ctx.ModuleForTests(t, "foo", "android_common")
signedApk := variant.Output("signed/foo.apk")
// Check cert signing lineage flag.
@@ -196,6 +241,7 @@
}
func TestAndroidAppImport_DefaultDevCert(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_app_import {
name: "foo",
@@ -207,7 +253,7 @@
}
`)
- variant := ctx.ModuleForTests("foo", "android_common")
+ variant := ctx.ModuleForTests(t, "foo", "android_common")
// Check dexpreopt outputs.
if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil ||
@@ -231,6 +277,7 @@
}
func TestAndroidAppImport_DpiVariants(t *testing.T) {
+ t.Parallel()
bp := `
android_app_import {
name: "foo",
@@ -302,7 +349,7 @@
}),
).RunTestWithBp(t, bp)
- variant := result.ModuleForTests("foo", "android_common")
+ variant := result.ModuleForTests(t, "foo", "android_common")
input := variant.Output("jnis-uncompressed/foo.apk").Input.String()
if strings.HasSuffix(input, test.expected) {
t.Errorf("wrong src apk, expected: %q got: %q", test.expected, input)
@@ -317,6 +364,7 @@
}
func TestAndroidAppImport_Filename(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_app_import {
name: "foo",
@@ -325,10 +373,25 @@
}
android_app_import {
+ name: "foo_compressed",
+ apk: "prebuilts/apk/app.apk",
+ presigned: true,
+ compress_apk: true,
+ }
+
+ android_app_import {
name: "bar",
apk: "prebuilts/apk/app.apk",
presigned: true,
- filename: "bar_sample.apk"
+ filename: "bar_sample.apk",
+ }
+
+ android_app_import {
+ name: "compressed_bar",
+ apk: "prebuilts/apk/app.apk",
+ presigned: true,
+ filename: "bar_sample.apk",
+ compress_apk: true,
}
`)
@@ -347,16 +410,30 @@
expectedMetaDataPath: "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto",
},
{
+ name: "foo_compressed",
+ expected: "foo_compressed.apk.gz",
+ onDevice: "/system/app/foo_compressed/foo_compressed.apk.gz",
+ expectedArtifactPath: "prebuilts/apk/app.apk",
+ expectedMetaDataPath: "out/soong/.intermediates/provenance_metadata/foo_compressed/provenance_metadata.textproto",
+ },
+ {
name: "bar",
expected: "bar_sample.apk",
onDevice: "/system/app/bar/bar_sample.apk",
expectedArtifactPath: "prebuilts/apk/app.apk",
expectedMetaDataPath: "out/soong/.intermediates/provenance_metadata/bar/provenance_metadata.textproto",
},
+ {
+ name: "compressed_bar",
+ expected: "bar_sample.apk",
+ onDevice: "/system/app/compressed_bar/bar_sample.apk",
+ expectedArtifactPath: "prebuilts/apk/app.apk",
+ expectedMetaDataPath: "out/soong/.intermediates/provenance_metadata/compressed_bar/provenance_metadata.textproto",
+ },
}
for _, test := range testCases {
- variant := ctx.ModuleForTests(test.name, "android_common")
+ variant := ctx.ModuleForTests(t, test.name, "android_common")
if variant.MaybeOutput(test.expected).Rule == nil {
t.Errorf("can't find output named %q - all outputs: %v", test.expected, variant.AllOutputs())
}
@@ -380,6 +457,7 @@
}
func TestAndroidAppImport_ArchVariants(t *testing.T) {
+ t.Parallel()
// The test config's target arch is ARM64.
testCases := []struct {
name string
@@ -505,9 +583,10 @@
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, test.bp)
- variant := ctx.ModuleForTests("foo", "android_common")
+ variant := ctx.ModuleForTests(t, "foo", "android_common")
if test.expected == "" {
if variant.Module().Enabled(android.PanickingConfigAndErrorContext(ctx)) {
t.Error("module should have been disabled, but wasn't")
@@ -530,6 +609,7 @@
}
func TestAndroidAppImport_SoongConfigVariables(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
bp string
@@ -572,6 +652,7 @@
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
+ t.Parallel()
ctx := android.GroupFixturePreparers(
prepareForJavaTest,
android.PrepareForTestWithSoongConfigModuleBuildComponents,
@@ -584,7 +665,7 @@
}),
).RunTestWithBp(t, test.bp).TestContext
- variant := ctx.ModuleForTests("foo", "android_common")
+ variant := ctx.ModuleForTests(t, "foo", "android_common")
if test.expected == "" {
if variant.Module().Enabled(android.PanickingConfigAndErrorContext(ctx)) {
t.Error("module should have been disabled, but wasn't")
@@ -607,6 +688,7 @@
}
func TestAndroidAppImport_overridesDisabledAndroidApp(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_app {
name: "foo",
@@ -622,7 +704,7 @@
}
`)
- variant := ctx.ModuleForTests("prebuilt_foo", "android_common")
+ variant := ctx.ModuleForTests(t, "prebuilt_foo", "android_common")
a := variant.Module().(*AndroidAppImport)
// The prebuilt module should still be enabled and active even if the source-based counterpart
// is disabled.
@@ -635,6 +717,7 @@
}
func TestAndroidAppImport_relativeInstallPath(t *testing.T) {
+ t.Parallel()
bp := `
android_app_import {
name: "no_relative_install_path",
@@ -664,28 +747,49 @@
}{
{
name: "no_relative_install_path",
- expectedInstallPath: "out/soong/target/product/test_device/system/app/no_relative_install_path/no_relative_install_path.apk",
+ expectedInstallPath: "out/target/product/test_device/system/app/no_relative_install_path/no_relative_install_path.apk",
errorMessage: "Install path is not correct when relative_install_path is missing",
},
{
name: "relative_install_path",
- expectedInstallPath: "out/soong/target/product/test_device/system/app/my/path/relative_install_path/relative_install_path.apk",
+ expectedInstallPath: "out/target/product/test_device/system/app/my/path/relative_install_path/relative_install_path.apk",
errorMessage: "Install path is not correct for app when relative_install_path is present",
},
{
name: "privileged_relative_install_path",
- expectedInstallPath: "out/soong/target/product/test_device/system/priv-app/my/path/privileged_relative_install_path/privileged_relative_install_path.apk",
+ expectedInstallPath: "out/target/product/test_device/system/priv-app/my/path/privileged_relative_install_path/privileged_relative_install_path.apk",
errorMessage: "Install path is not correct for privileged app when relative_install_path is present",
},
}
for _, testCase := range testCases {
- ctx, _ := testJava(t, bp)
- mod := ctx.ModuleForTests(testCase.name, "android_common").Module().(*AndroidAppImport)
- android.AssertPathRelativeToTopEquals(t, testCase.errorMessage, testCase.expectedInstallPath, mod.installPath)
+ t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
+ ctx, _ := testJava(t, bp)
+ mod := ctx.ModuleForTests(t, testCase.name, "android_common").Module().(*AndroidAppImport)
+ android.AssertPathRelativeToTopEquals(t, testCase.errorMessage, testCase.expectedInstallPath, mod.installPath)
+ })
}
}
+func TestAndroidAppImport_ExtractApk(t *testing.T) {
+ t.Parallel()
+ ctx, _ := testJava(t, `
+ android_app_import {
+ name: "foo",
+ apk: "prebuilts/apk/app.apk",
+ certificate: "platform",
+ extract_apk: "extract_path/sub_app.apk"
+ }
+ `)
+
+ variant := ctx.ModuleForTests(t, "foo", "android_common")
+ extractRuleArgs := variant.Output("extract-apk/foo.apk").BuildParams.Args
+ if extractRuleArgs["extract_apk"] != "extract_path/sub_app.apk" {
+ t.Errorf("Unexpected extract apk args: %s", extractRuleArgs["extract_apk"])
+ }
+}
func TestAndroidTestImport(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_test_import {
name: "foo",
@@ -697,7 +801,7 @@
}
`)
- test := ctx.ModuleForTests("foo", "android_common").Module().(*AndroidTestImport)
+ test := ctx.ModuleForTests(t, "foo", "android_common").Module().(*AndroidTestImport)
// Check android mks.
entries := android.AndroidMkEntriesForTest(t, ctx, test)[0]
@@ -714,6 +818,7 @@
}
func TestAndroidTestImport_NoJinUncompressForPresigned(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_test_import {
name: "foo",
@@ -734,16 +839,16 @@
}
`)
- variant := ctx.ModuleForTests("foo", "android_common")
+ variant := ctx.ModuleForTests(t, "foo", "android_common")
jniRule := variant.Output("jnis-uncompressed/foo.apk").BuildParams.Rule.String()
if jniRule == android.Cp.String() {
- t.Errorf("Unexpected JNI uncompress rule command: " + jniRule)
+ t.Errorf("Unexpected JNI uncompress rule command: %s", jniRule)
}
- variant = ctx.ModuleForTests("foo_presigned", "android_common")
+ variant = ctx.ModuleForTests(t, "foo_presigned", "android_common")
jniRule = variant.Output("jnis-uncompressed/foo_presigned.apk").BuildParams.Rule.String()
if jniRule != android.Cp.String() {
- t.Errorf("Unexpected JNI uncompress rule: " + jniRule)
+ t.Errorf("Unexpected JNI uncompress rule: %s", jniRule)
}
if variant.MaybeOutput("zip-aligned/foo_presigned.apk").Rule == nil {
t.Errorf("Presigned test apk should be aligned")
@@ -751,6 +856,7 @@
}
func TestAndroidTestImport_Preprocessed(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_test_import {
name: "foo",
@@ -761,10 +867,10 @@
`)
apkName := "foo.apk"
- variant := ctx.ModuleForTests("foo", "android_common")
+ variant := ctx.ModuleForTests(t, "foo", "android_common")
jniRule := variant.Output("jnis-uncompressed/" + apkName).BuildParams.Rule.String()
if jniRule != android.Cp.String() {
- t.Errorf("Unexpected JNI uncompress rule: " + jniRule)
+ t.Errorf("Unexpected JNI uncompress rule: %s", jniRule)
}
// Make sure signing and aligning were skipped.
@@ -777,9 +883,11 @@
}
func TestAndroidAppImport_Preprocessed(t *testing.T) {
+ t.Parallel()
for _, dontUncompressPrivAppDexs := range []bool{false, true} {
name := fmt.Sprintf("dontUncompressPrivAppDexs:%t", dontUncompressPrivAppDexs)
t.Run(name, func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
@@ -804,10 +912,10 @@
// non-privileged app
apkName := "foo.apk"
- variant := result.ModuleForTests("foo", "android_common")
+ variant := result.ModuleForTests(t, "foo", "android_common")
outputBuildParams := variant.Output(apkName).BuildParams
if outputBuildParams.Rule.String() != android.Cp.String() {
- t.Errorf("Unexpected prebuilt android_app_import rule: " + outputBuildParams.Rule.String())
+ t.Errorf("Unexpected prebuilt android_app_import rule: %s", outputBuildParams.Rule.String())
}
// Make sure compression and aligning were validated.
@@ -817,7 +925,7 @@
validationBuildParams := variant.Output("validated-prebuilt/check.stamp").BuildParams
if validationBuildParams.Rule.String() != checkPresignedApkRule.String() {
- t.Errorf("Unexpected validation rule: " + validationBuildParams.Rule.String())
+ t.Errorf("Unexpected validation rule: %s", validationBuildParams.Rule.String())
}
expectedScriptArgs := "--preprocessed"
@@ -826,10 +934,10 @@
// privileged app
apkName = "bar.apk"
- variant = result.ModuleForTests("bar", "android_common")
+ variant = result.ModuleForTests(t, "bar", "android_common")
outputBuildParams = variant.Output(apkName).BuildParams
if outputBuildParams.Rule.String() != android.Cp.String() {
- t.Errorf("Unexpected prebuilt android_app_import rule: " + outputBuildParams.Rule.String())
+ t.Errorf("Unexpected prebuilt android_app_import rule: %s", outputBuildParams.Rule.String())
}
// Make sure compression and aligning were validated.
@@ -839,7 +947,7 @@
validationBuildParams = variant.Output("validated-prebuilt/check.stamp").BuildParams
if validationBuildParams.Rule.String() != checkPresignedApkRule.String() {
- t.Errorf("Unexpected validation rule: " + validationBuildParams.Rule.String())
+ t.Errorf("Unexpected validation rule: %s", validationBuildParams.Rule.String())
}
expectedScriptArgs = "--privileged"
@@ -854,6 +962,7 @@
}
func TestAndroidTestImport_UncompressDex(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
bp string
@@ -894,7 +1003,7 @@
}),
).RunTestWithBp(t, bp)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
actual := foo.MaybeRule("uncompress-dex").Rule != nil
expect := !unbundled
@@ -917,6 +1026,7 @@
name := fmt.Sprintf("%s,unbundled:%t,dontUncompressPrivAppDexs:%t",
tt.name, unbundled, dontUncompressPrivAppDexs)
t.Run(name, func(t *testing.T) {
+ t.Parallel()
test(t, tt.bp, unbundled, dontUncompressPrivAppDexs)
})
}
@@ -925,6 +1035,7 @@
}
func TestAppImportMissingCertificateAllowMissingDependencies(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.PrepareForTestWithAllowMissingDependencies,
@@ -936,7 +1047,7 @@
certificate: ":missing_certificate",
}`)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
fooApk := foo.Output("signed/foo.apk")
if fooApk.Rule != android.ErrorRule {
t.Fatalf("expected ErrorRule for foo.apk, got %s", fooApk.Rule.String())
diff --git a/java/app_set.go b/java/app_set.go
index 7997570..6a2c678 100644
--- a/java/app_set.go
+++ b/java/app_set.go
@@ -192,6 +192,12 @@
},
)
+ android.SetProvider(ctx, AppInfoProvider, &AppInfo{
+ AppSet: true,
+ Privileged: as.Privileged(),
+ OutputFile: as.OutputFile(),
+ ApkCertsFile: as.apkcertsFile,
+ })
}
func (as *AndroidAppSet) InstallBypassMake() bool { return true }
diff --git a/java/app_set_test.go b/java/app_set_test.go
index c02b359..9b4c44b 100644
--- a/java/app_set_test.go
+++ b/java/app_set_test.go
@@ -24,13 +24,14 @@
)
func TestAndroidAppSet(t *testing.T) {
+ t.Parallel()
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
android_app_set {
name: "foo",
set: "prebuilts/apks/app.apks",
prerelease: true,
}`)
- module := result.ModuleForTests("foo", "android_common")
+ module := result.ModuleForTests(t, "foo", "android_common")
const packedSplitApks = "foo.zip"
params := module.Output(packedSplitApks)
if params.Rule == nil {
@@ -65,6 +66,7 @@
}
func TestAndroidAppSet_Variants(t *testing.T) {
+ t.Parallel()
bp := `
android_app_set {
name: "foo",
@@ -113,24 +115,24 @@
}
for _, test := range testCases {
- ctx := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.AAPTPrebuiltDPI = test.aaptPrebuiltDPI
- variables.Platform_sdk_version = &test.sdkVersion
- }),
- android.FixtureModifyConfig(func(config android.Config) {
- config.Targets[android.Android] = test.targets
- }),
- ).RunTestWithBp(t, bp)
+ t.Run(test.name, func(t *testing.T) {
+ ctx := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.AAPTPrebuiltDPI = test.aaptPrebuiltDPI
+ variables.Platform_sdk_version = &test.sdkVersion
+ }),
+ android.FixtureModifyConfig(func(config android.Config) {
+ config.Targets[android.Android] = test.targets
+ }),
+ ).RunTestWithBp(t, bp)
- module := ctx.ModuleForTests("foo", "android_common")
- const packedSplitApks = "foo.zip"
- params := module.Output(packedSplitApks)
- for k, v := range test.expected {
- t.Run(test.name, func(t *testing.T) {
+ module := ctx.ModuleForTests(t, "foo", "android_common")
+ const packedSplitApks = "foo.zip"
+ params := module.Output(packedSplitApks)
+ for k, v := range test.expected {
android.AssertStringEquals(t, fmt.Sprintf("arg value for `%s`", k), v, params.Args[k])
- })
- }
+ }
+ })
}
}
diff --git a/java/app_test.go b/java/app_test.go
index e9422a6..c6b22c7 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -18,6 +18,7 @@
"fmt"
"path/filepath"
"reflect"
+ "regexp"
"sort"
"strings"
"testing"
@@ -41,6 +42,7 @@
}
func TestApp(t *testing.T) {
+ t.Parallel()
resourceFiles := []string{
"res/layout/layout.xml",
"res/values/strings.xml",
@@ -55,6 +57,7 @@
for _, moduleType := range []string{"android_app", "android_library"} {
t.Run(moduleType, func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
android.FixtureModifyMockFS(func(fs android.MockFS) {
@@ -69,15 +72,15 @@
}
`)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
var expectedLinkImplicits []string
manifestFixer := foo.Output("manifest_fixer/AndroidManifest.xml")
expectedLinkImplicits = append(expectedLinkImplicits, manifestFixer.Output.String())
- frameworkRes := result.ModuleForTests("framework-res", "android_common")
- omniromRes := result.ModuleForTests("omnirom-res", "android_common")
+ frameworkRes := result.ModuleForTests(t, "framework-res", "android_common")
+ omniromRes := result.ModuleForTests(t,"omnirom-res", "android_common")
expectedLinkImplicits = append(expectedLinkImplicits,
frameworkRes.Output("package-res.apk").Output.String())
expectedLinkImplicits = append(expectedLinkImplicits,
@@ -96,13 +99,14 @@
expectedLinkImplicits = append(expectedLinkImplicits, list.Output.String())
// Check that the link rule uses
- res := result.ModuleForTests("foo", "android_common").Output("package-res.apk")
+ res := result.ModuleForTests(t, "foo", "android_common").Output("package-res.apk")
android.AssertDeepEquals(t, "aapt2 link implicits", expectedLinkImplicits, res.Implicits.Strings())
})
}
}
func TestAppSplits(t *testing.T) {
+ t.Parallel()
ctx := testApp(t, `
android_app {
name: "foo",
@@ -111,7 +115,7 @@
sdk_version: "current"
}`)
- foo := ctx.ModuleForTests("foo", "android_common")
+ foo := ctx.ModuleForTests(t, "foo", "android_common")
expectedOutputs := []string{
"out/soong/.intermediates/foo/android_common/foo.apk",
@@ -127,6 +131,7 @@
}
func TestPlatformAPIs(t *testing.T) {
+ t.Parallel()
testJava(t, `
android_app {
name: "foo",
@@ -161,6 +166,7 @@
}
func TestAndroidAppLinkType(t *testing.T) {
+ t.Parallel()
testJava(t, `
android_app {
name: "foo",
@@ -250,6 +256,7 @@
}
func TestUpdatableApps(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
bp string
@@ -361,6 +368,7 @@
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
+ t.Parallel()
errorHandler := android.FixtureExpectsNoErrors
if test.expectedError != "" {
errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(test.expectedError)
@@ -375,6 +383,7 @@
}
func TestUpdatableApps_TransitiveDepsShouldSetMinSdkVersion(t *testing.T) {
+ t.Parallel()
testJavaError(t, `module "bar".*: should support min_sdk_version\(29\)`, cc.GatherRequiredDepsForTest(android.Android)+`
android_app {
name: "foo",
@@ -393,6 +402,7 @@
}
func TestUpdatableApps_JniLibsShouldShouldSupportMinSdkVersion(t *testing.T) {
+ t.Parallel()
testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
android_app {
name: "foo",
@@ -413,6 +423,7 @@
}
func TestUpdatableApps_JniLibShouldBeBuiltAgainstMinSdkVersion(t *testing.T) {
+ t.Parallel()
bp := cc.GatherRequiredDepsForTest(android.Android) + `
android_app {
name: "foo",
@@ -440,11 +451,11 @@
ctx, _ := testJavaWithFS(t, bp, fs)
- inputs := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared").Description("link").Implicits
+ inputs := ctx.ModuleForTests(t, "libjni", "android_arm64_armv8-a_sdk_shared").Description("link").Implicits
var crtbeginFound, crtendFound bool
- expectedCrtBegin := ctx.ModuleForTests("crtbegin_so",
+ expectedCrtBegin := ctx.ModuleForTests(t, "crtbegin_so",
"android_arm64_armv8-a_sdk_29").Rule("noAddrSig").Output
- expectedCrtEnd := ctx.ModuleForTests("crtend_so",
+ expectedCrtEnd := ctx.ModuleForTests(t, "crtend_so",
"android_arm64_armv8-a_sdk_29").Rule("noAddrSig").Output
implicits := []string{}
for _, input := range inputs {
@@ -468,6 +479,7 @@
}
func TestUpdatableApps_ErrorIfJniLibDoesntSupportMinSdkVersion(t *testing.T) {
+ t.Parallel()
bp := cc.GatherRequiredDepsForTest(android.Android) + `
android_app {
name: "foo",
@@ -489,6 +501,7 @@
}
func TestUpdatableApps_ErrorIfDepMinSdkVersionIsHigher(t *testing.T) {
+ t.Parallel()
bp := cc.GatherRequiredDepsForTest(android.Android) + `
android_app {
name: "foo",
@@ -520,6 +533,7 @@
}
func TestUpdatableApps_ApplyDefaultUpdatableModuleVersion(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, `
@@ -531,7 +545,7 @@
updatable: true,
}
`)
- foo := result.ModuleForTests("com.android.foo", "android_common").Rule("manifestFixer")
+ foo := result.ModuleForTests(t, "com.android.foo", "android_common").Rule("manifestFixer")
android.AssertStringDoesContain(t,
"com.android.foo: expected manifest fixer to set override-placeholder-version to RELEASE_DEFAULT_UPDATABLE_MODULE_VERSION",
foo.BuildParams.Args["args"],
@@ -540,6 +554,7 @@
}
func TestUpdatableApps_ApplyOverrideApexManifestDefaultVersion(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.FixtureMergeEnv(map[string]string{
@@ -554,7 +569,7 @@
updatable: true,
}
`)
- foo := result.ModuleForTests("com.android.foo", "android_common").Rule("manifestFixer")
+ foo := result.ModuleForTests(t, "com.android.foo", "android_common").Rule("manifestFixer")
android.AssertStringDoesContain(t,
"com.android.foo: expected manifest fixer to set override-placeholder-version to 1234",
foo.BuildParams.Args["args"],
@@ -563,6 +578,7 @@
}
func TestResourceDirs(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
prop string
@@ -599,12 +615,13 @@
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
fs.AddToFixture(),
).RunTestWithBp(t, fmt.Sprintf(bp, testCase.prop))
- module := result.ModuleForTests("foo", "android_common")
+ module := result.ModuleForTests(t, "foo", "android_common")
resourceList := module.MaybeOutput("aapt2/res.list")
var resources []string
@@ -620,6 +637,7 @@
}
func TestLibraryAssets(t *testing.T) {
+ t.Parallel()
bp := `
android_app {
name: "foo",
@@ -714,7 +732,8 @@
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
- m := ctx.ModuleForTests(test.name, "android_common")
+ t.Parallel()
+ m := ctx.ModuleForTests(t, test.name, "android_common")
// Check asset flag in aapt2 link flags
var aapt2link android.TestingBuildParams
@@ -749,6 +768,7 @@
}
func TestAppJavaResources(t *testing.T) {
+ t.Parallel()
bp := `
android_app {
name: "foo",
@@ -766,7 +786,7 @@
ctx := testApp(t, bp)
- foo := ctx.ModuleForTests("foo", "android_common")
+ foo := ctx.ModuleForTests(t, "foo", "android_common")
fooResources := foo.Output("res/foo.jar")
fooDexJar := foo.Output("dex-withres/foo.jar")
fooDexJarAligned := foo.Output("dex-withres-aligned/foo.jar")
@@ -784,7 +804,7 @@
t.Errorf("expected aligned dex jar %q in foo apk inputs %q", w, g)
}
- bar := ctx.ModuleForTests("bar", "android_common")
+ bar := ctx.ModuleForTests(t, "bar", "android_common")
barResources := bar.Output("res/bar.jar")
barApk := bar.Rule("combineApk")
@@ -794,6 +814,7 @@
}
func TestAndroidResourceProcessor(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
appUsesRP bool
@@ -869,15 +890,24 @@
},
appSrcJars: []string{"out/soong/.intermediates/app/android_common/gen/android/R.srcjar"},
appClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
- "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
- "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
+ "out/soong/.intermediates/shared/android_common/turbine/shared.jar",
+ "out/soong/.intermediates/shared_transitive_static/android_common/turbine/shared_transitive_static.jar",
+ "out/soong/.intermediates/direct/android_common/turbine/direct.jar",
+ "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar",
+ "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar",
},
appCombined: []string{
"out/soong/.intermediates/app/android_common/javac/app.jar",
- "out/soong/.intermediates/direct/android_common/combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
+ "out/soong/.intermediates/direct/android_common/javac/direct.jar",
+ "out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar",
+ "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar",
},
directResources: nil,
@@ -890,21 +920,23 @@
directImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
directSrcJars: []string{"out/soong/.intermediates/direct/android_common/gen/android/R.srcjar"},
directClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
- "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
+ "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
},
directCombined: []string{
"out/soong/.intermediates/direct/android_common/javac/direct.jar",
"out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
},
transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"},
transitiveOverlays: nil,
transitiveImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
transitiveSrcJars: []string{"out/soong/.intermediates/transitive/android_common/gen/android/R.srcjar"},
- transitiveClasspath: []string{"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar"},
+ transitiveClasspath: []string{"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar"},
transitiveCombined: nil,
sharedResources: nil,
@@ -918,9 +950,9 @@
},
sharedSrcJars: []string{"out/soong/.intermediates/shared/android_common/gen/android/R.srcjar"},
sharedClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
- "out/soong/.intermediates/shared_transitive_shared/android_common/turbine-combined/shared_transitive_shared.jar",
- "out/soong/.intermediates/shared_transitive_static/android_common/turbine-combined/shared_transitive_static.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
+ "out/soong/.intermediates/shared_transitive_shared/android_common/turbine/shared_transitive_shared.jar",
+ "out/soong/.intermediates/shared_transitive_static/android_common/turbine/shared_transitive_static.jar",
},
sharedCombined: []string{
"out/soong/.intermediates/shared/android_common/javac/shared.jar",
@@ -967,17 +999,26 @@
},
appSrcJars: nil,
appClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
"out/soong/.intermediates/app/android_common/busybox/R.jar",
- "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
- "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
+ "out/soong/.intermediates/shared/android_common/turbine/shared.jar",
+ "out/soong/.intermediates/shared_transitive_static/android_common/turbine/shared_transitive_static.jar",
+ "out/soong/.intermediates/direct/android_common/turbine/direct.jar",
+ "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar",
+ "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar",
},
appCombined: []string{
"out/soong/.intermediates/app/android_common/javac/app.jar",
"out/soong/.intermediates/app/android_common/busybox/R.jar",
- "out/soong/.intermediates/direct/android_common/combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
+ "out/soong/.intermediates/direct/android_common/javac/direct.jar",
+ "out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar",
+ "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar",
},
directResources: nil,
@@ -990,18 +1031,20 @@
},
directSrcJars: nil,
directClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
"out/soong/.intermediates/direct/android_common/busybox/R.jar",
"out/soong/.intermediates/transitive/android_common/busybox/R.jar",
"out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar",
"out/soong/.intermediates/transitive_import/android_common/busybox/R.jar",
- "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar",
+ "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
},
directCombined: []string{
"out/soong/.intermediates/direct/android_common/javac/direct.jar",
"out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
},
transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"},
@@ -1009,7 +1052,7 @@
transitiveImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
transitiveSrcJars: nil,
transitiveClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
"out/soong/.intermediates/transitive/android_common/busybox/R.jar",
},
transitiveCombined: nil,
@@ -1023,12 +1066,12 @@
},
sharedSrcJars: nil,
sharedClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
"out/soong/.intermediates/shared/android_common/busybox/R.jar",
"out/soong/.intermediates/shared_transitive_static/android_common/busybox/R.jar",
"out/soong/.intermediates/shared_transitive_shared/android_common/busybox/R.jar",
- "out/soong/.intermediates/shared_transitive_shared/android_common/turbine-combined/shared_transitive_shared.jar",
- "out/soong/.intermediates/shared_transitive_static/android_common/turbine-combined/shared_transitive_static.jar",
+ "out/soong/.intermediates/shared_transitive_shared/android_common/turbine/shared_transitive_shared.jar",
+ "out/soong/.intermediates/shared_transitive_static/android_common/turbine/shared_transitive_static.jar",
},
sharedCombined: []string{
"out/soong/.intermediates/shared/android_common/javac/shared.jar",
@@ -1072,18 +1115,27 @@
},
appSrcJars: nil,
appClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
// R.jar has to come before direct.jar
"out/soong/.intermediates/app/android_common/busybox/R.jar",
- "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
- "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
+ "out/soong/.intermediates/shared/android_common/turbine/shared.jar",
+ "out/soong/.intermediates/shared_transitive_static/android_common/turbine/shared_transitive_static.jar",
+ "out/soong/.intermediates/direct/android_common/turbine/direct.jar",
+ "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar",
+ "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar",
},
appCombined: []string{
"out/soong/.intermediates/app/android_common/javac/app.jar",
"out/soong/.intermediates/app/android_common/busybox/R.jar",
- "out/soong/.intermediates/direct/android_common/combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
+ "out/soong/.intermediates/direct/android_common/javac/direct.jar",
+ "out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar",
+ "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar",
},
dontVerifyDirect: true,
@@ -1115,15 +1167,24 @@
},
appSrcJars: []string{"out/soong/.intermediates/app/android_common/gen/android/R.srcjar"},
appClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
- "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
- "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
+ "out/soong/.intermediates/shared/android_common/turbine/shared.jar",
+ "out/soong/.intermediates/shared_transitive_static/android_common/turbine/shared_transitive_static.jar",
+ "out/soong/.intermediates/direct/android_common/turbine/direct.jar",
+ "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar",
+ "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar",
},
appCombined: []string{
"out/soong/.intermediates/app/android_common/javac/app.jar",
- "out/soong/.intermediates/direct/android_common/combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
+ "out/soong/.intermediates/direct/android_common/javac/direct.jar",
+ "out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar",
+ "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar",
},
directResources: nil,
@@ -1136,17 +1197,19 @@
},
directSrcJars: nil,
directClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
"out/soong/.intermediates/direct/android_common/busybox/R.jar",
"out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar",
"out/soong/.intermediates/transitive_import/android_common/busybox/R.jar",
- "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar",
+ "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
},
directCombined: []string{
"out/soong/.intermediates/direct/android_common/javac/direct.jar",
"out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
},
dontVerifyTransitive: true,
@@ -1177,15 +1240,24 @@
},
appSrcJars: []string{"out/soong/.intermediates/app/android_common/gen/android/R.srcjar"},
appClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
- "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
- "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
+ "out/soong/.intermediates/shared/android_common/turbine/shared.jar",
+ "out/soong/.intermediates/shared_transitive_static/android_common/turbine/shared_transitive_static.jar",
+ "out/soong/.intermediates/direct/android_common/turbine/direct.jar",
+ "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar",
+ "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar",
},
appCombined: []string{
"out/soong/.intermediates/app/android_common/javac/app.jar",
- "out/soong/.intermediates/direct/android_common/combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
+ "out/soong/.intermediates/direct/android_common/javac/direct.jar",
+ "out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar",
+ "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar",
},
directResources: nil,
@@ -1198,14 +1270,16 @@
directImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
directSrcJars: []string{"out/soong/.intermediates/direct/android_common/gen/android/R.srcjar"},
directClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
- "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
+ "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
},
directCombined: []string{
"out/soong/.intermediates/direct/android_common/javac/direct.jar",
"out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar",
},
transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"},
@@ -1213,7 +1287,7 @@
transitiveImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
transitiveSrcJars: nil,
transitiveClasspath: []string{
- "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar",
"out/soong/.intermediates/transitive/android_common/busybox/R.jar",
},
transitiveCombined: nil,
@@ -1226,6 +1300,7 @@
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
bp := fmt.Sprintf(`
android_app {
name: "app",
@@ -1333,7 +1408,7 @@
}
getAaptInfo := func(moduleName string) (aaptInfo aaptInfo) {
- mod := result.ModuleForTests(moduleName, "android_common")
+ mod := result.ModuleForTests(t, moduleName, "android_common")
resourceListRule := mod.MaybeOutput("aapt2/res.list")
overlayListRule := mod.MaybeOutput("aapt2/overlay.list")
aaptRule := mod.Rule("aapt2Link")
@@ -1422,6 +1497,7 @@
}
func TestAndroidResourceOverlays(t *testing.T) {
+ t.Parallel()
type moduleAndVariant struct {
module string
variant string
@@ -1460,7 +1536,6 @@
"device/vendor/blah/overlay/bar/res/values/strings.xml",
},
{"lib", "android_common"}: {
- "out/soong/.intermediates/lib2/android_common/package-res.apk",
"lib/res/res/values/strings.xml",
"device/vendor/blah/overlay/lib/res/values/strings.xml",
},
@@ -1495,12 +1570,10 @@
"device/vendor/blah/overlay/bar/res/values/strings.xml",
},
{"lib", "android_common"}: {
- "out/soong/.intermediates/lib2/android_common/package-res.apk",
"lib/res/res/values/strings.xml",
"device/vendor/blah/overlay/lib/res/values/strings.xml",
},
{"lib", "android_common_rro"}: {
- "out/soong/.intermediates/lib2/android_common_rro/package-res.apk",
"lib/res/res/values/strings.xml",
},
},
@@ -1540,7 +1613,6 @@
},
{"bar", "android_common"}: {"device/vendor/blah/static_overlay/bar/res/values/strings.xml"},
{"lib", "android_common"}: {
- "out/soong/.intermediates/lib2/android_common/package-res.apk",
"lib/res/res/values/strings.xml",
},
},
@@ -1618,6 +1690,7 @@
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
fs.AddToFixture(),
@@ -1649,7 +1722,7 @@
}
getResources := func(moduleName, variantName string) (resourceFiles, overlayFiles, rroDirs []string) {
- module := result.ModuleForTests(moduleName, variantName)
+ module := result.ModuleForTests(t, moduleName, variantName)
resourceList := module.MaybeOutput("aapt2/res.list")
if resourceList.Rule != nil {
resourceFiles = resourceListToFiles(module, android.PathsRelativeToTop(resourceList.Inputs))
@@ -1708,7 +1781,7 @@
}
func checkSdkVersion(t *testing.T, result *android.TestResult, expectedSdkVersion string) {
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
link := foo.Output("package-res.apk")
linkFlags := strings.Split(link.Args["flags"], " ")
min := android.IndexList("--min-sdk-version", linkFlags)
@@ -1727,6 +1800,7 @@
}
func TestAppSdkVersion(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
sdkVersion string
@@ -1794,6 +1868,7 @@
for _, moduleType := range []string{"android_app", "android_library"} {
for _, test := range testCases {
t.Run(moduleType+" "+test.name, func(t *testing.T) {
+ t.Parallel()
platformApiProp := ""
if test.platformApis {
platformApiProp = "platform_apis: true,"
@@ -1830,6 +1905,7 @@
}
func TestVendorAppSdkVersion(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
sdkVersion string
@@ -1872,6 +1948,7 @@
for _, sdkKind := range []string{"", "system_"} {
for _, test := range testCases {
t.Run(moduleType+" "+test.name, func(t *testing.T) {
+ t.Parallel()
bp := fmt.Sprintf(`%s {
name: "foo",
srcs: ["a.java"],
@@ -1903,6 +1980,7 @@
}
func TestJNIABI(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
cc_library {
name: "libjni",
@@ -1959,7 +2037,8 @@
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
- app := ctx.ModuleForTests(test.name, "android_common")
+ t.Parallel()
+ app := ctx.ModuleForTests(t, test.name, "android_common")
jniLibZip := app.Output("jnilibs.zip")
var abis []string
args := strings.Fields(jniLibZip.Args["jarArgs"])
@@ -1977,6 +2056,7 @@
}
func TestAppSdkVersionByPartition(t *testing.T) {
+ t.Parallel()
testJavaError(t, "sdk_version must have a value when the module is located at vendor or product", `
android_app {
name: "foo",
@@ -2021,6 +2101,7 @@
}
func TestJNIPackaging(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
cc_library {
name: "libjni",
@@ -2092,7 +2173,8 @@
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
- app := ctx.ModuleForTests(test.name, "android_common")
+ t.Parallel()
+ app := ctx.ModuleForTests(t, test.name, "android_common")
jniLibZip := app.MaybeOutput("jnilibs.zip")
if g, w := (jniLibZip.Rule != nil), test.packaged; g != w {
t.Errorf("expected jni packaged %v, got %v", w, g)
@@ -2112,6 +2194,7 @@
}
func TestJNISDK(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
cc_library {
name: "libjni",
@@ -2173,16 +2256,17 @@
{name: "app_vendor", vendorJNI: true},
}
- platformJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_shared").
+ platformJNI := ctx.ModuleForTests(t, "libjni", "android_arm64_armv8-a_shared").
Output("libjni.so").Output.String()
- sdkJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared").
+ sdkJNI := ctx.ModuleForTests(t, "libjni", "android_arm64_armv8-a_sdk_shared").
Output("libjni.so").Output.String()
- vendorJNI := ctx.ModuleForTests("libvendorjni", "android_vendor_arm64_armv8-a_shared").
+ vendorJNI := ctx.ModuleForTests(t, "libvendorjni", "android_vendor_arm64_armv8-a_shared").
Output("libvendorjni.so").Output.String()
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
- app := ctx.ModuleForTests(test.name, "android_common")
+ t.Parallel()
+ app := ctx.ModuleForTests(t, test.name, "android_common")
jniLibZip := app.MaybeOutput("jnilibs.zip")
if len(jniLibZip.Implicits) != 1 {
@@ -2207,6 +2291,7 @@
}
t.Run("jni_uses_platform_apis_error", func(t *testing.T) {
+ t.Parallel()
testJavaError(t, `jni_uses_platform_apis: can only be set for modules that set sdk_version`, `
android_test {
name: "app_platform",
@@ -2217,6 +2302,7 @@
})
t.Run("jni_uses_sdk_apis_error", func(t *testing.T) {
+ t.Parallel()
testJavaError(t, `jni_uses_sdk_apis: can only be set for modules that do not set sdk_version`, `
android_test {
name: "app_sdk",
@@ -2229,6 +2315,7 @@
}
func TestCertificates(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
bp string
@@ -2366,6 +2453,7 @@
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
@@ -2381,7 +2469,7 @@
}),
).RunTestWithBp(t, test.bp)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
certificate := foo.Module().(*AndroidApp).certificate
android.AssertPathRelativeToTopEquals(t, "certificates key", test.expectedCertificate+".pk8", certificate.Key)
@@ -2403,6 +2491,7 @@
}
func TestRequestV4SigningFlag(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
bp string
@@ -2447,11 +2536,12 @@
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, test.bp)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
signapk := foo.Output("foo.apk")
signFlags := signapk.Args["flags"]
@@ -2461,6 +2551,7 @@
}
func TestPackageNameOverride(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
bp string
@@ -2479,7 +2570,7 @@
packageNameOverride: "",
expected: []string{
"out/soong/.intermediates/foo/android_common/foo.apk",
- "out/soong/target/product/test_device/system/app/foo/foo.apk",
+ "out/target/product/test_device/system/app/foo/foo.apk",
},
},
{
@@ -2495,7 +2586,7 @@
expected: []string{
// The package apk should be still be the original name for test dependencies.
"out/soong/.intermediates/foo/android_common/bar.apk",
- "out/soong/target/product/test_device/system/app/bar/bar.apk",
+ "out/target/product/test_device/system/app/bar/bar.apk",
},
},
{
@@ -2511,13 +2602,14 @@
packageNameOverride: "",
expected: []string{
"out/soong/.intermediates/foo/android_common/bar.apk",
- "out/soong/target/product/test_device/system/app/bar/bar.apk",
+ "out/target/product/test_device/system/app/bar/bar.apk",
},
},
}
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
@@ -2527,7 +2619,7 @@
}),
).RunTestWithBp(t, test.bp)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
outSoongDir := result.Config.SoongOutDir()
@@ -2546,6 +2638,7 @@
}
func TestInstrumentationTargetOverridden(t *testing.T) {
+ t.Parallel()
bp := `
android_app {
name: "foo",
@@ -2567,7 +2660,7 @@
}),
).RunTestWithBp(t, bp)
- bar := result.ModuleForTests("bar", "android_common")
+ bar := result.ModuleForTests(t, "bar", "android_common")
res := bar.Output("package-res.apk")
aapt2Flags := res.Args["flags"]
e := "--rename-instrumentation-target-package org.dandroid.bp"
@@ -2577,6 +2670,7 @@
}
func TestOverrideAndroidApp(t *testing.T) {
+ t.Parallel()
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(
t, `
android_app {
@@ -2654,7 +2748,7 @@
name: "foo",
moduleName: "foo",
variantName: "android_common",
- apkPath: "out/soong/target/product/test_device/system/app/foo/foo.apk",
+ apkPath: "out/target/product/test_device/system/app/foo/foo.apk",
certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
certSigningFlags: "",
overrides: []string{"qux"},
@@ -2666,7 +2760,7 @@
name: "foo",
moduleName: "bar",
variantName: "android_common_bar",
- apkPath: "out/soong/target/product/test_device/system/app/bar/bar.apk",
+ apkPath: "out/target/product/test_device/system/app/bar/bar.apk",
certFlag: "cert/new_cert.x509.pem cert/new_cert.pk8",
certSigningFlags: "--lineage lineage.bin --rotation-min-sdk-version 32",
overrides: []string{"qux", "foo"},
@@ -2678,7 +2772,7 @@
name: "foo",
moduleName: "baz",
variantName: "android_common_baz",
- apkPath: "out/soong/target/product/test_device/system/app/baz/baz.apk",
+ apkPath: "out/target/product/test_device/system/app/baz/baz.apk",
certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
certSigningFlags: "",
overrides: []string{"qux", "foo"},
@@ -2690,7 +2784,7 @@
name: "foo",
moduleName: "baz_no_rename_resources",
variantName: "android_common_baz_no_rename_resources",
- apkPath: "out/soong/target/product/test_device/system/app/baz_no_rename_resources/baz_no_rename_resources.apk",
+ apkPath: "out/target/product/test_device/system/app/baz_no_rename_resources/baz_no_rename_resources.apk",
certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
certSigningFlags: "",
overrides: []string{"qux", "foo"},
@@ -2702,7 +2796,7 @@
name: "foo_no_rename_resources",
moduleName: "baz_base_no_rename_resources",
variantName: "android_common_baz_base_no_rename_resources",
- apkPath: "out/soong/target/product/test_device/system/app/baz_base_no_rename_resources/baz_base_no_rename_resources.apk",
+ apkPath: "out/target/product/test_device/system/app/baz_base_no_rename_resources/baz_base_no_rename_resources.apk",
certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
certSigningFlags: "",
overrides: []string{"qux", "foo_no_rename_resources"},
@@ -2714,7 +2808,7 @@
name: "foo_no_rename_resources",
moduleName: "baz_override_base_rename_resources",
variantName: "android_common_baz_override_base_rename_resources",
- apkPath: "out/soong/target/product/test_device/system/app/baz_override_base_rename_resources/baz_override_base_rename_resources.apk",
+ apkPath: "out/target/product/test_device/system/app/baz_override_base_rename_resources/baz_override_base_rename_resources.apk",
certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
certSigningFlags: "",
overrides: []string{"qux", "foo_no_rename_resources"},
@@ -2724,7 +2818,7 @@
},
}
for _, expected := range expectedVariants {
- variant := result.ModuleForTests(expected.name, expected.variantName)
+ variant := result.ModuleForTests(t, expected.name, expected.variantName)
// Check the final apk name
variant.Output(expected.apkPath)
@@ -2759,6 +2853,7 @@
}
func TestOverrideAndroidAppOverrides(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(
t, `
android_app {
@@ -2808,7 +2903,7 @@
},
}
for _, expected := range expectedVariants {
- variant := ctx.ModuleForTests(expected.name, expected.variantName)
+ variant := ctx.ModuleForTests(t, expected.name, expected.variantName)
// Check if the overrides field values are correctly aggregated.
mod := variant.Module().(*AndroidApp)
@@ -2817,6 +2912,7 @@
}
func TestOverrideAndroidAppWithPrebuilt(t *testing.T) {
+ t.Parallel()
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(
t, `
android_app {
@@ -2839,19 +2935,20 @@
`)
// An app that has an override that also has a prebuilt should not be hidden.
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
if foo.Module().IsHideFromMake() {
t.Errorf("expected foo to have HideFromMake false")
}
// An override that also has a prebuilt should be hidden.
- barOverride := result.ModuleForTests("foo", "android_common_bar")
+ barOverride := result.ModuleForTests(t, "foo", "android_common_bar")
if !barOverride.Module().IsHideFromMake() {
t.Errorf("expected bar override variant of foo to have HideFromMake true")
}
}
func TestOverrideAndroidAppStem(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_app {
name: "foo",
@@ -2891,41 +2988,42 @@
{
moduleName: "foo",
variantName: "android_common",
- apkPath: "out/soong/target/product/test_device/system/app/foo/foo.apk",
+ apkPath: "out/target/product/test_device/system/app/foo/foo.apk",
},
{
moduleName: "foo",
variantName: "android_common_bar",
- apkPath: "out/soong/target/product/test_device/system/app/bar/bar.apk",
+ apkPath: "out/target/product/test_device/system/app/bar/bar.apk",
},
{
moduleName: "foo",
variantName: "android_common_baz",
- apkPath: "out/soong/target/product/test_device/system/app/baz_stem/baz_stem.apk",
+ apkPath: "out/target/product/test_device/system/app/baz_stem/baz_stem.apk",
},
{
moduleName: "foo2",
variantName: "android_common",
- apkPath: "out/soong/target/product/test_device/system/app/foo2_stem/foo2_stem.apk",
+ apkPath: "out/target/product/test_device/system/app/foo2_stem/foo2_stem.apk",
},
{
moduleName: "foo2",
variantName: "android_common_bar2",
// Note that this may cause the duplicate output error.
- apkPath: "out/soong/target/product/test_device/system/app/foo2_stem/foo2_stem.apk",
+ apkPath: "out/target/product/test_device/system/app/foo2_stem/foo2_stem.apk",
},
{
moduleName: "foo2",
variantName: "android_common_baz2",
- apkPath: "out/soong/target/product/test_device/system/app/baz2_stem/baz2_stem.apk",
+ apkPath: "out/target/product/test_device/system/app/baz2_stem/baz2_stem.apk",
},
} {
- variant := ctx.ModuleForTests(expected.moduleName, expected.variantName)
+ variant := ctx.ModuleForTests(t, expected.moduleName, expected.variantName)
variant.Output(expected.apkPath)
}
}
func TestOverrideAndroidAppDependency(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_app {
name: "foo",
@@ -2953,15 +3051,15 @@
`)
// Verify baz, which depends on the overridden module foo, has the correct classpath javac arg.
- javac := ctx.ModuleForTests("baz", "android_common").Rule("javac")
- fooTurbine := "out/soong/.intermediates/foo/android_common/turbine-combined/foo.jar"
+ javac := ctx.ModuleForTests(t, "baz", "android_common").Rule("javac")
+ fooTurbine := "out/soong/.intermediates/foo/android_common/turbine/foo.jar"
if !strings.Contains(javac.Args["classpath"], fooTurbine) {
t.Errorf("baz classpath %v does not contain %q", javac.Args["classpath"], fooTurbine)
}
// Verify qux, which depends on the overriding module bar, has the correct classpath javac arg.
- javac = ctx.ModuleForTests("qux", "android_common").Rule("javac")
- barTurbine := "out/soong/.intermediates/foo/android_common_bar/turbine-combined/foo.jar"
+ javac = ctx.ModuleForTests(t, "qux", "android_common").Rule("javac")
+ barTurbine := "out/soong/.intermediates/foo/android_common_bar/turbine/foo.jar"
if !strings.Contains(javac.Args["classpath"], barTurbine) {
t.Errorf("qux classpath %v does not contain %q", javac.Args["classpath"], barTurbine)
}
@@ -3024,10 +3122,10 @@
},
}
for _, expected := range expectedVariants {
- variant := ctx.ModuleForTests("foo_test", expected.variantName)
+ variant := ctx.ModuleForTests(t, "foo_test", expected.variantName)
// Check the final apk name
- variant.Output("out/soong" + expected.apkPath)
+ variant.Output("out" + expected.apkPath)
// Check if the overrides field values are correctly aggregated.
mod := variant.Module().(*AndroidTest)
@@ -3038,7 +3136,7 @@
// Check if javac classpath has the correct jar file path. This checks instrumentation_for overrides.
javac := variant.Rule("javac")
- turbine := filepath.Join("out", "soong", ".intermediates", "foo", expected.targetVariant, "turbine-combined", "foo.jar")
+ turbine := filepath.Join("out", "soong", ".intermediates", "foo", expected.targetVariant, "turbine", "foo.jar")
if !strings.Contains(javac.Args["classpath"], turbine) {
t.Errorf("classpath %q does not contain %q", javac.Args["classpath"], turbine)
}
@@ -3115,7 +3213,7 @@
}
for _, test := range testCases {
- variant := ctx.ModuleForTests(test.moduleName, test.variantName)
+ variant := ctx.ModuleForTests(t, test.moduleName, test.variantName)
params := variant.MaybeOutput("test_config_fixer/AndroidTest.xml")
if len(test.expectedFlags) > 0 {
@@ -3161,6 +3259,7 @@
}
func TestStl(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
cc_library {
name: "libjni",
@@ -3203,7 +3302,8 @@
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
- app := ctx.ModuleForTests(test.name, "android_common")
+ t.Parallel()
+ app := ctx.ModuleForTests(t, test.name, "android_common")
jniLibZip := app.Output("jnilibs.zip")
var jnis []string
args := strings.Fields(jniLibZip.Args["jarArgs"])
@@ -3380,8 +3480,8 @@
}),
).RunTestWithBp(t, bp)
- app := result.ModuleForTests("app", "android_common")
- prebuilt := result.ModuleForTests("prebuilt", "android_common")
+ app := result.ModuleForTests(t, "app", "android_common")
+ prebuilt := result.ModuleForTests(t, "prebuilt", "android_common")
// Test that implicit dependencies on java_sdk_library instances are passed to the manifest.
// These also include explicit `uses_libs`/`optional_uses_libs` entries, as they may be
@@ -3433,6 +3533,7 @@
}
func TestDexpreoptBcp(t *testing.T) {
+ t.Parallel()
bp := `
java_sdk_library {
name: "foo",
@@ -3475,6 +3576,7 @@
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -3484,7 +3586,7 @@
dexpreopt.FixtureSetPreoptWithUpdatableBcp(test.with),
).RunTestWithBp(t, bp)
- app := result.ModuleForTests("app", "android_common")
+ app := result.ModuleForTests(t, "app", "android_common")
cmd := app.Rule("dexpreopt").RuleParams.Command
bcp := " -Xbootclasspath-locations:" + test.expect + " " // space at the end matters
android.AssertStringDoesContain(t, "dexpreopt app bcp", cmd, bcp)
@@ -3493,6 +3595,7 @@
}
func TestCodelessApp(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
bp string
@@ -3557,9 +3660,10 @@
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
+ t.Parallel()
ctx := testApp(t, test.bp)
- foo := ctx.ModuleForTests("foo", "android_common")
+ foo := ctx.ModuleForTests(t, "foo", "android_common")
manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
if strings.Contains(manifestFixerArgs, "--has-no-code") != test.noCode {
t.Errorf("unexpected manifest_fixer args: %q", manifestFixerArgs)
@@ -3569,6 +3673,7 @@
}
func TestUncompressDex(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
bp string
@@ -3656,7 +3761,7 @@
}),
).RunTestWithBp(t, bp)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
dex := foo.Rule("r8")
uncompressedInDexJar := strings.Contains(dex.Args["zipFlags"], "-L 0")
aligned := foo.MaybeRule("zipalign").Rule != nil
@@ -3668,10 +3773,13 @@
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
+ t.Parallel()
t.Run("platform", func(t *testing.T) {
+ t.Parallel()
test(t, tt.bp, tt.uncompressedPlatform, false)
})
t.Run("unbundled", func(t *testing.T) {
+ t.Parallel()
test(t, tt.bp, tt.uncompressedUnbundled, true)
})
})
@@ -3693,6 +3801,7 @@
}
func TestExportedProguardFlagFiles(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
android_app {
name: "foo",
@@ -3738,7 +3847,7 @@
`)
- m := ctx.ModuleForTests("foo", "android_common")
+ m := ctx.ModuleForTests(t, "foo", "android_common")
r8 := m.Rule("java.r8")
implicits := r8.Implicits.RelativeToTop().Strings()
android.AssertStringListContains(t, "r8 implicits", implicits, "lib1proguard.cfg")
@@ -3754,6 +3863,7 @@
}
func TestTargetSdkVersionManifestFixer(t *testing.T) {
+ t.Parallel()
platform_sdk_codename := "Tiramisu"
platform_sdk_version := 33
testCases := []struct {
@@ -3806,43 +3916,47 @@
},
}
for _, testCase := range testCases {
- targetSdkVersionTemplate := ""
- if testCase.targetSdkVersionInBp != "" {
- targetSdkVersionTemplate = fmt.Sprintf(`target_sdk_version: "%s",`, testCase.targetSdkVersionInBp)
- }
- bp := fmt.Sprintf(`
+ t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
+ targetSdkVersionTemplate := ""
+ if testCase.targetSdkVersionInBp != "" {
+ targetSdkVersionTemplate = fmt.Sprintf(`target_sdk_version: "%s",`, testCase.targetSdkVersionInBp)
+ }
+ bp := fmt.Sprintf(`
android_app {
name: "foo",
sdk_version: "current",
%s
}
`, targetSdkVersionTemplate)
- fixture := android.GroupFixturePreparers(
- prepareForJavaTest,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- if testCase.platformSdkFinal {
- variables.Platform_sdk_final = proptools.BoolPtr(true)
- }
- // explicitly set platform_sdk_codename to make the test deterministic
- variables.Platform_sdk_codename = &platform_sdk_codename
- variables.Platform_sdk_version = &platform_sdk_version
- variables.Platform_version_active_codenames = []string{platform_sdk_codename}
- // create a non-empty list if unbundledBuild==true
- if testCase.unbundledBuild {
- variables.Unbundled_build_apps = []string{"apex_a", "apex_b"}
- }
- }),
- )
+ fixture := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ if testCase.platformSdkFinal {
+ variables.Platform_sdk_final = proptools.BoolPtr(true)
+ }
+ // explicitly set platform_sdk_codename to make the test deterministic
+ variables.Platform_sdk_codename = &platform_sdk_codename
+ variables.Platform_sdk_version = &platform_sdk_version
+ variables.Platform_version_active_codenames = []string{platform_sdk_codename}
+ // create a non-empty list if unbundledBuild==true
+ if testCase.unbundledBuild {
+ variables.Unbundled_build_apps = []string{"apex_a", "apex_b"}
+ }
+ }),
+ )
- result := fixture.RunTestWithBp(t, bp)
- foo := result.ModuleForTests("foo", "android_common")
+ result := fixture.RunTestWithBp(t, bp)
+ foo := result.ModuleForTests(t, "foo", "android_common")
- manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
- android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
+ manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
+ android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
+ })
}
}
func TestDefaultAppTargetSdkVersionForUpdatableModules(t *testing.T) {
+ t.Parallel()
platform_sdk_codename := "Tiramisu"
platform_sdk_version := 33
testCases := []struct {
@@ -3898,11 +4012,13 @@
},
}
for _, testCase := range testCases {
- targetSdkVersionTemplate := ""
- if testCase.targetSdkVersionInBp != nil {
- targetSdkVersionTemplate = fmt.Sprintf(`target_sdk_version: "%s",`, *testCase.targetSdkVersionInBp)
- }
- bp := fmt.Sprintf(`
+ t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
+ targetSdkVersionTemplate := ""
+ if testCase.targetSdkVersionInBp != nil {
+ targetSdkVersionTemplate = fmt.Sprintf(`target_sdk_version: "%s",`, *testCase.targetSdkVersionInBp)
+ }
+ bp := fmt.Sprintf(`
android_app {
name: "foo",
sdk_version: "current",
@@ -3913,30 +4029,32 @@
}
`, targetSdkVersionTemplate, testCase.updatable, testCase.updatable) // enforce default target sdk version if app is updatable
- fixture := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- android.PrepareForTestWithAllowMissingDependencies,
- android.PrepareForTestWithAndroidMk,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- // explicitly set following platform variables to make the test deterministic
- variables.Platform_sdk_final = &testCase.platform_sdk_final
- variables.Platform_sdk_version = &platform_sdk_version
- variables.Platform_sdk_codename = &platform_sdk_codename
- variables.Platform_version_active_codenames = []string{platform_sdk_codename}
- variables.Unbundled_build = proptools.BoolPtr(true)
- variables.Unbundled_build_apps = []string{"sampleModule"}
- }),
- )
+ fixture := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ android.PrepareForTestWithAllowMissingDependencies,
+ android.PrepareForTestWithAndroidMk,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ // explicitly set following platform variables to make the test deterministic
+ variables.Platform_sdk_final = &testCase.platform_sdk_final
+ variables.Platform_sdk_version = &platform_sdk_version
+ variables.Platform_sdk_codename = &platform_sdk_codename
+ variables.Platform_version_active_codenames = []string{platform_sdk_codename}
+ variables.Unbundled_build = proptools.BoolPtr(true)
+ variables.Unbundled_build_apps = []string{"sampleModule"}
+ }),
+ )
- result := fixture.RunTestWithBp(t, bp)
- foo := result.ModuleForTests("foo", "android_common")
+ result := fixture.RunTestWithBp(t, bp)
+ foo := result.ModuleForTests(t, "foo", "android_common")
- manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
- android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+*testCase.targetSdkVersionExpected)
+ manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
+ android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+*testCase.targetSdkVersionExpected)
+ })
}
}
func TestEnforceDefaultAppTargetSdkVersionFlag(t *testing.T) {
+ t.Parallel()
platform_sdk_codename := "Tiramisu"
platform_sdk_version := 33
testCases := []struct {
@@ -3981,8 +4099,10 @@
},
}
for _, testCase := range testCases {
- errExpected := testCase.expectedError != ""
- bp := fmt.Sprintf(`
+ t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
+ errExpected := testCase.expectedError != ""
+ bp := fmt.Sprintf(`
android_app {
name: "foo",
enforce_default_target_sdk_version: %t,
@@ -3993,35 +4113,37 @@
}
`, testCase.enforceDefaultTargetSdkVersion, testCase.targetSdkVersionInBp, testCase.updatable)
- fixture := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- android.PrepareForTestWithAllowMissingDependencies,
- android.PrepareForTestWithAndroidMk,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- // explicitly set following platform variables to make the test deterministic
- variables.Platform_sdk_final = &testCase.platform_sdk_final
- variables.Platform_sdk_version = &platform_sdk_version
- variables.Platform_sdk_codename = &platform_sdk_codename
- variables.Unbundled_build = proptools.BoolPtr(true)
- variables.Unbundled_build_apps = []string{"sampleModule"}
- }),
- )
+ fixture := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ android.PrepareForTestWithAllowMissingDependencies,
+ android.PrepareForTestWithAndroidMk,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ // explicitly set following platform variables to make the test deterministic
+ variables.Platform_sdk_final = &testCase.platform_sdk_final
+ variables.Platform_sdk_version = &platform_sdk_version
+ variables.Platform_sdk_codename = &platform_sdk_codename
+ variables.Unbundled_build = proptools.BoolPtr(true)
+ variables.Unbundled_build_apps = []string{"sampleModule"}
+ }),
+ )
- errorHandler := android.FixtureExpectsNoErrors
- if errExpected {
- errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.expectedError)
- }
- result := fixture.ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, bp)
+ errorHandler := android.FixtureExpectsNoErrors
+ if errExpected {
+ errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.expectedError)
+ }
+ result := fixture.ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, bp)
- if !errExpected {
- foo := result.ModuleForTests("foo", "android_common")
- manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
- android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
- }
+ if !errExpected {
+ foo := result.ModuleForTests(t, "foo", "android_common")
+ manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
+ android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
+ }
+ })
}
}
func TestEnforceDefaultAppTargetSdkVersionFlagForTests(t *testing.T) {
+ t.Parallel()
platform_sdk_codename := "Tiramisu"
platform_sdk_version := 33
testCases := []struct {
@@ -4054,8 +4176,10 @@
},
}
for _, testCase := range testCases {
- errExpected := testCase.expectedError != ""
- bp := fmt.Sprintf(`
+ t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
+ errExpected := testCase.expectedError != ""
+ bp := fmt.Sprintf(`
android_test {
name: "foo",
enforce_default_target_sdk_version: %t,
@@ -4064,35 +4188,37 @@
}
`, testCase.enforceDefaultTargetSdkVersion, testCase.targetSdkVersionInBp)
- fixture := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- android.PrepareForTestWithAllowMissingDependencies,
- android.PrepareForTestWithAndroidMk,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- // explicitly set following platform variables to make the test deterministic
- variables.Platform_sdk_final = &testCase.platform_sdk_final
- variables.Platform_sdk_version = &platform_sdk_version
- variables.Platform_sdk_codename = &platform_sdk_codename
- variables.Unbundled_build = proptools.BoolPtr(true)
- variables.Unbundled_build_apps = []string{"sampleModule"}
- }),
- )
+ fixture := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ android.PrepareForTestWithAllowMissingDependencies,
+ android.PrepareForTestWithAndroidMk,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ // explicitly set following platform variables to make the test deterministic
+ variables.Platform_sdk_final = &testCase.platform_sdk_final
+ variables.Platform_sdk_version = &platform_sdk_version
+ variables.Platform_sdk_codename = &platform_sdk_codename
+ variables.Unbundled_build = proptools.BoolPtr(true)
+ variables.Unbundled_build_apps = []string{"sampleModule"}
+ }),
+ )
- errorHandler := android.FixtureExpectsNoErrors
- if errExpected {
- errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.expectedError)
- }
- result := fixture.ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, bp)
+ errorHandler := android.FixtureExpectsNoErrors
+ if errExpected {
+ errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.expectedError)
+ }
+ result := fixture.ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, bp)
- if !errExpected {
- foo := result.ModuleForTests("foo", "android_common")
- manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
- android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
- }
+ if !errExpected {
+ foo := result.ModuleForTests(t, "foo", "android_common")
+ manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
+ android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
+ }
+ })
}
}
func TestAppMissingCertificateAllowMissingDependencies(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.PrepareForTestWithAllowMissingDependencies,
@@ -4113,7 +4239,7 @@
sdk_version: "current",
}`)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
fooApk := foo.Output("foo.apk")
if fooApk.Rule != android.ErrorRule {
t.Fatalf("expected ErrorRule for foo.apk, got %s", fooApk.Rule.String())
@@ -4122,6 +4248,7 @@
}
func TestAppIncludesJniPackages(t *testing.T) {
+ t.Parallel()
ctx := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, `
@@ -4184,7 +4311,8 @@
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
- app := ctx.ModuleForTests(tc.name, "android_common")
+ t.Parallel()
+ app := ctx.ModuleForTests(t, tc.name, "android_common")
outputFile := "jnilibs.zip"
jniOutputLibZip := app.MaybeOutput(outputFile)
@@ -4208,6 +4336,7 @@
}
func TestTargetSdkVersionMtsTests(t *testing.T) {
+ t.Parallel()
platformSdkCodename := "Tiramisu"
android_test := "android_test"
android_test_helper_app := "android_test_helper_app"
@@ -4263,14 +4392,18 @@
}),
)
for _, testCase := range testCases {
- result := fixture.RunTestWithBp(t, fmt.Sprintf(bpTemplate, testCase.moduleType, testCase.targetSdkVersionInBp, testCase.testSuites))
- mytest := result.ModuleForTests("mytest", "android_common")
- manifestFixerArgs := mytest.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
- android.AssertStringDoesContain(t, testCase.desc, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
+ t.Run(testCase.desc, func(t *testing.T) {
+ t.Parallel()
+ result := fixture.RunTestWithBp(t, fmt.Sprintf(bpTemplate, testCase.moduleType, testCase.targetSdkVersionInBp, testCase.testSuites))
+ mytest := result.ModuleForTests(t, "mytest", "android_common")
+ manifestFixerArgs := mytest.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
+ android.AssertStringDoesContain(t, testCase.desc, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
+ })
}
}
func TestPrivappAllowlist(t *testing.T) {
+ t.Parallel()
testJavaError(t, "privileged must be set in order to use privapp_allowlist", `
android_app {
name: "foo",
@@ -4296,8 +4429,8 @@
}
`,
)
- app := result.ModuleForTests("foo", "android_common")
- overrideApp := result.ModuleForTests("foo", "android_common_bar")
+ app := result.ModuleForTests(t, "foo", "android_common")
+ overrideApp := result.ModuleForTests(t, "foo", "android_common_bar")
// verify that privapp allowlist is created for override apps
overrideApp.Output("out/soong/.intermediates/foo/android_common_bar/privapp_allowlist_com.google.android.foo.xml")
@@ -4308,11 +4441,12 @@
}
// verify that permissions are copied to device
- app.Output("out/soong/target/product/test_device/system/etc/permissions/foo.xml")
- overrideApp.Output("out/soong/target/product/test_device/system/etc/permissions/bar.xml")
+ app.Output("out/target/product/test_device/system/etc/permissions/foo.xml")
+ overrideApp.Output("out/target/product/test_device/system/etc/permissions/bar.xml")
}
func TestPrivappAllowlistAndroidMk(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.PrepareForTestWithAndroidMk,
@@ -4333,8 +4467,8 @@
}
`,
)
- baseApp := result.ModuleForTests("foo", "android_common")
- overrideApp := result.ModuleForTests("foo", "android_common_bar")
+ baseApp := result.ModuleForTests(t, "foo", "android_common")
+ overrideApp := result.ModuleForTests(t, "foo", "android_common_bar")
baseAndroidApp := baseApp.Module().(*AndroidApp)
baseEntries := android.AndroidMkEntriesForTest(t, result.TestContext, baseAndroidApp)[0]
@@ -4392,6 +4526,7 @@
}
func TestAppFlagsPackages(t *testing.T) {
+ t.Parallel()
ctx := android.GroupFixturePreparers(
prepareForJavaTest,
android.FixtureMergeMockFs(
@@ -4429,7 +4564,7 @@
}
`)
- foo := ctx.ModuleForTests("foo", "android_common")
+ foo := ctx.ModuleForTests(t, "foo", "android_common")
// android_app module depends on aconfig_declarations listed in flags_packages
android.AssertBoolEquals(t, "foo expected to depend on bar", true,
@@ -4456,6 +4591,7 @@
}
func TestAppFlagsPackagesPropagation(t *testing.T) {
+ t.Parallel()
ctx := testApp(t, `
aconfig_declarations {
name: "foo",
@@ -4513,7 +4649,7 @@
}
`)
- bazApp := ctx.ModuleForTests("baz_app", "android_common")
+ bazApp := ctx.ModuleForTests(t, "baz_app", "android_common")
// android_app module depends on aconfig_declarations listed in flags_packages
// and that of static libs, but not libs
@@ -4533,6 +4669,7 @@
// Test that dexpreopt is disabled if an optional_uses_libs exists, but does not provide an implementation.
func TestNoDexpreoptOptionalUsesLibDoesNotHaveImpl(t *testing.T) {
+ t.Parallel()
bp := `
java_sdk_library_import {
name: "sdklib_noimpl",
@@ -4550,7 +4687,7 @@
}
`
result := prepareForJavaTest.RunTestWithBp(t, bp)
- dexpreopt := result.ModuleForTests("app", "android_common").MaybeRule("dexpreopt").Rule
+ dexpreopt := result.ModuleForTests(t, "app", "android_common").MaybeRule("dexpreopt").Rule
android.AssertBoolEquals(t, "dexpreopt should be disabled if optional_uses_libs does not have an implementation", true, dexpreopt == nil)
}
@@ -4592,7 +4729,77 @@
assertTestOnlyAndTopLevel(t, ctx, expectedTestOnly, expectedTopLevel)
}
+func TestTestConfigTemplate(t *testing.T) {
+ t.Parallel()
+ ctx := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ ).RunTestWithBp(t, `
+ android_test {
+ name: "android-test",
+ test_config_template: "AndroidTestTemplate.xml",
+ test_options: {
+ tradefed_options: [
+ {
+ name: "name1",
+ key: "key1",
+ value: "value1",
+ },
+ {
+ name: "name2",
+ key: "key2",
+ value: "value2",
+ },
+ ],
+ test_runner_options: [
+ {
+ name: "name3",
+ key: "key3",
+ value: "value3",
+ },
+ {
+ name: "name4",
+ key: "key4",
+ value: "value4",
+ },
+ ],
+ },
+ }
+ `)
+ type option struct {
+ name string
+ key string
+ value string
+ }
+ re := regexp.MustCompile(`<option name="(.*)" key="(.*)" value="(.*)" />`)
+ parse_options := func(optionsString string) []option {
+ lines := strings.Split(optionsString, `\n`)
+ var ret []option
+ for _, l := range lines {
+ sm := re.FindStringSubmatch(l)
+ if sm == nil {
+ continue
+ }
+ ret = append(ret, option{sm[1], sm[2], sm[3]})
+ }
+ return ret
+ }
+ rule := ctx.ModuleForTests(t, "android-test", "android_common").Rule("autogenInstrumentationTest")
+ android.AssertSameArray(t, "extraConfigs mismatch",
+ []option{
+ {"name1", "key1", "value1"},
+ {"name2", "key2", "value2"},
+ },
+ parse_options(rule.Args["extraConfigs"]))
+ android.AssertSameArray(t, "extraTestRunnerConfigs mismatch",
+ []option{
+ {"name3", "key3", "value3"},
+ {"name4", "key4", "value4"},
+ },
+ parse_options(rule.Args["extraTestRunnerConfigs"]))
+}
+
func TestAppStem(t *testing.T) {
+ t.Parallel()
ctx := testApp(t, `
android_app {
name: "foo",
@@ -4601,7 +4808,7 @@
sdk_version: "current",
}`)
- foo := ctx.ModuleForTests("foo", "android_common")
+ foo := ctx.ModuleForTests(t, "foo", "android_common")
outputs := fmt.Sprint(foo.AllOutputs())
if !strings.Contains(outputs, "foo-new.apk") {
@@ -4610,6 +4817,7 @@
}
func TestAppMinSdkVersionOverride(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, `
@@ -4626,8 +4834,8 @@
min_sdk_version: "33",
}
`)
- foo := result.ModuleForTests("com.android.foo", "android_common").Rule("manifestFixer")
- fooOverride := result.ModuleForTests("com.android.foo", "android_common_com.android.go.foo").Rule("manifestFixer")
+ foo := result.ModuleForTests(t, "com.android.foo", "android_common").Rule("manifestFixer")
+ fooOverride := result.ModuleForTests(t, "com.android.foo", "android_common_com.android.go.foo").Rule("manifestFixer")
android.AssertStringDoesContain(t,
"com.android.foo: expected manifest fixer to set minSdkVersion to T",
@@ -4643,6 +4851,7 @@
}
func TestNotApplyDefaultUpdatableModuleVersion(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, `
@@ -4653,7 +4862,7 @@
min_sdk_version: "31",
}
`)
- foo := result.ModuleForTests("com.android.foo", "android_common").Rule("manifestFixer")
+ foo := result.ModuleForTests(t, "com.android.foo", "android_common").Rule("manifestFixer")
android.AssertStringDoesNotContain(t,
"com.android.foo: expected manifest fixer to not set override-placeholder-version",
foo.BuildParams.Args["args"],
@@ -4662,6 +4871,7 @@
}
func TestNotApplyOverrideApexManifestDefaultVersion(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.FixtureMergeEnv(map[string]string{
@@ -4675,7 +4885,7 @@
min_sdk_version: "31",
}
`)
- foo := result.ModuleForTests("com.android.foo", "android_common").Rule("manifestFixer")
+ foo := result.ModuleForTests(t, "com.android.foo", "android_common").Rule("manifestFixer")
android.AssertStringDoesNotContain(t,
"com.android.foo: expected manifest fixer to not set override-placeholder-version",
foo.BuildParams.Args["args"],
@@ -4684,6 +4894,7 @@
}
func TestResourcesWithFlagDirectories(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.FixtureMergeMockFs(android.MockFS{
@@ -4702,7 +4913,7 @@
],
}
`)
- fooModule := result.ModuleForTests("foo", "android_common")
+ fooModule := result.ModuleForTests(t, "foo", "android_common")
compileOutputPaths := fooModule.Rule("aapt2Compile").Outputs.Strings()
android.AssertStringListContains(
@@ -4788,17 +4999,20 @@
},
}
for _, tc := range testCases {
- result := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.EnforceRROTargets = []string{"*"}
- }),
- android.OptionalFixturePreparer(tc.preparer),
- ).RunTestWithBp(t, bp)
- vendorOverlayApk := result.ModuleForTests("foo__test_product__auto_generated_rro_vendor", "android_arm64_armv8-a").MaybeOutput("foo__test_product__auto_generated_rro_vendor.apk")
- android.AssertBoolEquals(t, tc.desc, tc.overlayApkExpected, vendorOverlayApk.Rule != nil)
- overrideVendorOverlayApk := result.ModuleForTests("override_foo__test_product__auto_generated_rro_vendor", "android_arm64_armv8-a").MaybeOutput("override_foo__test_product__auto_generated_rro_vendor.apk")
- android.AssertBoolEquals(t, tc.desc, tc.overlayApkExpected, overrideVendorOverlayApk.Rule != nil)
+ t.Run(tc.desc, func(t *testing.T) {
+ t.Parallel()
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.EnforceRROTargets = []string{"*"}
+ }),
+ android.OptionalFixturePreparer(tc.preparer),
+ ).RunTestWithBp(t, bp)
+ vendorOverlayApk := result.ModuleForTests(t, "foo__test_product__auto_generated_rro_vendor", "android_arm64_armv8-a").MaybeOutput("foo__test_product__auto_generated_rro_vendor.apk")
+ android.AssertBoolEquals(t, tc.desc, tc.overlayApkExpected, vendorOverlayApk.Rule != nil)
+ overrideVendorOverlayApk := result.ModuleForTests(t, "override_foo__test_product__auto_generated_rro_vendor", "android_arm64_armv8-a").MaybeOutput("override_foo__test_product__auto_generated_rro_vendor.apk")
+ android.AssertBoolEquals(t, tc.desc, tc.overlayApkExpected, overrideVendorOverlayApk.Rule != nil)
+ })
}
}
@@ -4855,22 +5069,25 @@
},
}
for _, tc := range testCases {
- result := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- android.PrepareForTestWithSoongConfigModuleBuildComponents,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.EnforceRROTargets = []string{"*"}
- }),
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.DeviceResourceOverlays = []string{"device/company/test_product"}
- }),
- android.MockFS{
- "res/foo.xml": nil,
- "device/company/test_product/res/foo.xml": nil,
- }.AddToFixture(),
- android.OptionalFixturePreparer(tc.preparer),
- ).RunTestWithBp(t, bp)
- overrideVendorOverlayApk := result.ModuleForTests("override_foo__test_product__auto_generated_rro_vendor", "android_arm64_armv8-a").Module().(*AutogenRuntimeResourceOverlay)
- android.AssertBoolEquals(t, tc.desc, tc.overlayApkExpected, overrideVendorOverlayApk.exportPackage != nil)
+ t.Run(tc.desc, func(t *testing.T) {
+ t.Parallel()
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ android.PrepareForTestWithSoongConfigModuleBuildComponents,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.EnforceRROTargets = []string{"*"}
+ }),
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.DeviceResourceOverlays = []string{"device/company/test_product"}
+ }),
+ android.MockFS{
+ "res/foo.xml": nil,
+ "device/company/test_product/res/foo.xml": nil,
+ }.AddToFixture(),
+ android.OptionalFixturePreparer(tc.preparer),
+ ).RunTestWithBp(t, bp)
+ overrideVendorOverlayApk := result.ModuleForTests(t, "override_foo__test_product__auto_generated_rro_vendor", "android_arm64_armv8-a").Module().(*AutogenRuntimeResourceOverlay)
+ android.AssertBoolEquals(t, tc.desc, tc.overlayApkExpected, overrideVendorOverlayApk.exportPackage != nil)
+ })
}
}
diff --git a/java/base.go b/java/base.go
index c0ac4ab..8aa0109 100644
--- a/java/base.go
+++ b/java/base.go
@@ -60,6 +60,9 @@
// This is most useful in the arch/multilib variants to remove non-common files
Exclude_srcs []string `android:"path,arch_variant"`
+ // list of Kotlin source files that should excluded from the list of common_srcs.
+ Exclude_common_srcs []string `android:"path,arch_variant"`
+
// list of directories containing Java resources
Java_resource_dirs []string `android:"arch_variant"`
@@ -87,6 +90,10 @@
// list of module-specific flags that will be used for kotlinc compiles
Kotlincflags []string `android:"arch_variant"`
+ // Kotlin language version to target. Currently only 1.9 and 2 are supported.
+ // See kotlinc's `-language-version` flag.
+ Kotlin_lang_version *string
+
// list of java libraries that will be in the classpath
Libs []string `android:"arch_variant"`
@@ -106,6 +113,10 @@
// if not blank, used as prefix to generate repackage rule
Jarjar_prefix *string
+ // Number of shards for jarjar. It needs to be an integer represented as a string.
+ // TODO(b/383559945) change it to int, once Configurable supports the type.
+ Jarjar_shards proptools.Configurable[string]
+
// If not blank, set the java version passed to javac as -source and -target
Java_version *string
@@ -362,13 +373,13 @@
e.initSdkLibraryComponent(module)
}
-// Module/Import's DepIsInSameApex(...) delegates to this method.
+// Module/Import's OutgoingDepIsInSameApex(...) delegates to this method.
//
-// This cannot implement DepIsInSameApex(...) directly as that leads to ambiguity with
+// This cannot implement OutgoingDepIsInSameApex(...) directly as that leads to ambiguity with
// the one provided by ApexModuleBase.
-func (e *embeddableInModuleAndImport) depIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
+func depIsInSameApex(tag blueprint.DependencyTag) bool {
// dependencies other than the static linkage are all considered crossing APEX boundary
- if staticLibTag == ctx.OtherModuleDependencyTag(dep) {
+ if tag == staticLibTag {
return true
}
return false
@@ -618,7 +629,7 @@
return nil
}
if info.SdkVersion.Kind == android.SdkCorePlatform {
- if useLegacyCorePlatformApi(ctx, android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey).BaseModuleName) {
+ if useLegacyCorePlatformApi(ctx, android.OtherModulePointerProviderOrDefault(ctx, module, android.CommonModuleInfoProvider).BaseModuleName) {
return fmt.Errorf("non stable SDK %v - uses legacy core platform", info.SdkVersion)
} else {
// Treat stable core platform as stable.
@@ -645,14 +656,17 @@
// Make sure this module doesn't statically link to modules with lower-ranked SDK link type.
// See rank() for details.
- ctx.VisitDirectDeps(func(module android.Module) {
+ ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
tag := ctx.OtherModuleDependencyTag(module)
- switch module.(type) {
- // TODO(satayev): cover other types as well, e.g. imports
- case *Library, *AndroidLibrary:
+ libInfo, isJavaLibrary := android.OtherModuleProvider(ctx, module, JavaLibraryInfoProvider)
+ _, isAndroidLibrary := android.OtherModuleProvider(ctx, module, AndroidLibraryInfoProvider)
+ _, isJavaAconfigLibrary := android.OtherModuleProvider(ctx, module, android.CodegenInfoProvider)
+ // Exclude java_aconfig_library modules to maintain consistency with existing behavior.
+ if (isJavaLibrary && !libInfo.Prebuilt && !isJavaAconfigLibrary) || isAndroidLibrary {
+ // TODO(satayev): cover other types as well, e.g. imports
switch tag {
case bootClasspathTag, sdkLibTag, libTag, staticLibTag, java9LibTag:
- j.checkSdkLinkType(ctx, module.(moduleWithSdkDep), tag.(dependencyTag))
+ j.checkSdkLinkType(ctx, module)
}
}
})
@@ -835,13 +849,18 @@
}
func (j *Module) AvailableFor(what string) bool {
- if what == android.AvailableToPlatform && Bool(j.deviceProperties.Hostdex) {
+ return android.CheckAvailableForApex(what, j.ApexAvailableFor())
+}
+
+func (j *Module) ApexAvailableFor() []string {
+ list := j.ApexModuleBase.ApexAvailable()
+ if Bool(j.deviceProperties.Hostdex) {
// Exception: for hostdex: true libraries, the platform variant is created
// even if it's not marked as available to platform. In that case, the platform
// variant is used only for the hostdex and not installed to the device.
- return true
+ list = append(list, android.AvailableToPlatform)
}
- return j.ApexModuleBase.AvailableFor(what)
+ return android.FirstUniqueStrings(list)
}
func (j *Module) staticLibs(ctx android.BaseModuleContext) []string {
@@ -869,6 +888,10 @@
// Add dependency on libraries that provide additional hidden api annotations.
ctx.AddVariationDependencies(nil, hiddenApiAnnotationsTag, j.properties.Hiddenapi_additional_annotations...)
+ // Add dependency on (soft) downstream libs from which to trace references during optimization.
+ traceRefs := j.dexProperties.Optimize.Trace_references_from.GetOrDefault(ctx, []string{})
+ ctx.AddVariationDependencies(nil, traceReferencesTag, traceRefs...)
+
// For library dependencies that are component libraries (like stubs), add the implementation
// as a dependency (dexpreopt needs to be against the implementation library, not stubs).
for _, dep := range libDeps {
@@ -922,7 +945,7 @@
if j.useCompose(ctx) {
ctx.AddVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), kotlinPluginTag,
- "androidx.compose.compiler_compiler-hosted-plugin")
+ "kotlin-compose-compiler-plugin")
}
}
@@ -1141,7 +1164,7 @@
j.properties.Generated_srcjars = append(j.properties.Generated_srcjars, path)
}
-func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspathJars, extraCombinedJars, extraDepCombinedJars android.Paths) {
+func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspathJars, extraCombinedJars, extraDepCombinedJars android.Paths) *JavaInfo {
// Auto-propagating jarjar rules
jarjarProviderData := j.collectJarJarRules(ctx)
if jarjarProviderData != nil {
@@ -1182,7 +1205,7 @@
flags = protoFlags(ctx, &j.properties, &j.protoProperties, flags)
}
- kotlinCommonSrcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Common_srcs, nil)
+ kotlinCommonSrcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Common_srcs, j.properties.Exclude_common_srcs)
if len(kotlinCommonSrcFiles.FilterOutByExt(".kt")) > 0 {
ctx.PropertyErrorf("common_srcs", "common_srcs must be .kt files")
}
@@ -1229,7 +1252,6 @@
uniqueSrcFiles = append(uniqueSrcFiles, uniqueJavaFiles...)
uniqueSrcFiles = append(uniqueSrcFiles, uniqueKtFiles...)
j.uniqueSrcFiles = uniqueSrcFiles
- android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: uniqueSrcFiles.Strings()})
// 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
@@ -1265,7 +1287,7 @@
localHeaderJars, combinedHeaderJarFile := j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName,
extraCombinedJars)
- combinedHeaderJarFile, jarjared := j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine")
+ combinedHeaderJarFile, jarjared := j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine", false)
if jarjared {
localHeaderJars = android.Paths{combinedHeaderJarFile}
transitiveStaticLibsHeaderJars = nil
@@ -1276,22 +1298,19 @@
transitiveStaticLibsHeaderJars = nil
}
if ctx.Failed() {
- return
+ return nil
}
j.headerJarFile = combinedHeaderJarFile
- if ctx.Config().UseTransitiveJarsInClasspath() {
- if len(localHeaderJars) > 0 {
- ctx.CheckbuildFile(localHeaderJars...)
- } else {
- // There are no local sources or resources in this module, so there is nothing to checkbuild.
- ctx.UncheckedModule()
- }
+ if len(localHeaderJars) > 0 {
+ ctx.CheckbuildFile(localHeaderJars...)
} else {
- ctx.CheckbuildFile(j.headerJarFile)
+ // There are no local sources or resources in this module, so there is nothing to checkbuild.
+ ctx.UncheckedModule()
}
- android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
+ j.outputFile = j.headerJarFile
+ return &JavaInfo{
HeaderJars: android.PathsIfNonNil(j.headerJarFile),
LocalHeaderJars: localHeaderJars,
TransitiveStaticLibsHeaderJars: depset.New(depset.PREORDER, localHeaderJars, transitiveStaticLibsHeaderJars),
@@ -1304,10 +1323,7 @@
StubsLinkType: j.stubsLinkType,
AconfigIntermediateCacheOutputPaths: deps.aconfigProtoFiles,
SdkVersion: j.SdkVersion(ctx),
- })
-
- j.outputFile = j.headerJarFile
- return
+ }
}
if srcFiles.HasExt(".kt") {
@@ -1320,6 +1336,26 @@
kotlincFlags := j.properties.Kotlincflags
CheckKotlincFlags(ctx, kotlincFlags)
+ // Available kotlin versions can be found at
+ // https://github.com/JetBrains/kotlin/blob/master/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt#L560
+ // in the `LanguageVersion` class.
+ // For now, avoid targeting language versions directly, as we'd like to kee our source
+ // code version aligned as much as possible. Ideally, after defaulting to "2", we
+ // can remove the "1.9" option entirely, or at least make it emit a warning.
+ kotlin_default_lang_version := "1.9"
+ if build_flag_lang_version, ok := ctx.Config().GetBuildFlag("RELEASE_KOTLIN_LANG_VERSION"); ok {
+ kotlin_default_lang_version = build_flag_lang_version
+ }
+ kotlin_lang_version := proptools.StringDefault(j.properties.Kotlin_lang_version, kotlin_default_lang_version)
+ switch kotlin_lang_version {
+ case "1.9":
+ kotlincFlags = append(kotlincFlags, "-language-version 1.9")
+ case "2":
+ kotlincFlags = append(kotlincFlags, "-Xsuppress-version-warnings", "-Xconsistent-data-class-copy-visibility")
+ default:
+ ctx.PropertyErrorf("kotlin_lang_version", "Must be one of `1.9` or `2`")
+ }
+
// Workaround for KT-46512
kotlincFlags = append(kotlincFlags, "-Xsam-conversions=class")
@@ -1364,7 +1400,7 @@
kotlinHeaderJar := android.PathForModuleOut(ctx, "kotlin_headers", jarName)
j.kotlinCompile(ctx, kotlinJar, kotlinHeaderJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
if ctx.Failed() {
- return
+ return nil
}
kotlinJarPath, _ := j.repackageFlagsIfNecessary(ctx, kotlinJar, jarName, "kotlinc")
@@ -1401,7 +1437,7 @@
shardingHeaderJars = localHeaderJars
var jarjared bool
- j.headerJarFile, jarjared = j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine")
+ j.headerJarFile, jarjared = j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine", false)
if jarjared {
// jarjar modifies transitive static dependencies, use the combined header jar and drop the transitive
// static libs header jars.
@@ -1434,20 +1470,27 @@
// build.
flags = enableErrorproneFlags(flags)
} else if hasErrorproneableFiles && ctx.Config().RunErrorProne() && j.properties.Errorprone.Enabled == nil {
- // Otherwise, if the RUN_ERROR_PRONE environment variable is set, create
- // a new jar file just for compiling with the errorprone compiler to.
- // This is because we don't want to cause the java files to get completely
- // rebuilt every time the state of the RUN_ERROR_PRONE variable changes.
- // We also don't want to run this if errorprone is enabled by default for
- // this module, or else we could have duplicated errorprone messages.
- errorproneFlags := enableErrorproneFlags(flags)
- errorprone := android.PathForModuleOut(ctx, "errorprone", jarName)
- errorproneAnnoSrcJar := android.PathForModuleOut(ctx, "errorprone", "anno.srcjar")
+ if ctx.Config().RunErrorProneInline() {
+ // On CI, we're not going to toggle back/forth between errorprone and non-errorprone
+ // builds, so it's faster if we don't compile the module twice and instead always
+ // compile the module with errorprone.
+ flags = enableErrorproneFlags(flags)
+ } else {
+ // Otherwise, if the RUN_ERROR_PRONE environment variable is set, create
+ // a new jar file just for compiling with the errorprone compiler to.
+ // This is because we don't want to cause the java files to get completely
+ // rebuilt every time the state of the RUN_ERROR_PRONE variable changes.
+ // We also don't want to run this if errorprone is enabled by default for
+ // this module, or else we could have duplicated errorprone messages.
+ errorproneFlags := enableErrorproneFlags(flags)
+ errorprone := android.PathForModuleOut(ctx, "errorprone", jarName)
+ errorproneAnnoSrcJar := android.PathForModuleOut(ctx, "errorprone", "anno.srcjar")
- transformJavaToClasses(ctx, errorprone, -1, uniqueJavaFiles, srcJars, errorproneAnnoSrcJar, errorproneFlags, nil,
- "errorprone", "errorprone")
+ transformJavaToClasses(ctx, errorprone, -1, uniqueJavaFiles, srcJars, errorproneAnnoSrcJar, errorproneFlags, nil,
+ "errorprone", "errorprone")
- extraJarDeps = append(extraJarDeps, errorprone)
+ extraJarDeps = append(extraJarDeps, errorprone)
+ }
}
if enableSharding {
@@ -1484,7 +1527,7 @@
localImplementationJars = append(localImplementationJars, classes)
}
if ctx.Failed() {
- return
+ return nil
}
}
@@ -1524,7 +1567,7 @@
resourceJar := android.PathForModuleOut(ctx, "res", jarName)
TransformResourcesToJar(ctx, resourceJar, resArgs, resDeps)
if ctx.Failed() {
- return
+ return nil
}
localResourceJars = append(localResourceJars, resourceJar)
}
@@ -1561,12 +1604,7 @@
completeStaticLibsResourceJars := depset.New(depset.PREORDER, localResourceJars, deps.transitiveStaticLibsResourceJars)
var combinedResourceJar android.Path
- var resourceJars android.Paths
- if ctx.Config().UseTransitiveJarsInClasspath() {
- resourceJars = completeStaticLibsResourceJars.ToList()
- } else {
- resourceJars = append(slices.Clone(localResourceJars), deps.staticResourceJars...)
- }
+ resourceJars := completeStaticLibsResourceJars.ToList()
if len(resourceJars) == 1 {
combinedResourceJar = resourceJars[0]
} else if len(resourceJars) > 0 {
@@ -1587,12 +1625,7 @@
completeStaticLibsImplementationJars := depset.New(depset.PREORDER, localImplementationJars, deps.transitiveStaticLibsImplementationJars)
- var jars android.Paths
- if ctx.Config().UseTransitiveJarsInClasspath() {
- jars = completeStaticLibsImplementationJars.ToList()
- } else {
- jars = append(slices.Clone(localImplementationJars), deps.staticJars...)
- }
+ jars := completeStaticLibsImplementationJars.ToList()
jars = append(jars, extraDepCombinedJars...)
@@ -1628,7 +1661,7 @@
}
// jarjar implementation jar if necessary
- jarjarFile, jarjarred := j.jarjarIfNecessary(ctx, outputFile, jarName, "")
+ jarjarFile, jarjarred := j.jarjarIfNecessary(ctx, outputFile, jarName, "", true)
if jarjarred {
localImplementationJars = android.Paths{jarjarFile}
completeStaticLibsImplementationJars = depset.New(depset.PREORDER, localImplementationJars, nil)
@@ -1637,7 +1670,7 @@
// jarjar resource jar if necessary
if combinedResourceJar != nil {
- resourceJarJarFile, jarjarred := j.jarjarIfNecessary(ctx, combinedResourceJar, jarName, "resource")
+ resourceJarJarFile, jarjarred := j.jarjarIfNecessary(ctx, combinedResourceJar, jarName, "resource", false)
combinedResourceJar = resourceJarJarFile
if jarjarred {
localResourceJars = android.Paths{resourceJarJarFile}
@@ -1646,7 +1679,7 @@
}
if ctx.Failed() {
- return
+ return nil
}
if j.ravenizer.enabled {
@@ -1710,7 +1743,7 @@
CheckJarPackages(ctx, pkgckFile, outputFile, j.properties.Permitted_packages)
if ctx.Failed() {
- return
+ return nil
}
}
@@ -1723,7 +1756,7 @@
headerJarFile := android.PathForModuleOut(ctx, "javac-header", jarName)
convertImplementationJarToHeaderJar(ctx, j.implementationJarFile, headerJarFile)
j.headerJarFile = headerJarFile
- if len(localImplementationJars) == 1 && ctx.Config().UseTransitiveJarsInClasspath() {
+ if len(localImplementationJars) == 1 {
localHeaderJarFile := android.PathForModuleOut(ctx, "local-javac-header", jarName)
convertImplementationJarToHeaderJar(ctx, localImplementationJars[0], localHeaderJarFile)
localHeaderJars = append(localHeaderJars, localHeaderJarFile)
@@ -1735,7 +1768,7 @@
// enforce syntax check to jacoco filters for any build (http://b/183622051)
specs := j.jacocoModuleToZipCommand(ctx)
if ctx.Failed() {
- return
+ return nil
}
completeStaticLibsImplementationJarsToCombine := completeStaticLibsImplementationJars
@@ -1753,16 +1786,10 @@
// merge implementation jar with resources if necessary
var implementationAndResourcesJarsToCombine android.Paths
- if ctx.Config().UseTransitiveJarsInClasspath() {
- resourceJars := completeStaticLibsResourceJars.ToList()
- if len(resourceJars) > 0 {
- implementationAndResourcesJarsToCombine = append(resourceJars, completeStaticLibsImplementationJarsToCombine.ToList()...)
- implementationAndResourcesJarsToCombine = append(implementationAndResourcesJarsToCombine, extraDepCombinedJars...)
- }
- } else {
- if combinedResourceJar != nil {
- implementationAndResourcesJarsToCombine = android.Paths{combinedResourceJar, outputFile}
- }
+ combinedResourceJars := completeStaticLibsResourceJars.ToList()
+ if len(combinedResourceJars) > 0 {
+ implementationAndResourcesJarsToCombine = slices.Concat(combinedResourceJars,
+ completeStaticLibsImplementationJarsToCombine.ToList(), extraDepCombinedJars)
}
if len(implementationAndResourcesJarsToCombine) > 0 {
@@ -1789,7 +1816,7 @@
classesJar: outputFile,
jarName: jarName,
}
- if j.GetProfileGuided(ctx) && j.optimizeOrObfuscateEnabled() && !j.EnableProfileRewriting(ctx) {
+ if j.GetProfileGuided(ctx) && j.optimizeOrObfuscateEnabled(ctx) && !j.EnableProfileRewriting(ctx) {
ctx.PropertyErrorf("enable_profile_rewriting",
"Enable_profile_rewriting must be true when profile_guided dexpreopt and R8 optimization/obfuscation is turned on. The attached profile should be sourced from an unoptimized/unobfuscated APK.",
)
@@ -1803,7 +1830,7 @@
}
dexOutputFile, dexArtProfileOutput := j.dexer.compileDex(ctx, params)
if ctx.Failed() {
- return
+ return nil
}
// If r8/d8 provides a profile that matches the optimized dex, use that for dexpreopt.
@@ -1812,18 +1839,9 @@
}
// merge dex jar with resources if necessary
- var dexAndResourceJarsToCombine android.Paths
- if ctx.Config().UseTransitiveJarsInClasspath() {
- resourceJars := completeStaticLibsResourceJars.ToList()
- if len(resourceJars) > 0 {
- dexAndResourceJarsToCombine = append(android.Paths{dexOutputFile}, resourceJars...)
- }
- } else {
- if combinedResourceJar != nil {
- dexAndResourceJarsToCombine = android.Paths{dexOutputFile, combinedResourceJar}
- }
- }
- if len(dexAndResourceJarsToCombine) > 0 {
+ if len(combinedResourceJars) > 0 {
+ dexAndResourceJarsToCombine := append(android.Paths{dexOutputFile}, combinedResourceJars...)
+
combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName)
TransformJarsToJar(ctx, combinedJar, "for dex resources", dexAndResourceJarsToCombine, android.OptionalPath{},
false, nil, nil)
@@ -1862,7 +1880,7 @@
}
if ctx.Failed() {
- return
+ return nil
}
}
@@ -1895,21 +1913,19 @@
j.collectTransitiveSrcFiles(ctx, srcFiles)
- if ctx.Config().UseTransitiveJarsInClasspath() {
- if len(localImplementationJars) > 0 || len(localResourceJars) > 0 || len(localHeaderJars) > 0 {
- ctx.CheckbuildFile(localImplementationJars...)
- ctx.CheckbuildFile(localResourceJars...)
- ctx.CheckbuildFile(localHeaderJars...)
- } else {
- // There are no local sources or resources in this module, so there is nothing to checkbuild.
- ctx.UncheckedModule()
- }
+ if len(localImplementationJars) > 0 || len(localResourceJars) > 0 || len(localHeaderJars) > 0 {
+ ctx.CheckbuildFile(localImplementationJars...)
+ ctx.CheckbuildFile(localResourceJars...)
+ ctx.CheckbuildFile(localHeaderJars...)
} else {
- ctx.CheckbuildFile(j.implementationJarFile)
- ctx.CheckbuildFile(j.headerJarFile)
+ // There are no local sources or resources in this module, so there is nothing to checkbuild.
+ ctx.UncheckedModule()
}
- android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
+ // Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
+ j.outputFile = outputFile.WithoutRel()
+
+ return &JavaInfo{
HeaderJars: android.PathsIfNonNil(j.headerJarFile),
RepackagedHeaderJars: android.PathsIfNonNil(repackagedHeaderJarFile),
@@ -1934,10 +1950,8 @@
StubsLinkType: j.stubsLinkType,
AconfigIntermediateCacheOutputPaths: j.aconfigCacheFiles,
SdkVersion: j.SdkVersion(ctx),
- })
-
- // Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
- j.outputFile = outputFile.WithoutRel()
+ OutputFile: j.outputFile,
+ }
}
func (j *Module) useCompose(ctx android.BaseModuleContext) bool {
@@ -1945,7 +1959,7 @@
}
func collectDepProguardSpecInfo(ctx android.ModuleContext) (transitiveProguardFlags, transitiveUnconditionalExportedFlags []depset.DepSet[android.Path]) {
- ctx.VisitDirectDeps(func(m android.Module) {
+ ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider)
depTag := ctx.OtherModuleDependencyTag(m)
@@ -2041,7 +2055,9 @@
} else if strings.HasPrefix(flag, "-Xintellij-plugin-root") {
ctx.PropertyErrorf("kotlincflags",
"Bad flag: `%s`, only use internal compiler for consistency.", flag)
- } else if inList(flag, config.KotlincIllegalFlags) {
+ } else if slices.ContainsFunc(config.KotlincIllegalFlags, func(f string) bool {
+ return strings.HasPrefix(flag, f)
+ }) {
ctx.PropertyErrorf("kotlincflags", "Flag `%s` already used by build system", flag)
} else if flag == "-include-runtime" {
ctx.PropertyErrorf("kotlincflags", "Bad flag: `%s`, do not include runtime.", flag)
@@ -2070,13 +2086,8 @@
// Combine any static header libraries into classes-header.jar. If there is only
// one input jar this step will be skipped.
- var jars android.Paths
- if ctx.Config().UseTransitiveJarsInClasspath() {
- depSet := depset.New(depset.PREORDER, localHeaderJars, deps.transitiveStaticLibsHeaderJars)
- jars = depSet.ToList()
- } else {
- jars = append(slices.Clone(localHeaderJars), deps.staticHeaderJars...)
- }
+ depSet := depset.New(depset.PREORDER, localHeaderJars, deps.transitiveStaticLibsHeaderJars)
+ jars := depSet.ToList()
// we cannot skip the combine step for now if there is only one jar
// since we have to strip META-INF/TRANSITIVE dir from turbine.jar
@@ -2116,7 +2127,7 @@
directStaticLibs := android.Paths{}
transitiveLibs := []depset.DepSet[android.Path]{}
transitiveStaticLibs := []depset.DepSet[android.Path]{}
- ctx.VisitDirectDeps(func(module android.Module) {
+ ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
// don't add deps of the prebuilt version of the same library
if ctx.ModuleName() == android.RemoveOptionalPrebuiltPrefix(module.Name()) {
return
@@ -2184,6 +2195,8 @@
func (j *Module) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
if j.expandJarjarRules != nil {
dpInfo.Jarjar_rules = append(dpInfo.Jarjar_rules, j.expandJarjarRules.String())
+ }
+ if j.headerJarFile != nil {
// Add the header jar so that the rdeps can be resolved to the repackaged classes.
dpInfo.Jars = append(dpInfo.Jars, j.headerJarFile.String())
}
@@ -2202,29 +2215,33 @@
func (j *Module) hasCode(ctx android.ModuleContext) bool {
srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
- return len(srcFiles) > 0 || len(ctx.GetDirectDepsWithTag(staticLibTag)) > 0
+ return len(srcFiles) > 0 || len(ctx.GetDirectDepsProxyWithTag(staticLibTag)) > 0
}
// Implements android.ApexModule
-func (j *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
- return j.depIsInSameApex(ctx, dep)
+func (m *Module) GetDepInSameApexChecker() android.DepInSameApexChecker {
+ return JavaDepInSameApexChecker{}
+}
+
+type JavaDepInSameApexChecker struct {
+ android.BaseDepInSameApexChecker
+}
+
+func (m JavaDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
+ return depIsInSameApex(tag)
}
// Implements android.ApexModule
-func (j *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
+func (j *Module) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
sdkVersionSpec := j.SdkVersion(ctx)
minSdkVersion := j.MinSdkVersion(ctx)
- if !minSdkVersion.Specified() {
- return fmt.Errorf("min_sdk_version is not specified")
- }
+
// If the module is compiling against core (via sdk_version), skip comparison check.
if sdkVersionSpec.Kind == android.SdkCore {
- return nil
+ return android.MinApiLevel
}
- if minSdkVersion.GreaterThan(sdkVersion) {
- return fmt.Errorf("newer SDK(%v)", minSdkVersion)
- }
- return nil
+
+ return minSdkVersion
}
func (j *Module) Stem() string {
@@ -2240,7 +2257,7 @@
func (j *Module) collectTransitiveSrcFiles(ctx android.ModuleContext, mine android.Paths) {
var fromDeps []depset.DepSet[android.Path]
- ctx.VisitDirectDeps(func(module android.Module) {
+ ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
tag := ctx.OtherModuleDependencyTag(module)
if tag == staticLibTag {
if depInfo, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
@@ -2359,7 +2376,7 @@
// checkSdkLinkType make sures the given dependency doesn't have a lower SDK link type rank than
// this module's. See the comment on rank() for details and an example.
func (j *Module) checkSdkLinkType(
- ctx android.ModuleContext, dep moduleWithSdkDep, tag dependencyTag) {
+ ctx android.ModuleContext, dep android.ModuleProxy) {
if ctx.Host() {
return
}
@@ -2368,7 +2385,12 @@
if stubs {
return
}
- depLinkType, _ := dep.getSdkLinkType(ctx, ctx.OtherModuleName(dep))
+ info, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider)
+ if !ok || info.ModuleWithSdkDepInfo == nil {
+ panic(fmt.Errorf("dependency doesn't have ModuleWithSdkDepInfo: %v", dep))
+ }
+
+ depLinkType := info.ModuleWithSdkDepInfo.SdkLinkType
if myLinkType.rank() < depLinkType.rank() {
ctx.ModuleErrorf("compiles against %v, but dependency %q is compiling against %v. "+
@@ -2393,7 +2415,7 @@
var transitiveStaticJarsImplementationLibs []depset.DepSet[android.Path]
var transitiveStaticJarsResourceLibs []depset.DepSet[android.Path]
- ctx.VisitDirectDeps(func(module android.Module) {
+ ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
otherName := ctx.OtherModuleName(module)
tag := ctx.OtherModuleDependencyTag(module)
@@ -2427,7 +2449,7 @@
deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars...)
transitiveBootClasspathHeaderJars = append(transitiveBootClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
case sdkLibTag, libTag, instrumentationForTag:
- if _, ok := module.(*Plugin); ok {
+ if _, ok := android.OtherModuleProvider(ctx, module, JavaPluginInfoProvider); ok {
ctx.ModuleErrorf("a java_plugin (%s) cannot be used as a libs dependency", otherName)
}
deps.classpath = append(deps.classpath, dep.HeaderJars...)
@@ -2445,7 +2467,7 @@
deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...)
transitiveJava9ClasspathHeaderJars = append(transitiveJava9ClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
case staticLibTag:
- if _, ok := module.(*Plugin); ok {
+ if _, ok := android.OtherModuleProvider(ctx, module, JavaPluginInfoProvider); ok {
ctx.ModuleErrorf("a java_plugin (%s) cannot be used as a static_libs dependency", otherName)
}
deps.classpath = append(deps.classpath, dep.HeaderJars...)
@@ -2465,40 +2487,40 @@
transitiveStaticJarsImplementationLibs = append(transitiveStaticJarsImplementationLibs, dep.TransitiveStaticLibsImplementationJars)
transitiveStaticJarsResourceLibs = append(transitiveStaticJarsResourceLibs, dep.TransitiveStaticLibsResourceJars)
case pluginTag:
- if plugin, ok := module.(*Plugin); ok {
- if plugin.pluginProperties.Processor_class != nil {
- addPlugins(&deps, dep.ImplementationAndResourcesJars, *plugin.pluginProperties.Processor_class)
+ if plugin, ok := android.OtherModuleProvider(ctx, module, JavaPluginInfoProvider); ok {
+ if plugin.ProcessorClass != nil {
+ addPlugins(&deps, dep.ImplementationAndResourcesJars, *plugin.ProcessorClass)
} else {
addPlugins(&deps, dep.ImplementationAndResourcesJars)
}
// Turbine doesn't run annotation processors, so any module that uses an
// annotation processor that generates API is incompatible with the turbine
// optimization.
- deps.disableTurbine = deps.disableTurbine || Bool(plugin.pluginProperties.Generates_api)
+ deps.disableTurbine = deps.disableTurbine || plugin.GeneratesApi
} else {
ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName)
}
case errorpronePluginTag:
- if _, ok := module.(*Plugin); ok {
+ if _, ok := android.OtherModuleProvider(ctx, module, JavaPluginInfoProvider); ok {
deps.errorProneProcessorPath = append(deps.errorProneProcessorPath, dep.ImplementationAndResourcesJars...)
} else {
ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName)
}
case exportedPluginTag:
- if plugin, ok := module.(*Plugin); ok {
+ if plugin, ok := android.OtherModuleProvider(ctx, module, JavaPluginInfoProvider); ok {
j.exportedPluginJars = append(j.exportedPluginJars, dep.ImplementationAndResourcesJars...)
- if plugin.pluginProperties.Processor_class != nil {
- j.exportedPluginClasses = append(j.exportedPluginClasses, *plugin.pluginProperties.Processor_class)
+ if plugin.ProcessorClass != nil {
+ j.exportedPluginClasses = append(j.exportedPluginClasses, *plugin.ProcessorClass)
}
// Turbine doesn't run annotation processors, so any module that uses an
// annotation processor that generates API is incompatible with the turbine
// optimization.
- j.exportedDisableTurbine = Bool(plugin.pluginProperties.Generates_api)
+ j.exportedDisableTurbine = plugin.GeneratesApi
} else {
ctx.PropertyErrorf("exported_plugins", "%q is not a java_plugin module", otherName)
}
case kotlinPluginTag:
- if _, ok := module.(*KotlinPlugin); ok {
+ if _, ok := android.OtherModuleProvider(ctx, module, KotlinPluginInfoProvider); ok {
deps.kotlinPlugins = append(deps.kotlinPlugins, dep.ImplementationAndResourcesJars...)
} else {
ctx.PropertyErrorf("kotlin_plugins", "%q is not a kotlin_plugin module", otherName)
@@ -2510,21 +2532,21 @@
JavaInfo: dep,
})
}
- } else if dep, ok := module.(android.SourceFileProducer); ok {
+ } else if dep, ok := android.OtherModuleProvider(ctx, module, android.SourceFilesInfoProvider); ok {
switch tag {
case sdkLibTag, libTag:
- checkProducesJars(ctx, dep)
- deps.classpath = append(deps.classpath, dep.Srcs()...)
- deps.dexClasspath = append(deps.classpath, dep.Srcs()...)
+ checkProducesJars(ctx, dep, module)
+ deps.classpath = append(deps.classpath, dep.Srcs...)
+ deps.dexClasspath = append(deps.classpath, dep.Srcs...)
transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars,
- depset.New(depset.PREORDER, dep.Srcs(), nil))
+ depset.New(depset.PREORDER, dep.Srcs, nil))
case staticLibTag:
- checkProducesJars(ctx, dep)
- deps.classpath = append(deps.classpath, dep.Srcs()...)
- deps.staticJars = append(deps.staticJars, dep.Srcs()...)
- deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs()...)
+ checkProducesJars(ctx, dep, module)
+ deps.classpath = append(deps.classpath, dep.Srcs...)
+ deps.staticJars = append(deps.staticJars, dep.Srcs...)
+ deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs...)
- depHeaderJars := depset.New(depset.PREORDER, dep.Srcs(), nil)
+ depHeaderJars := depset.New(depset.PREORDER, dep.Srcs, nil)
transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, depHeaderJars)
transitiveStaticJarsHeaderLibs = append(transitiveStaticJarsHeaderLibs, depHeaderJars)
transitiveStaticJarsImplementationLibs = append(transitiveStaticJarsImplementationLibs, depHeaderJars)
@@ -2577,14 +2599,12 @@
deps.transitiveStaticLibsImplementationJars = transitiveStaticJarsImplementationLibs
deps.transitiveStaticLibsResourceJars = transitiveStaticJarsResourceLibs
- if ctx.Config().UseTransitiveJarsInClasspath() {
- depSet := depset.New(depset.PREORDER, nil, transitiveClasspathHeaderJars)
- deps.classpath = depSet.ToList()
- depSet = depset.New(depset.PREORDER, nil, transitiveBootClasspathHeaderJars)
- deps.bootClasspath = depSet.ToList()
- depSet = depset.New(depset.PREORDER, nil, transitiveJava9ClasspathHeaderJars)
- deps.java9Classpath = depSet.ToList()
- }
+ depSet := depset.New(depset.PREORDER, nil, transitiveClasspathHeaderJars)
+ deps.classpath = depSet.ToList()
+ depSet = depset.New(depset.PREORDER, nil, transitiveBootClasspathHeaderJars)
+ deps.bootClasspath = depSet.ToList()
+ depSet = depset.New(depset.PREORDER, nil, transitiveJava9ClasspathHeaderJars)
+ deps.java9Classpath = depSet.ToList()
if ctx.Device() {
sdkDep := decodeSdkDep(ctx, android.SdkContext(j))
@@ -2625,18 +2645,11 @@
RenameUseExclude
)
-type RenameUseElement struct {
- DepName string
- RenameUse DependencyUse
- Why string // token for determining where in the logic the decision was made.
-}
-
type JarJarProviderData struct {
// Mapping of class names: original --> renamed. If the value is "", the class will be
// renamed by the next rdep that has the jarjar_prefix attribute (or this module if it has
// attribute). Rdeps of that module will inherit the renaming.
- Rename map[string]string
- RenameUse []RenameUseElement
+ Rename map[string]string
}
func (this JarJarProviderData) GetDebugString() string {
@@ -2707,7 +2720,7 @@
module := ctx.Module()
moduleName := module.Name()
- ctx.VisitDirectDeps(func(m android.Module) {
+ ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
tag := ctx.OtherModuleDependencyTag(m)
// This logic mirrors that in (*Module).collectDeps above. There are several places
// where we explicitly return RenameUseExclude, even though it is the default, to
@@ -2715,93 +2728,89 @@
//
// Note well: there are probably cases that are getting to the unconditional return
// and are therefore wrong.
- shouldIncludeRenames := func() (DependencyUse, string) {
+ shouldIncludeRenames := func() DependencyUse {
if moduleName == m.Name() {
- return RenameUseInclude, "name" // If we have the same module name, include the renames.
+ return RenameUseInclude // If we have the same module name, include the renames.
}
if sc, ok := module.(android.SdkContext); ok {
if ctx.Device() {
sdkDep := decodeSdkDep(ctx, sc)
if !sdkDep.invalidVersion && sdkDep.useFiles {
- return RenameUseExclude, "useFiles"
+ return RenameUseExclude
}
}
}
if IsJniDepTag(tag) || tag == certificateTag || tag == proguardRaiseTag {
- return RenameUseExclude, "tags"
+ return RenameUseExclude
}
if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok {
switch tag {
case sdkLibTag, libTag:
- return RenameUseExclude, "sdklibdep" // matches collectDeps()
+ return RenameUseExclude // matches collectDeps()
}
- return RenameUseInvalid, "sdklibdep" // dep is not used in collectDeps()
+ return RenameUseInvalid // dep is not used in collectDeps()
} else if ji, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
switch ji.StubsLinkType {
case Stubs:
- return RenameUseExclude, "info"
+ return RenameUseExclude
case Implementation:
- return RenameUseInclude, "info"
+ return RenameUseInclude
default:
//fmt.Printf("collectDirectDepsProviders: %v -> %v StubsLinkType unknown\n", module, m)
// Fall through to the heuristic logic.
}
- switch reflect.TypeOf(m).String() {
- case "*java.GeneratedJavaLibraryModule":
+ if _, ok := android.OtherModuleProvider(ctx, m, android.CodegenInfoProvider); ok {
// Probably a java_aconfig_library module.
- // TODO: make this check better.
- return RenameUseInclude, "reflect"
+ return RenameUseInclude
}
switch tag {
case bootClasspathTag:
- return RenameUseExclude, "tagswitch"
+ return RenameUseExclude
case sdkLibTag, libTag, instrumentationForTag:
- return RenameUseInclude, "tagswitch"
+ return RenameUseInclude
case java9LibTag:
- return RenameUseExclude, "tagswitch"
+ return RenameUseExclude
case staticLibTag:
- return RenameUseInclude, "tagswitch"
+ return RenameUseInclude
case pluginTag:
- return RenameUseInclude, "tagswitch"
+ return RenameUseInclude
case errorpronePluginTag:
- return RenameUseInclude, "tagswitch"
+ return RenameUseInclude
case exportedPluginTag:
- return RenameUseInclude, "tagswitch"
+ return RenameUseInclude
case kotlinPluginTag:
- return RenameUseInclude, "tagswitch"
+ return RenameUseInclude
default:
- return RenameUseExclude, "tagswitch"
+ return RenameUseExclude
}
- } else if _, ok := m.(android.SourceFileProducer); ok {
+ } else if _, ok := android.OtherModuleProvider(ctx, m, android.SourceFilesInfoProvider); ok {
switch tag {
case sdkLibTag, libTag, staticLibTag:
- return RenameUseInclude, "srcfile"
+ return RenameUseInclude
default:
- return RenameUseExclude, "srcfile"
+ return RenameUseExclude
}
} else if _, ok := android.OtherModuleProvider(ctx, m, android.CodegenInfoProvider); ok {
- return RenameUseInclude, "aconfig_declarations_group"
+ return RenameUseInclude
} else {
switch tag {
case bootClasspathTag:
- return RenameUseExclude, "else"
+ return RenameUseExclude
case systemModulesTag:
- return RenameUseInclude, "else"
+ return RenameUseInclude
}
}
// If we got here, choose the safer option, which may lead to a build failure, rather
// than runtime failures on the device.
- return RenameUseExclude, "end"
+ return RenameUseExclude
}
if result == nil {
result = &JarJarProviderData{
- Rename: make(map[string]string),
- RenameUse: make([]RenameUseElement, 0),
+ Rename: make(map[string]string),
}
}
- how, why := shouldIncludeRenames()
- result.RenameUse = append(result.RenameUse, RenameUseElement{DepName: m.Name(), RenameUse: how, Why: why})
+ how := shouldIncludeRenames()
if how != RenameUseInclude {
// Nothing to merge.
return
@@ -2906,14 +2915,18 @@
// Get the jarjar rule text for a given provider for the fully resolved rules. Classes that map
// to "" won't be in this list because they shouldn't be renamed yet.
func getJarJarRuleText(provider *JarJarProviderData) string {
- result := ""
+ result := strings.Builder{}
for _, orig := range android.SortedKeys(provider.Rename) {
renamed := provider.Rename[orig]
if renamed != "" {
- result += "rule " + orig + " " + renamed + "\n"
+ result.WriteString("rule ")
+ result.WriteString(orig)
+ result.WriteString(" ")
+ result.WriteString(renamed)
+ result.WriteString("\n")
}
}
- return result
+ return result.String()
}
// Repackage the flags if the jarjar rule txt for the flags is generated
@@ -2926,12 +2939,23 @@
return repackagedJarjarFile, true
}
-func (j *Module) jarjarIfNecessary(ctx android.ModuleContext, infile android.Path, jarName, info string) (android.Path, bool) {
+func (j *Module) jarjarIfNecessary(ctx android.ModuleContext, infile android.Path, jarName, info string, useShards bool) (android.Path, bool) {
if j.expandJarjarRules == nil {
return infile, false
}
jarjarFile := android.PathForModuleOut(ctx, "jarjar", info, jarName)
- TransformJarJar(ctx, jarjarFile, infile, j.expandJarjarRules)
+
+ totalShards := 1
+ if useShards {
+ totalShardsStr := j.properties.Jarjar_shards.GetOrDefault(ctx, "1")
+ ts, err := strconv.Atoi(totalShardsStr)
+ if err != nil {
+ ctx.PropertyErrorf("jarjar_shards", "jarjar_shards must be an integer represented as a string")
+ return infile, false
+ }
+ totalShards = ts
+ }
+ TransformJarJarWithShards(ctx, jarjarFile, infile, j.expandJarjarRules, totalShards)
return jarjarFile, true
}
diff --git a/java/bootclasspath.go b/java/bootclasspath.go
index 3413cf3..98fb417 100644
--- a/java/bootclasspath.go
+++ b/java/bootclasspath.go
@@ -15,6 +15,8 @@
package java
import (
+ "fmt"
+
"android/soong/android"
"github.com/google/blueprint"
@@ -23,36 +25,9 @@
// Contains code that is common to both platform_bootclasspath and bootclasspath_fragment.
-func init() {
- registerBootclasspathBuildComponents(android.InitRegistrationContext)
-}
-
-func registerBootclasspathBuildComponents(ctx android.RegistrationContext) {
- ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.BottomUp("bootclasspath_deps", bootclasspathDepsMutator)
- })
-}
-
-// BootclasspathDepsMutator is the interface that a module must implement if it wants to add
-// dependencies onto APEX specific variants of bootclasspath fragments or bootclasspath contents.
-type BootclasspathDepsMutator interface {
- // BootclasspathDepsMutator implementations should add dependencies using
- // addDependencyOntoApexModulePair and addDependencyOntoApexVariants.
- BootclasspathDepsMutator(ctx android.BottomUpMutatorContext)
-}
-
-// bootclasspathDepsMutator is called during the final deps phase after all APEX variants have
-// been created so can add dependencies onto specific APEX variants of modules.
-func bootclasspathDepsMutator(ctx android.BottomUpMutatorContext) {
- m := ctx.Module()
- if p, ok := m.(BootclasspathDepsMutator); ok {
- p.BootclasspathDepsMutator(ctx)
- }
-}
-
// addDependencyOntoApexVariants adds dependencies onto the appropriate apex specific variants of
// the module as specified in the ApexVariantReference list.
-func addDependencyOntoApexVariants(ctx android.BottomUpMutatorContext, propertyName string, refs []ApexVariantReference, tag blueprint.DependencyTag) {
+func addDependencyOntoApexVariants(ctx android.BottomUpMutatorContext, propertyName string, refs []ApexVariantReference, tagType bootclasspathDependencyTagType) {
for i, ref := range refs {
apex := proptools.StringDefault(ref.Apex, "platform")
@@ -62,7 +37,7 @@
}
name := proptools.String(ref.Module)
- addDependencyOntoApexModulePair(ctx, apex, name, tag)
+ addDependencyOntoApexModulePair(ctx, apex, name, tagType)
}
}
@@ -75,68 +50,154 @@
// module when both source and prebuilt modules are available.
//
// Use gatherApexModulePairDepsWithTag to retrieve the dependencies.
-func addDependencyOntoApexModulePair(ctx android.BottomUpMutatorContext, apex string, name string, tag blueprint.DependencyTag) {
- var variations []blueprint.Variation
- if !android.IsConfiguredJarForPlatform(apex) {
- // Pick the correct apex variant.
- variations = []blueprint.Variation{
- {Mutator: "apex", Variation: apex},
- }
+func addDependencyOntoApexModulePair(ctx android.BottomUpMutatorContext, apex string, name string, tagType bootclasspathDependencyTagType) {
+ tag := bootclasspathDependencyTag{
+ typ: tagType,
}
-
target := ctx.Module().Target()
- variations = append(variations, target.Variations()...)
-
- addedDep := false
- if ctx.OtherModuleDependencyVariantExists(variations, name) {
- ctx.AddFarVariationDependencies(variations, tag, name)
- addedDep = true
+ if android.IsConfiguredJarForPlatform(apex) {
+ // Platform variant, add a direct dependency.
+ ctx.AddFarVariationDependencies(target.Variations(), tag, name)
+ } else {
+ // A module in an apex. Dependencies can't be added directly onto an apex variation, as that would
+ // require constructing a full ApexInfo configuration, which can't be predicted here. Add a dependency
+ // on the apex instead, and annotate the dependency tag with the desired module in the apex.
+ tag.moduleInApex = name
+ ctx.AddFarVariationDependencies(target.Variations(), tag, apex)
}
- // Add a dependency on the prebuilt module if it exists.
- prebuiltName := android.PrebuiltNameFromSource(name)
- if ctx.OtherModuleDependencyVariantExists(variations, prebuiltName) {
- ctx.AddVariationDependencies(variations, tag, prebuiltName)
- addedDep = true
- }
-
- // If no appropriate variant existing for this, so no dependency could be added, then it is an
- // error, unless missing dependencies are allowed. The simplest way to handle that is to add a
- // dependency that will not be satisfied and the default behavior will handle it.
- if !addedDep {
- // Add dependency on the unprefixed (i.e. source or renamed prebuilt) module which we know does
- // not exist. The resulting error message will contain useful information about the available
- // variants.
- reportMissingVariationDependency(ctx, variations, name)
-
- // Add dependency on the missing prefixed prebuilt variant too if a module with that name exists
- // so that information about its available variants will be reported too.
- if ctx.OtherModuleExists(prebuiltName) {
- reportMissingVariationDependency(ctx, variations, prebuiltName)
- }
- }
}
-// reportMissingVariationDependency intentionally adds a dependency on a missing variation in order
-// to generate an appropriate error message with information about the available variations.
-func reportMissingVariationDependency(ctx android.BottomUpMutatorContext, variations []blueprint.Variation, name string) {
- ctx.AddFarVariationDependencies(variations, nil, name)
+// gatherFragments collects fragments that are direct dependencies of this module, as well as
+// any fragments in apexes via the dependency on the apex. It returns a list of the fragment
+// modules and map from apex name to the fragment in that apex.
+func gatherFragments(ctx android.BaseModuleContext) ([]android.Module, map[string]android.Module) {
+ var fragments []android.Module
+
+ type fragmentInApex struct {
+ module string
+ apex string
+ }
+
+ var fragmentsInApexes []fragmentInApex
+
+ // Find any direct dependencies, as well as a list of the modules in apexes.
+ ctx.VisitDirectDeps(func(module android.Module) {
+ t := ctx.OtherModuleDependencyTag(module)
+ if bcpTag, ok := t.(bootclasspathDependencyTag); ok && bcpTag.typ == fragment {
+ if bcpTag.moduleInApex != "" {
+ fragmentsInApexes = append(fragmentsInApexes, fragmentInApex{bcpTag.moduleInApex, ctx.OtherModuleName(module)})
+ } else {
+ fragments = append(fragments, module)
+ }
+ }
+ })
+
+ fragmentsMap := make(map[string]android.Module)
+ for _, fragmentInApex := range fragmentsInApexes {
+ var found android.Module
+ // Find a desired module in an apex.
+ ctx.WalkDeps(func(child, parent android.Module) bool {
+ t := ctx.OtherModuleDependencyTag(child)
+ if parent == ctx.Module() {
+ if bcpTag, ok := t.(bootclasspathDependencyTag); ok && bcpTag.typ == fragment && ctx.OtherModuleName(child) == fragmentInApex.apex {
+ // This is the dependency from this module to the apex, recurse into it.
+ return true
+ }
+ } else if android.IsDontReplaceSourceWithPrebuiltTag(t) {
+ return false
+ } else if t == android.PrebuiltDepTag {
+ return false
+ } else if IsBootclasspathFragmentContentDepTag(t) {
+ return false
+ } else if android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child)) == fragmentInApex.module {
+ // This is the desired module inside the apex.
+ if found != nil && child != found {
+ panic(fmt.Errorf("found two conflicting modules %q in apex %q: %s and %s",
+ fragmentInApex.module, fragmentInApex.apex, found, child))
+ }
+ found = child
+ }
+ return false
+ })
+ if found != nil {
+ if existing, exists := fragmentsMap[fragmentInApex.apex]; exists {
+ ctx.ModuleErrorf("apex %s has multiple fragments, %s and %s", fragmentInApex.apex, fragmentInApex.module, existing)
+ } else {
+ fragmentsMap[fragmentInApex.apex] = found
+ fragments = append(fragments, found)
+ }
+ } else if !ctx.Config().AllowMissingDependencies() {
+ ctx.ModuleErrorf("failed to find fragment %q in apex %q\n",
+ fragmentInApex.module, fragmentInApex.apex)
+ }
+ }
+ return fragments, fragmentsMap
}
// gatherApexModulePairDepsWithTag returns the list of dependencies with the supplied tag that was
// added by addDependencyOntoApexModulePair.
-func gatherApexModulePairDepsWithTag(ctx android.BaseModuleContext, tag blueprint.DependencyTag) []android.Module {
+func gatherApexModulePairDepsWithTag(ctx android.BaseModuleContext, tagType bootclasspathDependencyTagType) ([]android.Module, map[android.Module]string) {
var modules []android.Module
- isActiveModulePred := func(module android.Module) bool {
- return isActiveModule(ctx, module)
+ modulesToApex := make(map[android.Module]string)
+
+ type moduleInApex struct {
+ module string
+ apex string
}
- ctx.VisitDirectDepsIf(isActiveModulePred, func(module android.Module) {
+
+ var modulesInApexes []moduleInApex
+
+ ctx.VisitDirectDeps(func(module android.Module) {
t := ctx.OtherModuleDependencyTag(module)
- if t == tag {
- modules = append(modules, module)
+ if bcpTag, ok := t.(bootclasspathDependencyTag); ok && bcpTag.typ == tagType {
+ if bcpTag.moduleInApex != "" {
+ modulesInApexes = append(modulesInApexes, moduleInApex{bcpTag.moduleInApex, ctx.OtherModuleName(module)})
+ } else {
+ modules = append(modules, module)
+ }
}
})
- return modules
+
+ for _, moduleInApex := range modulesInApexes {
+ var found android.Module
+ ctx.WalkDeps(func(child, parent android.Module) bool {
+ t := ctx.OtherModuleDependencyTag(child)
+ if parent == ctx.Module() {
+ if bcpTag, ok := t.(bootclasspathDependencyTag); ok && bcpTag.typ == tagType && ctx.OtherModuleName(child) == moduleInApex.apex {
+ // recurse into the apex
+ return true
+ }
+ } else if tagType != fragment && android.IsFragmentInApexTag(t) {
+ return true
+ } else if android.IsDontReplaceSourceWithPrebuiltTag(t) {
+ return false
+ } else if t == android.PrebuiltDepTag {
+ return false
+ } else if IsBootclasspathFragmentContentDepTag(t) {
+ return false
+ } else if android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child)) == moduleInApex.module {
+ if found != nil && child != found {
+ panic(fmt.Errorf("found two conflicting modules %q in apex %q: %s and %s",
+ moduleInApex.module, moduleInApex.apex, found, child))
+ }
+ found = child
+ }
+ return false
+ })
+ if found != nil {
+ modules = append(modules, found)
+ if existing, exists := modulesToApex[found]; exists && existing != moduleInApex.apex {
+ ctx.ModuleErrorf("module %s is in two apexes, %s and %s", moduleInApex.module, existing, moduleInApex.apex)
+ } else {
+ modulesToApex[found] = moduleInApex.apex
+ }
+ } else if !ctx.Config().AllowMissingDependencies() {
+ ctx.ModuleErrorf("failed to find module %q in apex %q\n",
+ moduleInApex.module, moduleInApex.apex)
+ }
+ }
+ return modules, modulesToApex
}
// ApexVariantReference specifies a particular apex variant of a module.
@@ -165,7 +226,7 @@
// addDependenciesOntoFragments adds dependencies to the fragments specified in this properties
// structure.
func (p *BootclasspathFragmentsDepsProperties) addDependenciesOntoFragments(ctx android.BottomUpMutatorContext) {
- addDependencyOntoApexVariants(ctx, "fragments", p.Fragments, bootclasspathFragmentDepTag)
+ addDependencyOntoApexVariants(ctx, "fragments", p.Fragments, fragment)
}
// bootclasspathDependencyTag defines dependencies from/to bootclasspath_fragment,
@@ -174,23 +235,38 @@
type bootclasspathDependencyTag struct {
blueprint.BaseDependencyTag
- name string
+ typ bootclasspathDependencyTagType
+
+ // moduleInApex is set to the name of the desired module when this dependency points
+ // to the apex that the modules is contained in.
+ moduleInApex string
}
+type bootclasspathDependencyTagType int
+
+const (
+ // The tag used for dependencies onto bootclasspath_fragments.
+ fragment bootclasspathDependencyTagType = iota
+ // The tag used for dependencies onto platform_bootclasspath.
+ platform
+ dexpreoptBootJar
+ artBootJar
+ platformBootJar
+ apexBootJar
+)
+
func (t bootclasspathDependencyTag) ExcludeFromVisibilityEnforcement() {
}
+func (t bootclasspathDependencyTag) LicenseAnnotations() []android.LicenseAnnotation {
+ return []android.LicenseAnnotation{android.LicenseAnnotationSharedDependency}
+}
+
// Dependencies that use the bootclasspathDependencyTag instances are only added after all the
// visibility checking has been done so this has no functional effect. However, it does make it
// clear that visibility is not being enforced on these tags.
var _ android.ExcludeFromVisibilityEnforcementTag = bootclasspathDependencyTag{}
-// The tag used for dependencies onto bootclasspath_fragments.
-var bootclasspathFragmentDepTag = bootclasspathDependencyTag{name: "fragment"}
-
-// The tag used for dependencies onto platform_bootclasspath.
-var platformBootclasspathDepTag = bootclasspathDependencyTag{name: "platform"}
-
// BootclasspathNestedAPIProperties defines properties related to the API provided by parts of the
// bootclasspath that are nested within the main BootclasspathAPIProperties.
type BootclasspathNestedAPIProperties struct {
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index 375a1aa..a09416d 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -41,6 +41,10 @@
ctx.RegisterModuleType("prebuilt_bootclasspath_fragment", prebuiltBootclasspathFragmentFactory)
}
+type BootclasspathFragmentInfo struct{}
+
+var BootclasspathFragmentInfoProvider = blueprint.NewProvider[BootclasspathFragmentInfo]()
+
// BootclasspathFragmentSdkMemberType is the member type used to add bootclasspath_fragments to
// the SDK snapshot. It is exported for use by apex.
var BootclasspathFragmentSdkMemberType = &bootclasspathFragmentMemberType{
@@ -89,6 +93,19 @@
// The tag used for the dependency between the bootclasspath_fragment module and its contents.
var bootclasspathFragmentContentDepTag = bootclasspathFragmentContentDependencyTag{}
+type moduleInFragmentDependencyTag struct {
+ blueprint.DependencyTag
+}
+
+func (m moduleInFragmentDependencyTag) ExcludeFromVisibilityEnforcement() {
+}
+
+// moduleInFragmentDepTag is added alongside bootclasspathFragmentContentDependencyTag,
+// but doesn't set ReplaceSourceWithPrebuilt. It is used to find modules in the fragment
+// by traversing from the apex to the fragment to the module, which prevents having to
+// construct a dependency on the apex variant of the fragment directly.
+var moduleInFragmentDepTag = moduleInFragmentDependencyTag{}
+
var _ android.ExcludeFromVisibilityEnforcementTag = bootclasspathFragmentContentDepTag
var _ android.ReplaceSourceWithPrebuilt = bootclasspathFragmentContentDepTag
var _ android.SdkMemberDependencyTag = bootclasspathFragmentContentDepTag
@@ -239,6 +256,8 @@
profilePathErr error
}
+var _ android.ApexModule = (*BootclasspathFragmentModule)(nil)
+
// commonBootclasspathFragment defines the methods that are implemented by both source and prebuilt
// bootclasspath fragment modules.
type commonBootclasspathFragment interface {
@@ -290,6 +309,10 @@
return m
}
+func (m *BootclasspathFragmentModule) UniqueApexVariations() bool {
+ return true
+}
+
func (m *BootclasspathFragmentModule) bootclasspathFragmentPropertyCheck(ctx android.ModuleContext) {
contents := m.properties.Contents.GetOrDefault(ctx, nil)
if len(contents) == 0 {
@@ -393,11 +416,17 @@
return i.profileInstallPathInApex
}
-func (b *BootclasspathFragmentModule) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
- tag := ctx.OtherModuleDependencyTag(dep)
+func (m *BootclasspathFragmentModule) GetDepInSameApexChecker() android.DepInSameApexChecker {
+ return BootclasspathFragmentDepInSameApexChecker{}
+}
+type BootclasspathFragmentDepInSameApexChecker struct {
+ android.BaseDepInSameApexChecker
+}
+
+func (b BootclasspathFragmentDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
// If the module is a default module, do not check the tag
- if _, ok := dep.(*Defaults); ok {
+ if tag == android.DefaultsDepTag {
return true
}
if IsBootclasspathFragmentContentDepTag(tag) {
@@ -408,17 +437,31 @@
// Cross-cutting metadata dependencies are metadata.
return false
}
+ if tag == moduleInFragmentDepTag {
+ return true
+ }
// Dependency to the bootclasspath fragment of another apex
// e.g. concsrypt-bootclasspath-fragment --> art-bootclasspath-fragment
- if tag == bootclasspathFragmentDepTag {
+ if bcpTag, ok := tag.(bootclasspathDependencyTag); ok && bcpTag.typ == fragment {
return false
-
}
- panic(fmt.Errorf("boot_image module %q should not have a dependency on %q via tag %s", b, dep, android.PrettyPrintTag(tag)))
+ if tag == moduleInFragmentDepTag {
+ return false
+ }
+ if tag == dexpreopt.Dex2oatDepTag {
+ return false
+ }
+ if tag == android.PrebuiltDepTag {
+ return false
+ }
+ if _, ok := tag.(hiddenAPIStubsDependencyTag); ok {
+ return false
+ }
+ panic(fmt.Errorf("boot_image module should not have a dependency tag %s", android.PrettyPrintTag(tag)))
}
-func (b *BootclasspathFragmentModule) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
- return nil
+func (m *BootclasspathFragmentModule) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
+ return android.MinApiLevel
}
// ComponentDepsMutator adds dependencies onto modules before any prebuilt modules without a
@@ -456,24 +499,24 @@
}
}
- if !dexpreopt.IsDex2oatNeeded(ctx) {
- return
+ if dexpreopt.IsDex2oatNeeded(ctx) {
+ // Add a dependency onto the dex2oat tool which is needed for creating the boot image. The
+ // path is retrieved from the dependency by GetGlobalSoongConfig(ctx).
+ dexpreopt.RegisterToolDeps(ctx)
}
- // Add a dependency onto the dex2oat tool which is needed for creating the boot image. The
- // path is retrieved from the dependency by GetGlobalSoongConfig(ctx).
- dexpreopt.RegisterToolDeps(ctx)
-
// Add a dependency to `all_apex_contributions` to determine if prebuilts are active.
// If prebuilts are active, `contents` validation on the source bootclasspath fragment should be disabled.
if _, isPrebuiltModule := ctx.Module().(*PrebuiltBootclasspathFragmentModule); !isPrebuiltModule {
ctx.AddDependency(b, android.AcDepTag, "all_apex_contributions")
}
-}
-func (b *BootclasspathFragmentModule) BootclasspathDepsMutator(ctx android.BottomUpMutatorContext) {
// Add dependencies on all the fragments.
b.properties.BootclasspathFragmentsDepsProperties.addDependenciesOntoFragments(ctx)
+
+ for _, name := range b.properties.Contents.GetOrDefault(ctx, nil) {
+ ctx.AddDependency(ctx.Module(), moduleInFragmentDepTag, name)
+ }
}
func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -496,7 +539,7 @@
}
})
- fragments := gatherApexModulePairDepsWithTag(ctx, bootclasspathFragmentDepTag)
+ fragments, _ := gatherFragments(ctx)
// Perform hidden API processing.
hiddenAPIOutput := b.generateHiddenAPIBuildActions(ctx, contents, fragments)
@@ -518,6 +561,8 @@
if !ctx.IsFinalModule(ctx.Module()) {
b.HideFromMake()
}
+
+ android.SetProvider(ctx, BootclasspathFragmentInfoProvider, BootclasspathFragmentInfo{})
}
// getProfileProviderApex returns the name of the apex that provides a boot image profile, or an
@@ -529,19 +574,18 @@
}
// Bootclasspath fragment modules that are for the platform do not produce boot related files.
- apexInfos, _ := android.ModuleProvider(ctx, android.AllApexInfoProvider)
- if apexInfos == nil {
+ apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
+ if apexInfo.IsForPlatform() {
return ""
}
- for _, apexInfo := range apexInfos.ApexInfos {
- for _, apex := range apexInfo.InApexVariants {
- if isProfileProviderApex(ctx, apex) {
- return apex
+ for _, config := range genBootImageConfigs(ctx) {
+ if config.profileProviderModule == b.BaseModuleName() {
+ if len(config.profileImports) > 0 {
+ return config.profileImports[0]
}
}
}
-
return ""
}
@@ -605,7 +649,7 @@
if android.IsModulePrebuilt(ctx.Module()) {
// prebuilt bcpf. the validation of this will be done at the top-level apex
providerClasspathFragmentValidationInfoProvider(ctx, unknown)
- } else if !disableSourceApexVariant(ctx) {
+ } else if !disableSourceApexVariant(ctx) && android.IsModulePreferred(ctx.Module()) {
// source bcpf, and prebuilt apex are not selected.
ctx.ModuleErrorf("%s in contents must also be declared in PRODUCT_APEX_BOOT_JARS", unknown)
}
@@ -1141,6 +1185,13 @@
android.InitPrebuiltModule(m, &[]string{"placeholder"})
android.InitApexModule(m)
android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibCommon)
+ android.InitDefaultableModule(m)
+
+ m.SetDefaultableHook(func(mctx android.DefaultableHookContext) {
+ if mctx.Config().AlwaysUsePrebuiltSdks() {
+ m.prebuilt.ForcePrefer()
+ }
+ })
return m
}
diff --git a/java/bootclasspath_fragment_test.go b/java/bootclasspath_fragment_test.go
index 3aa1258..87b853c 100644
--- a/java/bootclasspath_fragment_test.go
+++ b/java/bootclasspath_fragment_test.go
@@ -31,6 +31,7 @@
)
func TestBootclasspathFragment_UnknownImageName(t *testing.T) {
+ t.Parallel()
prepareForTestWithBootclasspathFragment.
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
`\Qimage_name: unknown image name "unknown", expected "art"\E`)).
@@ -50,6 +51,7 @@
}
func TestPrebuiltBootclasspathFragment_UnknownImageName(t *testing.T) {
+ t.Parallel()
prepareForTestWithBootclasspathFragment.
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
`\Qimage_name: unknown image name "unknown", expected "art"\E`)).
@@ -68,6 +70,7 @@
}
func TestBootclasspathFragmentInconsistentArtConfiguration_Platform(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForTestWithBootclasspathFragment,
dexpreopt.FixtureSetArtBootJars("platform:foo", "apex:bar"),
@@ -99,6 +102,7 @@
}
func TestBootclasspathFragmentInconsistentArtConfiguration_ApexMixture(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForTestWithBootclasspathFragment,
dexpreopt.FixtureSetArtBootJars("apex1:foo", "apex2:bar"),
@@ -131,6 +135,7 @@
}
func TestBootclasspathFragment_Coverage(t *testing.T) {
+ t.Parallel()
prepareWithBp := android.FixtureWithRootAndroidBp(`
bootclasspath_fragment {
name: "myfragment",
@@ -204,11 +209,13 @@
)
t.Run("without coverage", func(t *testing.T) {
+ t.Parallel()
result := preparer.RunTest(t)
checkContents(t, result, "mybootlib")
})
t.Run("with coverage", func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForTestWithFrameworkJacocoInstrumentation,
preparer,
@@ -364,7 +371,7 @@
}
`)
- fragment := result.ModuleForTests("myfragment", "android_common")
+ fragment := result.ModuleForTests(t, "myfragment", "android_common")
dependencyStubDexFlag := "--dependency-stub-dex=out/soong/.intermediates/default/java/android-non-updatable.stubs.test_module_lib/android_common/dex/android-non-updatable.stubs.test_module_lib.jar"
stubFlagsCommand := fragment.Output("modular-hiddenapi/stub-flags.csv").RuleParams.Command
android.AssertStringDoesContain(t,
@@ -472,7 +479,7 @@
// Make sure that the signature-patterns.csv is passed all the appropriate package properties
// from the bootclasspath_fragment and its contents.
- fragment := result.ModuleForTests("mybootclasspathfragment", "android_common")
+ fragment := result.ModuleForTests(t, "mybootclasspathfragment", "android_common")
rule := fragment.Output("modular-hiddenapi/signature-patterns.csv")
expectedCommand := strings.Join([]string{
"--split-package newlibrary",
diff --git a/java/builder.go b/java/builder.go
index 895ddb6..dff0032 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -46,6 +46,7 @@
`mkdir -p "$outDir" "$annoDir" "$srcJarDir" && ` +
`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
`(if [ -s $srcJarDir/list ] || [ -s $out.rsp ] ; then ` +
+ `${config.FindInputDeltaCmd} --template '' --target "$out" --inputs_file "$out.rsp" && ` +
`${config.SoongJavacWrapper} $javaTemplate${config.JavacCmd} ` +
`${config.JavacHeapFlags} ${config.JavacVmFlags} ${config.CommonJdkFlags} ` +
`$processorpath $processor $javacFlags $bootClasspath $classpath ` +
@@ -55,8 +56,10 @@
`$zipTemplate${config.SoongZipCmd} -jar -o $out.tmp -C $outDir -D $outDir && ` +
`if ! cmp -s "$out.tmp" "$out"; then mv "$out.tmp" "$out"; fi && ` +
`if ! cmp -s "$annoSrcJar.tmp" "$annoSrcJar"; then mv "$annoSrcJar.tmp" "$annoSrcJar"; fi && ` +
+ `if [ -f "$out.pc_state.new" ]; then mv "$out.pc_state.new" "$out.pc_state"; fi && ` +
`rm -rf "$srcJarDir" "$outDir"`,
CommandDeps: []string{
+ "${config.FindInputDeltaCmd}",
"${config.JavacCmd}",
"${config.SoongZipCmd}",
"${config.ZipSyncCmd}",
@@ -165,7 +168,7 @@
"${config.JavaCmd}",
},
Rspfile: "$out.rsp",
- RspfileContent: "$in",
+ RspfileContent: "$in_newline",
Restat: true,
},
&remoteexec.REParams{Labels: map[string]string{"type": "tool", "name": "turbine"},
@@ -223,6 +226,12 @@
},
"jarArgs")
+ extractR8Rules = pctx.AndroidStaticRule("extractR8Rules",
+ blueprint.RuleParams{
+ Command: `${config.ExtractR8RulesCmd} --rules-output $out --include-origin-comments $in`,
+ CommandDeps: []string{"${config.ExtractR8RulesCmd}"},
+ })
+
jarjar = pctx.AndroidStaticRule("jarjar",
blueprint.RuleParams{
Command: "" +
@@ -235,12 +244,12 @@
// for newly repackaged classes. Dropping @UnsupportedAppUsage on repackaged classes
// avoids adding new hiddenapis after jarjar'ing.
" -DremoveAndroidCompatAnnotations=true" +
- " -jar ${config.JarjarCmd} process $rulesFile $in $out && " +
+ " -jar ${config.JarjarCmd} process $rulesFile $in $out $total_shards $shard_index && " +
// Turn a missing output file into a ninja error
`[ -e ${out} ] || (echo "Missing output file"; exit 1)`,
CommandDeps: []string{"${config.JavaCmd}", "${config.JarjarCmd}", "$rulesFile"},
},
- "rulesFile")
+ "rulesFile", "total_shards", "shard_index")
packageCheck = pctx.AndroidStaticRule("packageCheck",
blueprint.RuleParams{
@@ -301,7 +310,7 @@
gatherReleasedFlaggedApisRule = pctx.AndroidStaticRule("gatherReleasedFlaggedApisRule",
blueprint.RuleParams{
- Command: `${aconfig} dump-cache --dedup --format='{fully_qualified_name}' ` +
+ Command: `${aconfig} dump-cache --dedup --format=protobuf ` +
`--out ${out} ` +
`${flags_path} ` +
`${filter_args} `,
@@ -311,8 +320,15 @@
generateMetalavaRevertAnnotationsRule = pctx.AndroidStaticRule("generateMetalavaRevertAnnotationsRule",
blueprint.RuleParams{
- Command: `${keep-flagged-apis} ${in} > ${out}`,
- CommandDeps: []string{"${keep-flagged-apis}"},
+ Command: `${aconfig-to-metalava-flags} ${in} > ${out}`,
+ CommandDeps: []string{"${aconfig-to-metalava-flags}"},
+ })
+
+ generateApiXMLRule = pctx.AndroidStaticRule("generateApiXMLRule",
+ blueprint.RuleParams{
+ Command: `${config.JavaCmd} ${config.JavaVmFlags} -Xmx4g -jar ${config.MetalavaJar} jar-to-jdiff ${in} ${out}`,
+ CommandDeps: []string{"${config.JavaCmd}", "${config.MetalavaJar}"},
+ Description: "Converting API file to XML",
})
)
@@ -323,7 +339,7 @@
pctx.HostBinToolVariable("aconfig", "aconfig")
pctx.HostBinToolVariable("ravenizer", "ravenizer")
pctx.HostBinToolVariable("apimapper", "apimapper")
- pctx.HostBinToolVariable("keep-flagged-apis", "keep-flagged-apis")
+ pctx.HostBinToolVariable("aconfig-to-metalava-flags", "aconfig-to-metalava-flags")
}
type javaBuilderFlags struct {
@@ -456,9 +472,10 @@
const srcJarArgsLimit = 32 * 1024
if len(srcJarArgs) > srcJarArgsLimit {
srcJarRspFile := android.PathForModuleOut(ctx, "turbine", "srcjars.rsp")
- android.WriteFileRule(ctx, srcJarRspFile, srcJarArgs)
+ android.WriteFileRule(ctx, srcJarRspFile, strings.Join(srcJars.Strings(), "\n"))
srcJarArgs = "@" + srcJarRspFile.String()
implicits = append(implicits, srcJarRspFile)
+ rspFiles = append(rspFiles, srcJarRspFile)
rbeInputs = append(rbeInputs, srcJarRspFile)
} else {
rbeInputs = append(rbeInputs, srcJars...)
@@ -488,7 +505,7 @@
const classpathLimit = 32 * 1024
if len(classpathFlags) > classpathLimit {
classpathRspFile := android.PathForModuleOut(ctx, dir, "classpath.rsp")
- android.WriteFileRule(ctx, classpathRspFile, classpathFlags)
+ android.WriteFileRule(ctx, classpathRspFile, strings.Join(classpath.Strings(), "\n"))
classpathFlags = "@" + classpathRspFile.String()
implicits = append(implicits, classpathRspFile)
rspFiles = append(rspFiles, classpathRspFile)
@@ -736,6 +753,16 @@
})
}
+func TransformJarToR8Rules(ctx android.ModuleContext, outputFile android.WritablePath,
+ jar android.Path) {
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: extractR8Rules,
+ Output: outputFile,
+ Input: jar,
+ })
+}
+
func convertImplementationJarToHeaderJar(ctx android.ModuleContext, implementationJarFile android.Path,
headerJarFile android.WritablePath) {
ctx.Build(pctx, android.BuildParams{
@@ -747,16 +774,58 @@
func TransformJarJar(ctx android.ModuleContext, outputFile android.WritablePath,
classesJar android.Path, rulesFile android.Path) {
+ TransformJarJarWithShards(ctx, outputFile, classesJar, rulesFile, 1)
+}
+
+func TransformJarJarWithShards(ctx android.ModuleContext, outputFile android.WritablePath,
+ classesJar android.Path, rulesFile android.Path, totalShards int) {
+
+ // If the total number of shards is 1, just run jarjar as-is, with `total_shards` = 1
+ // and `shard_index` == 0, which effectively disables sharding
+ if totalShards == 1 {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: jarjar,
+ Description: "jarjar",
+ Output: outputFile,
+ Input: classesJar,
+ Implicit: rulesFile,
+ Args: map[string]string{
+ "rulesFile": rulesFile.String(),
+ "total_shards": "1",
+ "shard_index": "0",
+ },
+ })
+ return
+ }
+
+ // Otherwise, run multiple jarjar instances and use merge_zips to combine the output.
+ tempJars := make([]android.Path, 0)
+ totalStr := strconv.Itoa(totalShards)
+ for i := 0; i < totalShards; i++ {
+ iStr := strconv.Itoa(i)
+ tempOut := outputFile.ReplaceExtension(ctx, "-"+iStr+".jar")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: jarjar,
+ Description: "jarjar (" + iStr + "/" + totalStr + ")",
+ Output: tempOut,
+ Input: classesJar,
+ Implicit: rulesFile,
+ Args: map[string]string{
+ "rulesFile": rulesFile.String(),
+ "total_shards": totalStr,
+ "shard_index": iStr,
+ },
+ })
+ tempJars = append(tempJars, tempOut)
+ }
+
ctx.Build(pctx, android.BuildParams{
- Rule: jarjar,
- Description: "jarjar",
+ Rule: combineJar,
+ Description: "merge jarjar shards",
Output: outputFile,
- Input: classesJar,
- Implicit: rulesFile,
- Args: map[string]string{
- "rulesFile": rulesFile.String(),
- },
+ Inputs: tempJars,
})
+
}
func CheckJarPackages(ctx android.ModuleContext, outputFile android.WritablePath,
diff --git a/java/classpath_element.go b/java/classpath_element.go
index abbcae7..4af2770 100644
--- a/java/classpath_element.go
+++ b/java/classpath_element.go
@@ -108,33 +108,18 @@
//
// e.g. Given the following input:
//
-// libraries: com.android.art:core-oj, com.android.art:core-libart, framework, ext
-// fragments: com.android.art:art-bootclasspath-fragment
+// libraries: core-oj, core-libart, framework, ext
+// fragments: art-bootclasspath-fragment
+// libraryToApex: core-oj: com.android.art, core-libart: com.android.art
+// apexNameToFragment: com.android.art: art-bootclasspath-fragment
//
// Then this will return:
//
// ClasspathFragmentElement(art-bootclasspath-fragment, [core-oj, core-libart]),
// ClasspathLibraryElement(framework),
// ClasspathLibraryElement(ext),
-func CreateClasspathElements(ctx ClasspathElementContext, libraries []android.Module, fragments []android.Module) ClasspathElements {
- // Create a map from apex name to the fragment module. This makes it easy to find the fragment
- // associated with a particular apex.
- apexToFragment := map[string]android.Module{}
- for _, fragment := range fragments {
- apexInfo, ok := android.OtherModuleProvider(ctx, fragment, android.ApexInfoProvider)
- if !ok {
- ctx.ModuleErrorf("fragment %s is not part of an apex", fragment)
- continue
- }
-
- for _, apex := range apexInfo.InApexVariants {
- if existing, ok := apexToFragment[apex]; ok {
- ctx.ModuleErrorf("apex %s has multiple fragments, %s and %s", apex, fragment, existing)
- continue
- }
- apexToFragment[apex] = fragment
- }
- }
+func CreateClasspathElements(ctx ClasspathElementContext, libraries []android.Module, fragments []android.Module,
+ libraryToApex map[android.Module]string, apexNameToFragment map[string]android.Module) ClasspathElements {
fragmentToElement := map[android.Module]*ClasspathFragmentElement{}
elements := []ClasspathElement{}
@@ -144,31 +129,28 @@
// Iterate over the libraries to construct the ClasspathElements list.
for _, library := range libraries {
var element ClasspathElement
- if apexInfo, ok := android.OtherModuleProvider(ctx, library, android.ApexInfoProvider); ok {
-
+ if libraryApex, ok := libraryToApex[library]; ok {
var fragment android.Module
// Make sure that the library is in only one fragment of the classpath.
- for _, apex := range apexInfo.InApexVariants {
- if f, ok := apexToFragment[apex]; ok {
- if fragment == nil {
- // This is the first fragment so just save it away.
- fragment = f
- } else if f != fragment {
- // This apex variant of the library is in a different fragment.
- ctx.ModuleErrorf("library %s is in two separate fragments, %s and %s", library, fragment, f)
- // Skip over this library entirely as otherwise the resulting classpath elements would
- // be invalid.
- continue skipLibrary
- }
- } else {
- // There is no fragment associated with the library's apex.
+ if f, ok := apexNameToFragment[libraryApex]; ok {
+ if fragment == nil {
+ // This is the first fragment so just save it away.
+ fragment = f
+ } else if f != fragment {
+ // This apex variant of the library is in a different fragment.
+ ctx.ModuleErrorf("library %s is in two separate fragments, %s and %s", library, fragment, f)
+ // Skip over this library entirely as otherwise the resulting classpath elements would
+ // be invalid.
+ continue skipLibrary
}
+ } else {
+ // There is no fragment associated with the library's apex.
}
if fragment == nil {
ctx.ModuleErrorf("library %s is from apexes %s which have no corresponding fragment in %s",
- library, apexInfo.InApexVariants, fragments)
+ library, []string{libraryApex}, fragments)
// Skip over this library entirely as otherwise the resulting classpath elements would
// be invalid.
continue skipLibrary
diff --git a/java/config/config.go b/java/config/config.go
index 87703d8..fdb8d78 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -159,6 +159,7 @@
pctx.SourcePathVariable("ResourceProcessorBusyBox", "prebuilts/bazel/common/android_tools/android_tools/all_android_tools_deploy.jar")
pctx.HostBinToolVariable("GenKotlinBuildFileCmd", "gen-kotlin-build-file")
+ pctx.HostBinToolVariable("FindInputDeltaCmd", "find_input_delta")
pctx.SourcePathVariable("JarArgsCmd", "build/soong/scripts/jar-args.sh")
pctx.SourcePathVariable("PackageCheckCmd", "build/soong/scripts/package-check.sh")
@@ -170,7 +171,9 @@
pctx.HostBinToolVariable("ApiCheckCmd", "apicheck")
pctx.HostBinToolVariable("D8Cmd", "d8")
pctx.HostBinToolVariable("R8Cmd", "r8")
+ pctx.HostBinToolVariable("ExtractR8RulesCmd", "extract-r8-rules")
pctx.HostBinToolVariable("ResourceShrinkerCmd", "resourceshrinker")
+ pctx.HostBinToolVariable("TraceReferencesCmd", "tracereferences")
pctx.HostBinToolVariable("HiddenAPICmd", "hiddenapi")
pctx.HostBinToolVariable("ExtractApksCmd", "extract_apks")
pctx.VariableFunc("TurbineJar", func(ctx android.PackageVarContext) string {
diff --git a/java/config/kotlin.go b/java/config/kotlin.go
index 302d021..ffb025d 100644
--- a/java/config/kotlin.go
+++ b/java/config/kotlin.go
@@ -21,6 +21,7 @@
KotlincIllegalFlags = []string{
"-no-jdk",
"-no-stdlib",
+ "-language-version",
}
)
@@ -56,5 +57,5 @@
// platform that are not fully compatible with the kotlinc used in g3 kythe indexers.
// e.g. uninitialized variables are a warning in 1.*, but an error in 2.*
// https://github.com/JetBrains/kotlin/blob/master/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt#L748
- pctx.StaticVariable("KotlincKytheGlobalFlags", strings.Join([]string{"-language-version 1.9"}, " "))
+ pctx.StaticVariable("KotlincKytheGlobalFlags", strings.Join([]string{}, " "))
}
diff --git a/java/container_test.go b/java/container_test.go
index 25cfa4c..35a3020 100644
--- a/java/container_test.go
+++ b/java/container_test.go
@@ -26,6 +26,7 @@
}
func TestJavaContainersModuleProperties(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
).RunTestWithBp(t, `
@@ -154,7 +155,7 @@
}
for _, c := range testcases {
- m := result.ModuleForTests(c.moduleName, "android_common")
+ m := result.ModuleForTests(t, c.moduleName, "android_common")
containers, _ := android.OtherModuleProvider(result.TestContext.OtherModuleProviderAdaptor(), m.Module(), android.ContainersInfoProvider)
belongingContainers := containers.BelongingContainers()
checkContainerMatch(t, c.moduleName, "system", c.isSystemContainer, android.InList(android.SystemContainer, belongingContainers))
diff --git a/java/device_host_converter.go b/java/device_host_converter.go
index bfacea6..04def3e 100644
--- a/java/device_host_converter.go
+++ b/java/device_host_converter.go
@@ -140,7 +140,7 @@
d.combinedHeaderJar = d.headerJars[0]
}
- android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
+ javaInfo := &JavaInfo{
HeaderJars: d.headerJars,
LocalHeaderJars: d.headerJars,
TransitiveStaticLibsHeaderJars: depset.New(depset.PREORDER, nil, transitiveHeaderJars),
@@ -154,7 +154,9 @@
StubsLinkType: Implementation,
// TODO: Not sure if aconfig flags that have been moved between device and host variants
// make sense.
- })
+ }
+ setExtraJavaInfo(ctx, d, javaInfo)
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
}
diff --git a/java/device_host_converter_test.go b/java/device_host_converter_test.go
index 6ccc5c1..42e3b46 100644
--- a/java/device_host_converter_test.go
+++ b/java/device_host_converter_test.go
@@ -15,13 +15,15 @@
package java
import (
- "android/soong/android"
"slices"
"strings"
"testing"
+
+ "android/soong/android"
)
func TestDeviceForHost(t *testing.T) {
+ t.Parallel()
bp := `
java_library {
name: "device_module",
@@ -52,15 +54,15 @@
ctx, config := testJava(t, bp)
- deviceModule := ctx.ModuleForTests("device_module", "android_common")
- deviceTurbineCombined := deviceModule.Output("turbine-combined/device_module.jar")
+ deviceModule := ctx.ModuleForTests(t, "device_module", "android_common")
+ deviceTurbine := deviceModule.Output("turbine/device_module.jar")
deviceJavac := deviceModule.Output("javac/device_module.jar")
deviceRes := deviceModule.Output("res/device_module.jar")
- deviceImportModule := ctx.ModuleForTests("device_import_module", "android_common")
- deviceImportCombined := deviceImportModule.Output("combined/device_import_module.jar")
+ deviceImportModule := ctx.ModuleForTests(t, "device_import_module", "android_common")
+ deviceImportCombined := deviceImportModule.Output("local-combined/device_import_module.jar")
- hostModule := ctx.ModuleForTests("host_module", config.BuildOSCommonTarget.String())
+ hostModule := ctx.ModuleForTests(t, "host_module", config.BuildOSCommonTarget.String())
hostJavac := hostModule.Output("javac/host_module.jar")
hostRes := hostModule.Output("res/host_module.jar")
combined := hostModule.Output("combined/host_module.jar")
@@ -68,7 +70,7 @@
// check classpath of host module with dependency on device_for_host_module
expectedClasspath := "-classpath " + strings.Join(android.Paths{
- deviceTurbineCombined.Output,
+ deviceTurbine.Output,
deviceImportCombined.Output,
}.Strings(), ":")
@@ -102,6 +104,7 @@
}
func TestHostForDevice(t *testing.T) {
+ t.Parallel()
bp := `
java_library_host {
name: "host_module",
@@ -133,15 +136,15 @@
ctx, config := testJava(t, bp)
- hostModule := ctx.ModuleForTests("host_module", config.BuildOSCommonTarget.String())
+ hostModule := ctx.ModuleForTests(t, "host_module", config.BuildOSCommonTarget.String())
hostJavac := hostModule.Output("javac/host_module.jar")
- hostJavacHeader := hostModule.Output("javac-header/host_module.jar")
+ hostJavacHeader := hostModule.Output("local-javac-header/host_module.jar")
hostRes := hostModule.Output("res/host_module.jar")
- hostImportModule := ctx.ModuleForTests("host_import_module", config.BuildOSCommonTarget.String())
- hostImportCombined := hostImportModule.Output("combined/host_import_module.jar")
+ hostImportModule := ctx.ModuleForTests(t, "host_import_module", config.BuildOSCommonTarget.String())
+ hostImportCombined := hostImportModule.Output("local-combined/host_import_module.jar")
- deviceModule := ctx.ModuleForTests("device_module", "android_common")
+ deviceModule := ctx.ModuleForTests(t, "device_module", "android_common")
deviceJavac := deviceModule.Output("javac/device_module.jar")
deviceRes := deviceModule.Output("res/device_module.jar")
combined := deviceModule.Output("combined/device_module.jar")
diff --git a/java/dex.go b/java/dex.go
index 2b3c931..e3058e9 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -42,13 +42,39 @@
// True if the module containing this has it set by default.
EnabledByDefault bool `blueprint:"mutated"`
+ // If true, then `d8` will be used on eng builds instead of `r8`, even though
+ // optimize.enabled is true.
+ D8_on_eng *bool
+
+ // Whether to allow that library classes inherit from program classes.
+ // Defaults to false.
+ Ignore_library_extends_program *bool
+
// Whether to continue building even if warnings are emitted. Defaults to true.
Ignore_warnings *bool
+ // Whether runtime invisible annotations should be kept by R8. Defaults to false.
+ // This is equivalent to:
+ // -keepattributes RuntimeInvisibleAnnotations,
+ // RuntimeInvisibleParameterAnnotations,
+ // RuntimeInvisibleTypeAnnotations
+ // This is only applicable when RELEASE_R8_ONLY_RUNTIME_VISIBLE_ANNOTATIONS is
+ // enabled and will be used to migrate away from keeping runtime invisible
+ // annotations (b/387958004).
+ Keep_runtime_invisible_annotations *bool
+
// If true, runs R8 in Proguard compatibility mode, otherwise runs R8 in full mode.
- // Defaults to false for apps, true for libraries and tests.
+ // Defaults to false for apps and tests, true for libraries.
Proguard_compatibility *bool
+ // If true, R8 will not add public or protected members (fields or methods) to
+ // the API surface of the compilation unit, i.e., classes that are kept or
+ // have kept subclasses will not expose any members added by R8 for internal
+ // use. That includes renamed members if obfuscation is enabled.
+ // This should only be used for building targets that go on the bootclasspath.
+ // Defaults to false.
+ Protect_api_surface *bool
+
// If true, optimize for size by removing unused code. Defaults to true for apps,
// false for libraries and tests.
Shrink *bool
@@ -81,6 +107,34 @@
// If true, transitive reverse dependencies of this module will have this
// module's proguard spec appended to their optimization action
Export_proguard_flags_files *bool
+
+ // Path to a file containing a list of class names that should not be compiled using R8.
+ // These classes will be compiled by D8 similar to when Optimize.Enabled is false.
+ //
+ // Example:
+ //
+ // r8.exclude:
+ // com.example.Foo
+ // com.example.Bar
+ // com.example.Bar$Baz
+ //
+ // By default all classes are compiled using R8 when Optimize.Enabled is set.
+ Exclude *string `android:"path"`
+
+ // Optional list of downstream (Java) libraries from which to trace and preserve references
+ // when optimizing. Note that this requires that the source reference does *not* have
+ // a strict lib dependency on this target; dependencies should be on intermediate targets
+ // statically linked into this target, e.g., if A references B, and we want to trace and
+ // keep references from A when optimizing B, you would create an intermediate B.impl (
+ // containing all static code), have A depend on `B.impl` via libs, and set
+ // `trace_references_from: ["A"]` on B.
+ //
+ // Also note that these are *not* inherited across targets, they must be specified at the
+ // top-level target that is optimized.
+ //
+ // TODO(b/212737576): Handle this implicitly using bottom-up deps mutation and implicit
+ // creation of a proxy `.impl` library.
+ Trace_references_from proptools.Configurable[[]string] `android:"arch_variant"`
}
// Keep the data uncompressed. We always need uncompressed dex for execution,
@@ -111,7 +165,12 @@
providesTransitiveHeaderJarsForR8
}
-func (d *dexer) effectiveOptimizeEnabled() bool {
+func (d *dexer) effectiveOptimizeEnabled(ctx android.EarlyModuleContext) bool {
+ // For eng builds, if Optimize.D8_on_eng is true, then disable optimization.
+ if ctx.Config().Eng() && proptools.Bool(d.dexProperties.Optimize.D8_on_eng) {
+ return false
+ }
+ // Otherwise, use the legacy logic of a default value which can be explicitly overridden by the module.
return BoolDefault(d.dexProperties.Optimize.Enabled, d.dexProperties.Optimize.EnabledByDefault)
}
@@ -123,8 +182,8 @@
return d.resourceShrinkingEnabled(ctx) && BoolDefault(d.Optimize.Optimized_shrink_resources, ctx.Config().UseOptimizedResourceShrinkingByDefault())
}
-func (d *dexer) optimizeOrObfuscateEnabled() bool {
- return d.effectiveOptimizeEnabled() && (proptools.Bool(d.dexProperties.Optimize.Optimize) || proptools.Bool(d.dexProperties.Optimize.Obfuscate))
+func (d *dexer) optimizeOrObfuscateEnabled(ctx android.EarlyModuleContext) bool {
+ return d.effectiveOptimizeEnabled(ctx) && (proptools.Bool(d.dexProperties.Optimize.Optimize) || proptools.Bool(d.dexProperties.Optimize.Obfuscate))
}
var d8, d8RE = pctx.MultiCommandRemoteStaticRules("d8",
@@ -156,6 +215,71 @@
},
}, []string{"outDir", "d8Flags", "zipFlags", "mergeZipsFlags"}, nil)
+// Include all of the args for d8r8, so that we can generate the partialcompileclean target's build using the same list.
+var d8r8Clean = pctx.AndroidStaticRule("d8r8-partialcompileclean",
+ blueprint.RuleParams{
+ Command: `rm -rf "${outDir}" "${outDict}" "${outConfig}" "${outUsage}" "${outUsageZip}" "${outUsageDir}" ` +
+ `"${resourcesOutput}" "${outR8ArtProfile}" ${builtOut}`,
+ }, "outDir", "outDict", "outConfig", "outUsage", "outUsageZip", "outUsageDir", "builtOut",
+ "d8Flags", "r8Flags", "zipFlags", "mergeZipsFlags", "resourcesOutput", "outR8ArtProfile", "implicits",
+)
+
+var d8r8, d8r8RE = pctx.MultiCommandRemoteStaticRules("d8r8",
+ blueprint.RuleParams{
+ Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
+ `rm -f "$outDict" && rm -f "$outConfig" && rm -rf "${outUsageDir}" && ` +
+ `mkdir -p $$(dirname ${outUsage}) && ` +
+ `if [ -n "$${SOONG_USE_PARTIAL_COMPILE}" ]; then ` +
+ ` for f in "${outConfig}" "${outDict}" "${outUsage}" "${resourcesOutput}"; do ` +
+ ` test -n "$${f}" && test ! -f "$${f}" && mkdir -p "$$(dirname "$${f}")" && touch "$${f}" || true; ` +
+ ` done && ` +
+ ` $d8Template${config.D8Cmd} ${config.D8Flags} $d8Flags --output $outDir --no-dex-input-jar $in; ` +
+ `else ` +
+ ` $r8Template${config.R8Cmd} ${config.R8Flags} $r8Flags -injars $in --output $outDir ` +
+ ` --no-data-resources ` +
+ ` -printmapping ${outDict} ` +
+ ` -printconfiguration ${outConfig} ` +
+ ` -printusage ${outUsage} ` +
+ ` --deps-file ${out}.d && ` +
+ ` touch "${outDict}" "${outConfig}" "${outUsage}"; ` +
+ `fi && ` +
+ `${config.SoongZipCmd} -o ${outUsageZip} -C ${outUsageDir} -f ${outUsage} && ` +
+ `rm -rf ${outUsageDir} && ` +
+ `$zipTemplate${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` +
+ `${config.MergeZipsCmd} -D -stripFile "**/*.class" $mergeZipsFlags $out $outDir/classes.dex.jar $in && ` +
+ `rm -f "$outDir"/classes*.dex "$outDir/classes.dex.jar" `,
+ CommandDeps: []string{
+ "${config.D8Cmd}",
+ "${config.R8Cmd}",
+ "${config.SoongZipCmd}",
+ "${config.MergeZipsCmd}",
+ },
+ }, map[string]*remoteexec.REParams{
+ "$d8Template": &remoteexec.REParams{
+ Labels: map[string]string{"type": "compile", "compiler": "d8"},
+ Inputs: []string{"${config.D8Jar}"},
+ ExecStrategy: "${config.RED8ExecStrategy}",
+ ToolchainInputs: []string{"${config.JavaCmd}"},
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ },
+ "$r8Template": &remoteexec.REParams{
+ Labels: map[string]string{"type": "compile", "compiler": "r8"},
+ Inputs: []string{"$implicits", "${config.R8Jar}"},
+ OutputFiles: []string{"${outUsage}", "${outConfig}", "${outDict}", "${resourcesOutput}", "${outR8ArtProfile}"},
+ ExecStrategy: "${config.RER8ExecStrategy}",
+ ToolchainInputs: []string{"${config.JavaCmd}"},
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ },
+ "$zipTemplate": &remoteexec.REParams{
+ Labels: map[string]string{"type": "tool", "name": "soong_zip"},
+ Inputs: []string{"${config.SoongZipCmd}", "$outDir"},
+ OutputFiles: []string{"$outDir/classes.dex.jar"},
+ ExecStrategy: "${config.RED8ExecStrategy}",
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ },
+ }, []string{"outDir", "outDict", "outConfig", "outUsage", "outUsageZip", "outUsageDir",
+ "d8Flags", "r8Flags", "zipFlags", "mergeZipsFlags", "resourcesOutput", "outR8ArtProfile"}, []string{"implicits"})
+
var r8, r8RE = pctx.MultiCommandRemoteStaticRules("r8",
blueprint.RuleParams{
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
@@ -220,21 +344,29 @@
deps = append(deps, f)
}
- var requestReleaseMode bool
+ var requestReleaseMode, requestDebugMode bool
requestReleaseMode, flags = android.RemoveFromList("--release", flags)
+ requestDebugMode, flags = android.RemoveFromList("--debug", flags)
if ctx.Config().Getenv("NO_OPTIMIZE_DX") != "" || ctx.Config().Getenv("GENERATE_DEX_DEBUG") != "" {
- flags = append(flags, "--debug")
+ requestDebugMode = true
requestReleaseMode = false
}
// Don't strip out debug information for eng builds, unless the target
// explicitly provided the `--release` build flag. This allows certain
// test targets to remain optimized as part of eng test_suites builds.
- if requestReleaseMode {
+ if requestDebugMode {
+ flags = append(flags, "--debug")
+ } else if requestReleaseMode {
flags = append(flags, "--release")
} else if ctx.Config().Eng() {
flags = append(flags, "--debug")
+ } else if !d.effectiveOptimizeEnabled(ctx) && d.dexProperties.Optimize.EnabledByDefault {
+ // D8 uses --debug by default, whereas R8 uses --release by default.
+ // For targets that default to R8 usage (e.g., apps), but override this default, we still
+ // want D8 to run in release mode, preserving semantics as much as possible between the two.
+ flags = append(flags, "--release")
}
// Supplying the platform build flag disables various features like API modeling and desugaring.
@@ -306,7 +438,7 @@
// TODO(b/360905238): Remove SdkSystemServer exception after resolving missing class references.
if !dexParams.sdkVersion.Stable() || dexParams.sdkVersion.Kind == android.SdkSystemServer {
var proguardRaiseDeps classpath
- ctx.VisitDirectDepsWithTag(proguardRaiseTag, func(m android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(proguardRaiseTag, func(m android.ModuleProxy) {
if dep, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
proguardRaiseDeps = append(proguardRaiseDeps, dep.RepackagedHeaderJars...)
}
@@ -340,11 +472,30 @@
android.PathForSource(ctx, "build/make/core/proguard.flags"),
}
+ if ctx.Config().UseR8GlobalCheckNotNullFlags() {
+ flagFiles = append(flagFiles, android.PathForSource(ctx,
+ "build/make/core/proguard/checknotnull.flags"))
+ }
+
flagFiles = append(flagFiles, d.extraProguardFlagsFiles...)
// TODO(ccross): static android library proguard files
flagFiles = append(flagFiles, android.PathsForModuleSrc(ctx, opt.Proguard_flags_files)...)
+ traceReferencesSources := android.Paths{}
+ ctx.VisitDirectDepsProxyWithTag(traceReferencesTag, func(m android.ModuleProxy) {
+ if dep, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
+ traceReferencesSources = append(traceReferencesSources, dep.ImplementationJars...)
+ }
+ })
+ if len(traceReferencesSources) > 0 {
+ traceTarget := dexParams.classesJar
+ traceLibs := android.FirstUniquePaths(append(flags.bootClasspath.Paths(), flags.dexClasspath.Paths()...))
+ traceReferencesFlags := android.PathForModuleOut(ctx, "proguard", "trace_references.flags")
+ TraceReferences(ctx, traceReferencesSources, traceTarget, traceLibs, traceReferencesFlags)
+ flagFiles = append(flagFiles, traceReferencesFlags)
+ }
+
flagFiles = android.FirstUniquePaths(flagFiles)
r8Flags = append(r8Flags, android.JoinWithPrefix(flagFiles.Strings(), "-include "))
@@ -356,10 +507,22 @@
r8Flags = append(r8Flags, opt.Proguard_flags...)
- if BoolDefault(opt.Proguard_compatibility, true) {
+ if BoolDefault(opt.Ignore_library_extends_program, false) {
+ r8Flags = append(r8Flags, "--ignore-library-extends-program")
+ }
+
+ if BoolDefault(opt.Keep_runtime_invisible_annotations, false) {
+ r8Flags = append(r8Flags, "--keep-runtime-invisible-annotations")
+ }
+
+ if BoolDefault(opt.Proguard_compatibility, !ctx.Config().UseR8FullModeByDefault()) {
r8Flags = append(r8Flags, "--force-proguard-compatibility")
}
+ if BoolDefault(opt.Protect_api_surface, false) {
+ r8Flags = append(r8Flags, "--protect-api-surface")
+ }
+
// Avoid unnecessary stack frame noise by only injecting source map ids for non-debug
// optimized or obfuscated targets.
if (Bool(opt.Optimize) || Bool(opt.Obfuscate)) && !debugMode {
@@ -412,6 +575,15 @@
artProfileOutput = profileOutput
}
+ if ctx.Config().UseR8StoreStoreFenceConstructorInlining() {
+ r8Flags = append(r8Flags, "--store-store-fence-constructor-inlining")
+ }
+
+ if opt.Exclude != nil {
+ r8Flags = append(r8Flags, "--exclude", *opt.Exclude)
+ r8Deps = append(r8Deps, android.PathForModuleSrc(ctx, *opt.Exclude))
+ }
+
return r8Flags, r8Deps, artProfileOutput
}
@@ -448,6 +620,7 @@
// Compile classes.jar into classes.dex and then javalib.jar
javalibJar := android.PathForModuleOut(ctx, "dex", dexParams.jarName).OutputPath
+ cleanPhonyPath := android.PathForModuleOut(ctx, "dex", dexParams.jarName+"-partialcompileclean").OutputPath
outDir := android.PathForModuleOut(ctx, "dex")
zipFlags := "--ignore_missing_files"
@@ -463,8 +636,20 @@
mergeZipsFlags = "-stripFile META-INF/*.kotlin_module -stripFile **/*.kotlin_builtins"
}
- useR8 := d.effectiveOptimizeEnabled()
+ useR8 := d.effectiveOptimizeEnabled(ctx)
+ useD8 := !useR8 || ctx.Config().PartialCompileFlags().Use_d8
+ rbeR8 := ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_R8")
+ rbeD8 := ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_D8")
+ var rule blueprint.Rule
+ var description string
var artProfileOutputPath *android.OutputPath
+ var implicitOutputs android.WritablePaths
+ var deps android.Paths
+ args := map[string]string{
+ "zipFlags": zipFlags,
+ "outDir": outDir.String(),
+ "mergeZipsFlags": mergeZipsFlags,
+ }
if useR8 {
proguardDictionary := android.PathForModuleOut(ctx, "proguard_dictionary")
d.proguardDictionary = android.OptionalPathForPath(proguardDictionary)
@@ -477,83 +662,89 @@
d.proguardUsageZip = android.OptionalPathForPath(proguardUsageZip)
resourcesOutput := android.PathForModuleOut(ctx, "package-res-shrunken.apk")
d.resourcesOutput = android.OptionalPathForPath(resourcesOutput)
- implicitOutputs := android.WritablePaths{
+ implicitOutputs = append(implicitOutputs, android.WritablePaths{
proguardDictionary,
proguardUsageZip,
proguardConfiguration,
- }
+ }...)
+ description = "r8"
debugMode := android.InList("--debug", commonFlags)
r8Flags, r8Deps, r8ArtProfileOutputPath := d.r8Flags(ctx, dexParams, debugMode)
- rule := r8
- args := map[string]string{
- "r8Flags": strings.Join(append(commonFlags, r8Flags...), " "),
- "zipFlags": zipFlags,
- "outDict": proguardDictionary.String(),
- "outConfig": proguardConfiguration.String(),
- "outUsageDir": proguardUsageDir.String(),
- "outUsage": proguardUsage.String(),
- "outUsageZip": proguardUsageZip.String(),
- "outDir": outDir.String(),
- "mergeZipsFlags": mergeZipsFlags,
- }
+ deps = append(deps, r8Deps...)
+ args["r8Flags"] = strings.Join(append(commonFlags, r8Flags...), " ")
if r8ArtProfileOutputPath != nil {
artProfileOutputPath = r8ArtProfileOutputPath
- implicitOutputs = append(
- implicitOutputs,
- artProfileOutputPath,
- )
// Add the implicit r8 Art profile output to args so that r8RE knows
// about this implicit output
- args["outR8ArtProfile"] = artProfileOutputPath.String()
+ args["outR8ArtProfile"] = r8ArtProfileOutputPath.String()
}
-
- if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_R8") {
- rule = r8RE
- args["implicits"] = strings.Join(r8Deps.Strings(), ",")
- }
+ args["outDict"] = proguardDictionary.String()
+ args["outConfig"] = proguardConfiguration.String()
+ args["outUsageDir"] = proguardUsageDir.String()
+ args["outUsage"] = proguardUsage.String()
+ args["outUsageZip"] = proguardUsageZip.String()
if d.resourcesInput.Valid() {
implicitOutputs = append(implicitOutputs, resourcesOutput)
args["resourcesOutput"] = resourcesOutput.String()
}
- ctx.Build(pctx, android.BuildParams{
- Rule: rule,
- Description: "r8",
- Output: javalibJar,
- ImplicitOutputs: implicitOutputs,
- Input: dexParams.classesJar,
- Implicits: r8Deps,
- Args: args,
- })
- } else {
- implicitOutputs := android.WritablePaths{}
+
+ rule = r8
+ if rbeR8 {
+ rule = r8RE
+ args["implicits"] = strings.Join(deps.Strings(), ",")
+ }
+ }
+ if useD8 {
+ description = "d8"
d8Flags, d8Deps, d8ArtProfileOutputPath := d.d8Flags(ctx, dexParams)
+ deps = append(deps, d8Deps...)
+ deps = append(deps, commonDeps...)
+ args["d8Flags"] = strings.Join(append(commonFlags, d8Flags...), " ")
if d8ArtProfileOutputPath != nil {
artProfileOutputPath = d8ArtProfileOutputPath
- implicitOutputs = append(
- implicitOutputs,
- artProfileOutputPath,
- )
}
- d8Deps = append(d8Deps, commonDeps...)
- rule := d8
- if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_D8") {
+ // If we are generating both d8 and r8, only use RBE when both are enabled.
+ switch {
+ case useR8 && rule == r8:
+ rule = d8r8
+ description = "d8r8"
+ case useR8 && rule == r8RE && rbeD8:
+ rule = d8r8RE
+ description = "d8r8"
+ case rbeD8:
rule = d8RE
+ default:
+ rule = d8
}
- ctx.Build(pctx, android.BuildParams{
- Rule: rule,
- Description: "d8",
- Output: javalibJar,
- Input: dexParams.classesJar,
- ImplicitOutputs: implicitOutputs,
- Implicits: d8Deps,
- Args: map[string]string{
- "d8Flags": strings.Join(append(commonFlags, d8Flags...), " "),
- "zipFlags": zipFlags,
- "outDir": outDir.String(),
- "mergeZipsFlags": mergeZipsFlags,
- },
- })
}
+ if artProfileOutputPath != nil {
+ implicitOutputs = append(
+ implicitOutputs,
+ artProfileOutputPath,
+ )
+ }
+ ctx.Build(pctx, android.BuildParams{
+ Rule: rule,
+ Description: description,
+ Output: javalibJar,
+ ImplicitOutputs: implicitOutputs,
+ Input: dexParams.classesJar,
+ Implicits: deps,
+ Args: args,
+ })
+ if useR8 && useD8 {
+ // Generate the rule for partial compile clean.
+ args["builtOut"] = javalibJar.String()
+ ctx.Build(pctx, android.BuildParams{
+ Rule: d8r8Clean,
+ Description: "d8r8Clean",
+ Output: cleanPhonyPath,
+ Args: args,
+ PhonyOutput: true,
+ })
+ ctx.Phony("partialcompileclean", cleanPhonyPath)
+ }
+
if proptools.Bool(d.dexProperties.Uncompress_dex) {
alignedJavalibJar := android.PathForModuleOut(ctx, "aligned", dexParams.jarName).OutputPath
TransformZipAlign(ctx, alignedJavalibJar, javalibJar, nil)
@@ -562,3 +753,13 @@
return javalibJar, artProfileOutputPath
}
+
+type ProguardInfo struct {
+ ModuleName string
+ Class string
+ ProguardDictionary android.Path
+ ProguardUsageZip android.Path
+ ClassesJar android.Path
+}
+
+var ProguardProvider = blueprint.NewProvider[ProguardInfo]()
diff --git a/java/dex_test.go b/java/dex_test.go
index 8bc28e6..8c1e5f7 100644
--- a/java/dex_test.go
+++ b/java/dex_test.go
@@ -16,6 +16,7 @@
import (
"fmt"
+ "strconv"
"testing"
"android/soong/android"
@@ -24,6 +25,7 @@
)
func TestR8(t *testing.T) {
+ t.Parallel()
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
android_app {
name: "app",
@@ -58,26 +60,27 @@
}
`)
- app := result.ModuleForTests("app", "android_common")
- stableApp := result.ModuleForTests("stable_app", "android_common")
- corePlatformApp := result.ModuleForTests("core_platform_app", "android_common")
- lib := result.ModuleForTests("lib", "android_common")
- staticLib := result.ModuleForTests("static_lib", "android_common")
+ app := result.ModuleForTests(t, "app", "android_common")
+ stableApp := result.ModuleForTests(t, "stable_app", "android_common")
+ corePlatformApp := result.ModuleForTests(t, "core_platform_app", "android_common")
+ lib := result.ModuleForTests(t, "lib", "android_common")
+ staticLib := result.ModuleForTests(t, "static_lib", "android_common")
appJavac := app.Rule("javac")
appR8 := app.Rule("r8")
stableAppR8 := stableApp.Rule("r8")
corePlatformAppR8 := corePlatformApp.Rule("r8")
- libHeader := lib.Output("turbine-combined/lib.jar").Output
- staticLibHeader := staticLib.Output("turbine-combined/static_lib.jar").Output
+ libHeader := lib.Output("turbine/lib.jar").Output
+ libCombinedHeader := lib.Output("turbine-combined/lib.jar").Output
+ staticLibHeader := staticLib.Output("turbine/static_lib.jar").Output
android.AssertStringDoesContain(t, "expected lib header jar in app javac classpath",
appJavac.Args["classpath"], libHeader.String())
android.AssertStringDoesContain(t, "expected static_lib header jar in app javac classpath",
appJavac.Args["classpath"], staticLibHeader.String())
- android.AssertStringDoesContain(t, "expected lib header jar in app r8 classpath",
- appR8.Args["r8Flags"], libHeader.String())
+ android.AssertStringDoesContain(t, "expected lib combined header jar in app r8 classpath",
+ appR8.Args["r8Flags"], libCombinedHeader.String())
android.AssertStringDoesNotContain(t, "expected no static_lib header jar in app r8 classpath",
appR8.Args["r8Flags"], staticLibHeader.String())
android.AssertStringDoesContain(t, "expected -ignorewarnings in app r8 flags",
@@ -91,6 +94,7 @@
}
func TestR8TransitiveDeps(t *testing.T) {
+ t.Parallel()
bp := `
override_android_app {
name: "override_app",
@@ -192,6 +196,7 @@
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
+ t.Parallel()
fixturePreparer := PrepareForTestWithJavaDefaultModules
if tc.unbundled {
fixturePreparer = android.GroupFixturePreparers(
@@ -206,14 +211,14 @@
result := fixturePreparer.RunTestWithBp(t, bp)
getHeaderJar := func(name string) android.Path {
- mod := result.ModuleForTests(name, "android_common")
+ mod := result.ModuleForTests(t, name, "android_common")
return mod.Output("turbine-combined/" + name + ".jar").Output
}
- appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
- overrideAppR8 := result.ModuleForTests("app", "android_common_override_app").Rule("r8")
+ appR8 := result.ModuleForTests(t, "app", "android_common").Rule("r8")
+ overrideAppR8 := result.ModuleForTests(t, "app", "android_common_override_app").Rule("r8")
appHeader := getHeaderJar("app")
- overrideAppHeader := result.ModuleForTests("app", "android_common_override_app").Output("turbine-combined/app.jar").Output
+ overrideAppHeader := result.ModuleForTests(t, "app", "android_common_override_app").Output("turbine-combined/app.jar").Output
libHeader := getHeaderJar("lib")
transitiveLibHeader := getHeaderJar("transitive_lib")
transitiveLib2Header := getHeaderJar("transitive_lib_2")
@@ -222,7 +227,7 @@
repeatedDepHeader := getHeaderJar("repeated_dep")
usesLibHeader := getHeaderJar("uses_lib")
optionalUsesLibHeader := getHeaderJar("optional_uses_lib")
- prebuiltLibHeader := result.ModuleForTests("prebuilt_lib", "android_common").Output("combined/lib.jar").Output
+ prebuiltLibHeader := result.ModuleForTests(t, "prebuilt_lib", "android_common").Output("combined/lib.jar").Output
for _, rule := range []android.TestingBuildParams{appR8, overrideAppR8} {
android.AssertStringDoesNotContain(t, "expected no app header jar in app r8 classpath",
@@ -259,6 +264,7 @@
}
func TestR8Flags(t *testing.T) {
+ t.Parallel()
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
android_app {
name: "app",
@@ -273,7 +279,7 @@
}
`)
- app := result.ModuleForTests("app", "android_common")
+ app := result.ModuleForTests(t, "app", "android_common")
appR8 := app.Rule("r8")
android.AssertStringDoesContain(t, "expected -dontshrink in app r8 flags",
appR8.Args["r8Flags"], "-dontshrink")
@@ -288,6 +294,7 @@
}
func TestD8(t *testing.T) {
+ t.Parallel()
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
java_library {
name: "foo",
@@ -306,29 +313,52 @@
name: "static_lib",
srcs: ["foo.java"],
}
+
+ android_app {
+ name: "app",
+ srcs: ["foo.java"],
+ platform_apis: true,
+ optimize: {
+ enabled: false,
+ },
+ }
`)
- foo := result.ModuleForTests("foo", "android_common")
- lib := result.ModuleForTests("lib", "android_common")
- staticLib := result.ModuleForTests("static_lib", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
+ lib := result.ModuleForTests(t, "lib", "android_common")
+ app := result.ModuleForTests(t, "app", "android_common")
+ staticLib := result.ModuleForTests(t, "static_lib", "android_common")
fooJavac := foo.Rule("javac")
fooD8 := foo.Rule("d8")
- libHeader := lib.Output("turbine-combined/lib.jar").Output
- staticLibHeader := staticLib.Output("turbine-combined/static_lib.jar").Output
+ appD8 := app.Rule("d8")
+ libHeader := lib.Output("turbine/lib.jar").Output
+ libCombinedHeader := lib.Output("turbine-combined/lib.jar").Output
+ staticLibHeader := staticLib.Output("turbine/static_lib.jar").Output
android.AssertStringDoesContain(t, "expected lib header jar in foo javac classpath",
fooJavac.Args["classpath"], libHeader.String())
android.AssertStringDoesContain(t, "expected static_lib header jar in foo javac classpath",
fooJavac.Args["classpath"], staticLibHeader.String())
- android.AssertStringDoesContain(t, "expected lib header jar in foo d8 classpath",
- fooD8.Args["d8Flags"], libHeader.String())
+ android.AssertStringDoesContain(t, "expected lib combined header jar in foo d8 classpath",
+ fooD8.Args["d8Flags"], libCombinedHeader.String())
android.AssertStringDoesNotContain(t, "expected no static_lib header jar in foo javac classpath",
fooD8.Args["d8Flags"], staticLibHeader.String())
+
+ // A --release flag is added only for targets that opt out of default R8 behavior (e.g., apps).
+ // For library targets that don't use R8 by default, no --debug or --release flag should be
+ // added, instead relying on default D8 behavior (--debug).
+ android.AssertStringDoesContain(t, "expected --release in app d8 flags",
+ appD8.Args["d8Flags"], "--release")
+ android.AssertStringDoesNotContain(t, "expected no --release flag in lib d8 flags",
+ fooD8.Args["d8Flags"], "--release")
+ android.AssertStringDoesNotContain(t, "expected no --debug flag in lib d8 flags",
+ fooD8.Args["d8Flags"], "--debug")
}
func TestProguardFlagsInheritanceStatic(t *testing.T) {
+ t.Parallel()
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
android_app {
name: "app",
@@ -370,7 +400,7 @@
}
`)
- app := result.ModuleForTests("app", "android_common")
+ app := result.ModuleForTests(t, "app", "android_common")
appR8 := app.Rule("r8")
android.AssertStringDoesContain(t, "expected primary_lib's proguard flags from direct dep",
appR8.Args["r8Flags"], "primary.flags")
@@ -383,6 +413,7 @@
}
func TestProguardFlagsInheritance(t *testing.T) {
+ t.Parallel()
directDepFlagsFileName := "direct_dep.flags"
transitiveDepFlagsFileName := "transitive_dep.flags"
@@ -601,6 +632,7 @@
for _, topLevelModuleDef := range topLevelModules {
for _, tc := range testcases {
t.Run(topLevelModuleDef.name+"-"+tc.name, func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.FixtureMergeMockFs(android.MockFS{
@@ -617,7 +649,7 @@
tc.transitiveDepExportsFlagsFiles,
),
)
- appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
+ appR8 := result.ModuleForTests(t, "app", "android_common").Rule("r8")
shouldHaveDepFlags := android.InList(directDepFlagsFileName, tc.expectedFlagsFiles)
if shouldHaveDepFlags {
@@ -642,6 +674,7 @@
}
func TestProguardFlagsInheritanceAppImport(t *testing.T) {
+ t.Parallel()
bp := `
android_app {
name: "app",
@@ -658,12 +691,13 @@
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, bp)
- appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
+ appR8 := result.ModuleForTests(t, "app", "android_common").Rule("r8")
android.AssertStringDoesContain(t, "expected aarimports's proguard flags",
appR8.Args["r8Flags"], "proguard.txt")
}
func TestR8FlagsArtProfile(t *testing.T) {
+ t.Parallel()
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
android_app {
name: "app",
@@ -677,7 +711,7 @@
}
`)
- app := result.ModuleForTests("app", "android_common")
+ app := result.ModuleForTests(t, "app", "android_common")
appR8 := app.Rule("r8")
android.AssertStringDoesContain(t, "expected --art-profile in app r8 flags",
appR8.Args["r8Flags"], "--art-profile")
@@ -696,6 +730,7 @@
//
// The rewritten profile should be used since the dex signatures in the checked-in profile will not match the optimized binary.
func TestEnableProfileRewritingIsRequiredForOptimizedApps(t *testing.T) {
+ t.Parallel()
testJavaError(t,
"Enable_profile_rewriting must be true when profile_guided dexpreopt and R8 optimization/obfuscation is turned on",
`
@@ -715,11 +750,15 @@
}
func TestDebugReleaseFlags(t *testing.T) {
+ t.Parallel()
bp := `
android_app {
name: "app",
srcs: ["foo.java"],
platform_apis: true,
+ optimize: {
+ enabled: %s,
+ },
dxflags: ["%s"]
}
`
@@ -728,6 +767,7 @@
name string
envVar string
isEng bool
+ useD8 bool
dxFlags string
expectedFlags string
}{
@@ -757,20 +797,36 @@
},
{
name: "app_eng",
+ useD8: true,
isEng: true,
expectedFlags: "--debug",
},
{
name: "app_release_eng",
isEng: true,
+ useD8: true,
dxFlags: "--release",
// Eng mode does *not* override explicit dxflags.
expectedFlags: "--release",
},
+ {
+ name: "app_d8",
+ useD8: true,
+ // D8 usage w/ apps should explicitly enable --release mode.
+ expectedFlags: "--release",
+ },
+ {
+ name: "app_d8_debug",
+ useD8: true,
+ dxFlags: "--debug",
+ // D8 usage w/ apps respects overriding dxFlags.
+ expectedFlags: "--debug",
+ },
}
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
+ t.Parallel()
fixturePreparer := PrepareForTestWithJavaDefaultModules
fixturePreparer = android.GroupFixturePreparers(
fixturePreparer,
@@ -788,11 +844,16 @@
}),
)
}
- result := fixturePreparer.RunTestWithBp(t, fmt.Sprintf(bp, tc.dxFlags))
+ result := fixturePreparer.RunTestWithBp(t, fmt.Sprintf(bp, strconv.FormatBool(!tc.useD8), tc.dxFlags))
- appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
- android.AssertStringDoesContain(t, "expected flag in R8 flags",
- appR8.Args["r8Flags"], tc.expectedFlags)
+ dexRuleKey := "r8"
+ if tc.useD8 {
+ dexRuleKey = "d8"
+ }
+ dexFlagsKey := dexRuleKey + "Flags"
+ appDex := result.ModuleForTests(t, "app", "android_common").Rule(dexRuleKey)
+ android.AssertStringDoesContain(t, "expected flag in dex flags",
+ appDex.Args[dexFlagsKey], tc.expectedFlags)
var unexpectedFlags string
if tc.expectedFlags == "--debug" {
@@ -801,9 +862,52 @@
unexpectedFlags = "--debug"
}
if unexpectedFlags != "" {
- android.AssertStringDoesNotContain(t, "unexpected flag in R8 flags",
- appR8.Args["r8Flags"], unexpectedFlags)
+ android.AssertStringDoesNotContain(t, "unexpected flag in dex flags",
+ appDex.Args[dexFlagsKey], unexpectedFlags)
}
})
}
}
+
+func TestTraceReferences(t *testing.T) {
+ t.Parallel()
+ bp := `
+ android_app {
+ name: "app",
+ libs: ["lib.impl"],
+ srcs: ["foo.java"],
+ platform_apis: true,
+ }
+
+ java_library {
+ name: "lib",
+ optimize: {
+ enabled: true,
+ trace_references_from: ["app"],
+ },
+ srcs: ["bar.java"],
+ static_libs: ["lib.impl"],
+ installable: true,
+ }
+
+ java_library {
+ name: "lib.impl",
+ srcs: ["baz.java"],
+ }
+ `
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ ).RunTestWithBp(t, bp)
+
+ appJar := result.ModuleForTests(t, "app", "android_common").Output("combined/app.jar").Output
+ libJar := result.ModuleForTests(t, "lib", "android_common").Output("combined/lib.jar").Output
+ libTraceRefs := result.ModuleForTests(t, "lib", "android_common").Rule("traceReferences")
+ libR8 := result.ModuleForTests(t, "lib", "android_common").Rule("r8")
+
+ android.AssertStringDoesContain(t, "expected trace reference source from app jar",
+ libTraceRefs.Args["sources"], "--source "+appJar.String())
+ android.AssertStringEquals(t, "expected trace reference target into lib jar",
+ libJar.String(), libTraceRefs.Input.String())
+ android.AssertStringDoesContain(t, "expected trace reference proguard flags in lib r8 flags",
+ libR8.Args["r8Flags"], "trace_references.flags")
+}
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 5928446..e8e1cd4 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -36,61 +36,24 @@
// If the java module is to be installed into an APEX, this list contains information about the
// dexpreopt outputs to be installed on devices. Note that these dexpreopt outputs are installed
// outside of the APEX.
- DexpreoptBuiltInstalledForApex() []dexpreopterInstall
+ ApexSystemServerDexpreoptInstalls() []DexpreopterInstall
- // The Make entries to install the dexpreopt outputs. Derived from
- // `DexpreoptBuiltInstalledForApex`.
- AndroidMkEntriesForApex() []android.AndroidMkEntries
+ // ApexSystemServerDexJars returns the list of dex jars if this is an apex system server jar.
+ ApexSystemServerDexJars() android.Paths
// See `dexpreopter.outputProfilePathOnHost`.
OutputProfilePathOnHost() android.Path
}
-type dexpreopterInstall struct {
- // A unique name to distinguish an output from others for the same java library module. Usually in
- // the form of `<arch>-<encoded-path>.odex/vdex/art`.
- name string
-
- // The name of the input java module.
- moduleName string
-
+type DexpreopterInstall struct {
// The path to the dexpreopt output on host.
- outputPathOnHost android.Path
+ OutputPathOnHost android.Path
// The directory on the device for the output to install to.
- installDirOnDevice android.InstallPath
+ InstallDirOnDevice android.InstallPath
// The basename (the last segment of the path) for the output to install as.
- installFileOnDevice string
-}
-
-// The full module name of the output in the makefile.
-func (install *dexpreopterInstall) FullModuleName() string {
- return install.moduleName + install.SubModuleName()
-}
-
-// The sub-module name of the output in the makefile (the name excluding the java module name).
-func (install *dexpreopterInstall) SubModuleName() string {
- return "-dexpreopt-" + install.name
-}
-
-// Returns Make entries for installing the file.
-//
-// This function uses a value receiver rather than a pointer receiver to ensure that the object is
-// safe to use in `android.AndroidMkExtraEntriesFunc`.
-func (install dexpreopterInstall) ToMakeEntries() android.AndroidMkEntries {
- return android.AndroidMkEntries{
- Class: "ETC",
- OutputFile: android.OptionalPathForPath(install.outputPathOnHost),
- ExtraEntries: []android.AndroidMkExtraEntriesFunc{
- func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- entries.SetString("LOCAL_MODULE", install.FullModuleName())
- entries.SetString("LOCAL_MODULE_PATH", install.installDirOnDevice.String())
- entries.SetString("LOCAL_INSTALLED_MODULE_STEM", install.installFileOnDevice)
- entries.SetString("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", "false")
- },
- },
- }
+ InstallFileOnDevice string
}
type Dexpreopter struct {
@@ -120,8 +83,9 @@
classLoaderContexts dexpreopt.ClassLoaderContextMap
// See the `dexpreopt` function for details.
- builtInstalled string
- builtInstalledForApex []dexpreopterInstall
+ builtInstalled string
+ apexSystemServerDexpreoptInstalls []DexpreopterInstall
+ apexSystemServerDexJars android.Paths
// The config is used for two purposes:
// - Passing dexpreopt information about libraries from Soong to Make. This is needed when
@@ -204,27 +168,23 @@
}
apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
psi := android.PrebuiltSelectionInfoMap{}
- ctx.VisitDirectDeps(func(am android.Module) {
+ ctx.VisitDirectDepsProxy(func(am android.ModuleProxy) {
if prebuiltSelectionInfo, ok := android.OtherModuleProvider(ctx, am, android.PrebuiltSelectionInfoProvider); ok {
psi = prebuiltSelectionInfo
}
})
// Find the apex variant for this module
- apexVariantsWithoutTestApexes := []string{}
+ apexVariants := []string{}
if apexInfo.BaseApexName != "" {
- // This is a transitive dependency of an override_apex
- apexVariantsWithoutTestApexes = append(apexVariantsWithoutTestApexes, apexInfo.BaseApexName)
- } else {
- _, variants, _ := android.ListSetDifference(apexInfo.InApexVariants, apexInfo.TestApexes)
- apexVariantsWithoutTestApexes = append(apexVariantsWithoutTestApexes, variants...)
+ apexVariants = append(apexVariants, apexInfo.BaseApexName)
}
if apexInfo.ApexAvailableName != "" {
- apexVariantsWithoutTestApexes = append(apexVariantsWithoutTestApexes, apexInfo.ApexAvailableName)
+ apexVariants = append(apexVariants, apexInfo.ApexAvailableName)
}
disableSource := false
// find the selected apexes
- for _, apexVariant := range apexVariantsWithoutTestApexes {
+ for _, apexVariant := range apexVariants {
if len(psi.GetSelectedModulesForApiDomain(apexVariant)) > 0 {
// If the apex_contribution for this api domain is non-empty, disable the source variant
disableSource = true
@@ -279,20 +239,6 @@
if !isApexSystemServerJar {
return true
}
- ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
- allApexInfos := []android.ApexInfo{}
- if allApexInfosProvider, ok := android.ModuleProvider(ctx, android.AllApexInfoProvider); ok {
- allApexInfos = allApexInfosProvider.ApexInfos
- }
- if len(allApexInfos) > 0 && !ai.MinSdkVersion.EqualTo(allApexInfos[0].MinSdkVersion) {
- // Apex system server jars are dexpreopted and installed on to the system image.
- // Since we can have BigAndroid and Go variants of system server jar providing apexes,
- // and these two variants can have different min_sdk_versions, hide one of the apex variants
- // from make to prevent collisions.
- //
- // Unlike cc, min_sdk_version does not have an effect on the build actions of java libraries.
- ctx.Module().MakeUninstallable()
- }
} else {
// Don't preopt the platform variant of an APEX system server jar to avoid conflicts.
if isApexSystemServerJar {
@@ -347,7 +293,11 @@
d.installPath = android.PathForModuleInPartitionInstall(ctx, "", strings.TrimPrefix(dexpreopt.GetSystemServerDexLocation(ctx, dc, libraryName), "/"))
// generate the rules for creating the .odex and .vdex files for this system server jar
dexJarFile := di.PrebuiltExportPath(ApexRootRelativePathToJavaLib(libraryName))
-
+ if dexJarFile == nil {
+ ctx.ModuleErrorf(
+ `Could not find library %s in prebuilt apex %s.
+Please make sure that the value of PRODUCT_APEX_(SYSTEM_SERVER|STANDALONE_SYSTEM_SERVER)_JARS is correct`, libraryName, ctx.ModuleName())
+ }
d.inputProfilePathOnHost = nil // reset: TODO(spandandas): Make dexpreopter stateless
if android.InList(libraryName, di.GetDexpreoptProfileGuidedExportedModuleNames()) {
// Set the profile path to guide optimization
@@ -539,12 +489,8 @@
Output(appProductPackages)
productPackagesRule.Restat().Build("product_packages."+dexJarStem, "dexpreopt product_packages")
- // Prebuilts are active, do not copy the dexpreopt'd source javalib to out/soong/system_server_dexjars
- // The javalib from the deapexed prebuilt will be copied to this location.
- // TODO (b/331665856): Implement a principled solution for this.
- copyApexSystemServerJarDex := !disableSourceApexVariant(ctx) && !ctx.Module().IsHideFromMake()
dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(
- ctx, globalSoong, global, dexpreoptConfig, appProductPackages, copyApexSystemServerJarDex)
+ ctx, globalSoong, global, dexpreoptConfig, appProductPackages)
if err != nil {
ctx.ModuleErrorf("error generating dexpreopt rule: %s", err.Error())
return
@@ -577,7 +523,6 @@
partition = ""
}
installBase := filepath.Base(install.To)
- arch := filepath.Base(installDir)
installPath := android.PathForModuleInPartitionInstall(ctx, partition, installDir)
isProfile := strings.HasSuffix(installBase, ".prof")
@@ -593,16 +538,13 @@
// libraries, only those in the system server classpath are handled here.
// Preopting of boot classpath jars in the ART APEX are handled in
// java/dexpreopt_bootjars.go, and other APEX jars are not preopted.
- // The installs will be handled by Make as sub-modules of the java library.
- di := dexpreopterInstall{
- name: arch + "-" + installBase,
- moduleName: libName,
- outputPathOnHost: install.From,
- installDirOnDevice: installPath,
- installFileOnDevice: installBase,
+ // The installs will be handled the apex module that includes this library.
+ di := DexpreopterInstall{
+ OutputPathOnHost: install.From,
+ InstallDirOnDevice: installPath,
+ InstallFileOnDevice: installBase,
}
- ctx.InstallFile(di.installDirOnDevice, di.installFileOnDevice, di.outputPathOnHost)
- d.builtInstalledForApex = append(d.builtInstalledForApex, di)
+ d.apexSystemServerDexpreoptInstalls = append(d.apexSystemServerDexpreoptInstalls, di)
}
} else if !d.preventInstall {
@@ -611,9 +553,22 @@
}
}
+ if isApexSystemServerJar {
+ // Store the dex jar location for system server jars in apexes, the apex will copy the file into
+ // a known location for dex2oat.
+ d.apexSystemServerDexJars = append(d.apexSystemServerDexJars, dexJarFile)
+ } else if isSystemServerJar && !d.preventInstall {
+ // Copy the dex jar into a known location for dex2oat for non-apex system server jars.
+ android.CopyFileRule(ctx, dexJarFile, android.PathForOutput(ctx, dexpreopt.SystemServerDexjarsDir, dexJarFile.Base()))
+ }
+
if !isApexSystemServerJar {
d.builtInstalled = dexpreoptRule.Installs().String()
}
+
+ if isSystemServerJar {
+ checkSystemServerOrder(ctx, libName)
+ }
}
func getModuleInstallPathInfo(ctx android.ModuleContext, fullInstallPath string) (android.InstallPath, string, string) {
@@ -645,16 +600,12 @@
}
}
-func (d *dexpreopter) DexpreoptBuiltInstalledForApex() []dexpreopterInstall {
- return d.builtInstalledForApex
+func (d *dexpreopter) ApexSystemServerDexpreoptInstalls() []DexpreopterInstall {
+ return d.apexSystemServerDexpreoptInstalls
}
-func (d *dexpreopter) AndroidMkEntriesForApex() []android.AndroidMkEntries {
- var entries []android.AndroidMkEntries
- for _, install := range d.builtInstalledForApex {
- entries = append(entries, install.ToMakeEntries())
- }
- return entries
+func (d *dexpreopter) ApexSystemServerDexJars() android.Paths {
+ return d.apexSystemServerDexJars
}
func (d *dexpreopter) OutputProfilePathOnHost() android.Path {
@@ -684,3 +635,33 @@
func (d *dexpreopter) SetRewrittenProfile(p android.Path) {
d.rewrittenProfile = p
}
+
+// Check the order of jars on the system server classpath and give a warning/error if a jar precedes
+// one of its dependencies. This is not an error, but a missed optimization, as dexpreopt won't
+// have the dependency jar in the class loader context, and it won't be able to resolve any
+// references to its classes and methods.
+func checkSystemServerOrder(ctx android.ModuleContext, libName string) {
+ config := dexpreopt.GetGlobalConfig(ctx)
+ jars := config.AllSystemServerClasspathJars(ctx)
+ jarIndex := config.AllSystemServerJars(ctx).IndexOfJar(libName)
+ ctx.WalkDeps(func(dep android.Module, parent android.Module) bool {
+ tag := ctx.OtherModuleDependencyTag(dep)
+ // Ideally this should only be walking relevant dependencies, but to maintain existing behavior
+ // for now just exclude any known irrelevant dependencies that would lead to incorrect errors.
+ if _, ok := tag.(bootclasspathDependencyTag); ok {
+ return false
+ } else if tag == traceReferencesTag {
+ // Allow ordering inversion if the dependency is purely for tracing references.
+ return false
+ }
+ depIndex := jars.IndexOfJar(dep.Name())
+ if jarIndex < depIndex && !config.BrokenSuboptimalOrderOfSystemServerJars {
+ jar := jars.Jar(jarIndex)
+ dep := jars.Jar(depIndex)
+ ctx.ModuleErrorf("non-optimal order of jars on the system server classpath:"+
+ " '%s' precedes its dependency '%s', so dexpreopt is unable to resolve any"+
+ " references from '%s' to '%s'.\n", jar, dep, jar, dep)
+ }
+ return true
+ })
+}
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 8c60d23..2287043 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -15,6 +15,7 @@
package java
import (
+ "fmt"
"path/filepath"
"strings"
@@ -225,7 +226,6 @@
}
var (
- dexpreoptBootJarDepTag = bootclasspathDependencyTag{name: "dexpreopt-boot-jar"}
dexBootJarsFragmentsKey = android.NewOnceKey("dexBootJarsFragments")
apexContributionsMetadataDepTag = dependencyTag{name: "all_apex_contributions"}
)
@@ -293,6 +293,9 @@
// Profiles imported from APEXes, in addition to the profile at the default path. Each entry must
// be the name of an APEX module.
profileImports []string
+
+ // The name of the module that provides boot image profiles, if any.
+ profileProviderModule string
}
// Target-dependent description of a boot image.
@@ -464,9 +467,6 @@
func RegisterDexpreoptBootJarsComponents(ctx android.RegistrationContext) {
ctx.RegisterParallelSingletonModuleType("dex_bootjars", dexpreoptBootJarsFactory)
ctx.RegisterModuleType("art_boot_images", artBootImagesFactory)
- ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.BottomUp("dex_bootjars_deps", DexpreoptBootJarsMutator)
- })
}
func SkipDexpreoptBootJars(ctx android.PathContext) bool {
@@ -502,12 +502,6 @@
func (dbj *dexpreoptBootJars) DepsMutator(ctx android.BottomUpMutatorContext) {
// Create a dependency on all_apex_contributions to determine the selected mainline module
ctx.AddDependency(ctx.Module(), apexContributionsMetadataDepTag, "all_apex_contributions")
-}
-
-func DexpreoptBootJarsMutator(ctx android.BottomUpMutatorContext) {
- if _, ok := ctx.Module().(*dexpreoptBootJars); !ok {
- return
- }
if dexpreopt.IsDex2oatNeeded(ctx) {
// Add a dependency onto the dex2oat tool which is needed for creating the boot image. The
@@ -521,7 +515,7 @@
continue
}
// For accessing the boot jars.
- addDependenciesOntoBootImageModules(ctx, config.modules, dexpreoptBootJarDepTag)
+ addDependenciesOntoBootImageModules(ctx, config.modules, dexpreoptBootJar)
// Create a dependency on the apex selected using RELEASE_APEX_CONTRIBUTIONS_*
// TODO: b/308174306 - Remove the direct depedendency edge to the java_library (source/prebuilt) once all mainline modules
// have been flagged using RELEASE_APEX_CONTRIBUTIONS_*
@@ -534,11 +528,11 @@
if ctx.OtherModuleExists("platform-bootclasspath") {
// For accessing all bootclasspath fragments.
- addDependencyOntoApexModulePair(ctx, "platform", "platform-bootclasspath", platformBootclasspathDepTag)
+ addDependencyOntoApexModulePair(ctx, "platform", "platform-bootclasspath", platform)
} else if ctx.OtherModuleExists("art-bootclasspath-fragment") {
// For accessing the ART bootclasspath fragment on a thin manifest (e.g., master-art) where
// platform-bootclasspath doesn't exist.
- addDependencyOntoApexModulePair(ctx, "com.android.art", "art-bootclasspath-fragment", bootclasspathFragmentDepTag)
+ addDependencyOntoApexModulePair(ctx, "com.android.art", "art-bootclasspath-fragment", fragment)
}
}
@@ -556,13 +550,13 @@
// We need to add a dep on only the apex listed in `contents` of the selected apex_contributions module
// This is not available in a structured format in `apex_contributions`, so this hack adds a dep on all `contents`
// (some modules like art.module.public.api do not have an apex variation since it is a pure stub module that does not get installed)
- apexVariationOfSelected := append(ctx.Target().Variations(), blueprint.Variation{Mutator: "apex", Variation: apex})
- if ctx.OtherModuleDependencyVariantExists(apexVariationOfSelected, selected) {
- ctx.AddFarVariationDependencies(apexVariationOfSelected, dexpreoptBootJarDepTag, selected)
- } else if ctx.OtherModuleDependencyVariantExists(apexVariationOfSelected, android.RemoveOptionalPrebuiltPrefix(selected)) {
- // The prebuilt might have been renamed by prebuilt_rename mutator if the source module does not exist.
- // Remove the prebuilt_ prefix.
- ctx.AddFarVariationDependencies(apexVariationOfSelected, dexpreoptBootJarDepTag, android.RemoveOptionalPrebuiltPrefix(selected))
+ tag := bootclasspathDependencyTag{
+ typ: dexpreoptBootJar,
+ }
+
+ dep := android.RemoveOptionalPrebuiltPrefix(selected)
+ if ctx.OtherModuleDependencyVariantExists(ctx.Target().Variations(), dep) {
+ ctx.AddFarVariationDependencies(ctx.Target().Variations(), tag, dep)
}
}
}
@@ -571,23 +565,55 @@
func gatherBootclasspathFragments(ctx android.ModuleContext) map[string]android.Module {
return ctx.Config().Once(dexBootJarsFragmentsKey, func() interface{} {
fragments := make(map[string]android.Module)
+
+ type moduleInApexPair struct {
+ module string
+ apex string
+ }
+
+ var modulesInApexes []moduleInApexPair
+
+ // Find the list of modules in apexes.
ctx.WalkDeps(func(child, parent android.Module) bool {
if !isActiveModule(ctx, child) {
return false
}
tag := ctx.OtherModuleDependencyTag(child)
- if tag == platformBootclasspathDepTag {
- return true
- }
- if tag == bootclasspathFragmentDepTag {
- apexInfo, _ := android.OtherModuleProvider(ctx, child, android.ApexInfoProvider)
- for _, apex := range apexInfo.InApexVariants {
- fragments[apex] = child
+ if bcpTag, ok := tag.(bootclasspathDependencyTag); ok {
+ if bcpTag.typ == platform {
+ return true
}
- return false
+ if bcpTag.typ == fragment {
+ if bcpTag.moduleInApex == "" {
+ panic(fmt.Errorf("expected fragment to be in apex"))
+ }
+ modulesInApexes = append(modulesInApexes, moduleInApexPair{bcpTag.moduleInApex, ctx.OtherModuleName(child)})
+ return true
+ }
}
return false
})
+
+ for _, moduleInApex := range modulesInApexes {
+ // Find a desired module in an apex.
+ ctx.WalkDeps(func(child, parent android.Module) bool {
+ t := ctx.OtherModuleDependencyTag(child)
+ if bcpTag, ok := t.(bootclasspathDependencyTag); ok {
+ if bcpTag.typ == platform {
+ return true
+ }
+ if bcpTag.typ == fragment && ctx.OtherModuleName(child) == moduleInApex.apex {
+ // This is the dependency from this module to the apex, recurse into it.
+ return true
+ }
+ } else if android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child)) == moduleInApex.module {
+ // This is the desired module inside the apex.
+ fragments[android.RemoveOptionalPrebuiltPrefix(moduleInApex.apex)] = child
+ }
+ return false
+ })
+ }
+
return fragments
}).(map[string]android.Module)
}
@@ -649,6 +675,139 @@
installs: artBootImageHostInstalls,
},
)
+
+ d.buildBootZip(ctx)
+}
+
+// Build the boot.zip which contains the boot jars and their compilation output
+// We can do this only if preopt is enabled and if the product uses libart config (which sets the
+// default properties for preopting).
+// Origionally, this was only for ART Cloud.
+func (d *dexpreoptBootJars) buildBootZip(ctx android.ModuleContext) {
+ image := d.defaultBootImage
+ if image == nil || SkipDexpreoptBootJars(ctx) {
+ return
+ }
+ global := dexpreopt.GetGlobalConfig(ctx)
+ globalSoong := dexpreopt.GetGlobalSoongConfig(ctx)
+ if global.DisablePreopt || global.OnlyPreoptArtBootImage {
+ return
+ }
+
+ bootclasspathDexFiles, bootclassPathLocations := bcpForDexpreopt(ctx, global.PreoptWithUpdatableBcp)
+ if len(bootclasspathDexFiles) == 0 {
+ return
+ }
+
+ systemServerDexjarsDir := android.PathForOutput(ctx, dexpreopt.SystemServerDexjarsDir)
+
+ bootZipMetadataTmp := android.PathForModuleOut(ctx, "boot_zip", "METADATA.txt.tmp")
+ bootZipMetadata := android.PathForModuleOut(ctx, "boot_zip", "METADATA.txt")
+ newlineFile := android.PathForModuleOut(ctx, "boot_zip", "newline.txt")
+ android.WriteFileRule(ctx, newlineFile, "")
+
+ dexPreoptRootDir := filepath.Dir(filepath.Dir(bootclasspathDexFiles[0].String()))
+
+ var sb strings.Builder
+ sb.WriteString("bootclasspath = ")
+ for i, bootclasspathJar := range bootclasspathDexFiles {
+ if i > 0 {
+ sb.WriteString(":")
+ }
+ rel, err := filepath.Rel(dexPreoptRootDir, bootclasspathJar.String())
+ if err != nil {
+ ctx.ModuleErrorf("All dexpreopt jars should be under the same rootdir %q, but %q wasn't.", dexPreoptRootDir, bootclasspathJar)
+ } else {
+ sb.WriteString(rel)
+ }
+ }
+ sb.WriteString("\nbootclasspath-locations = ")
+ for i, bootclasspathLocation := range bootclassPathLocations {
+ if i > 0 {
+ sb.WriteString(":")
+ }
+ sb.WriteString(bootclasspathLocation)
+ }
+ sb.WriteString("\nboot-image = ")
+
+ // Infix can be 'art' (ART image for testing), 'boot' (primary), or 'mainline' (mainline
+ // extension). Soong creates a set of variables for Make, one or each boot image. The only
+ // reason why the ART image is exposed to Make is testing (art gtests) and benchmarking (art
+ // golem benchmarks). Install rules that use those variables are in dex_preopt_libart.mk. Here
+ // for dexpreopt purposes the infix is always 'boot' or 'mainline'.
+ dexpreoptInfix := "boot"
+ if global.PreoptWithUpdatableBcp {
+ dexpreoptInfix = "mainline"
+ }
+
+ var dexPreoptImageZipBoot android.Path
+ var dexPreoptImageZipArt android.Path
+ var dexPreoptImageZipMainline android.Path
+ for _, current := range append(d.otherImages, image) {
+ if current.name == dexpreoptInfix {
+ _, imageLocationsOnDevice := current.getAnyAndroidVariant().imageLocations()
+ for i, location := range imageLocationsOnDevice {
+ imageLocationsOnDevice[i] = strings.TrimPrefix(location, "/")
+ }
+ sb.WriteString(strings.Join(imageLocationsOnDevice, ":"))
+ }
+ switch current.name {
+ case "boot":
+ dexPreoptImageZipBoot = current.zip
+ case "art":
+ dexPreoptImageZipArt = current.zip
+ case "mainline":
+ dexPreoptImageZipMainline = current.zip
+ }
+ }
+ sb.WriteString("\nextra-args = ")
+ android.WriteFileRuleVerbatim(ctx, bootZipMetadataTmp, sb.String())
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cat,
+ Inputs: []android.Path{
+ bootZipMetadataTmp,
+ globalSoong.UffdGcFlag,
+ newlineFile,
+ },
+ Output: bootZipMetadata,
+ })
+
+ bootZipFirstPart := android.PathForModuleOut(ctx, "boot_zip", "boot_first_part.zip")
+ bootZip := android.PathForModuleOut(ctx, "boot_zip", "boot.zip")
+ builder := android.NewRuleBuilder(pctx, ctx)
+ cmd := builder.Command().BuiltTool("soong_zip").
+ FlagWithOutput("-o ", bootZipFirstPart).
+ FlagWithArg("-C ", filepath.Dir(filepath.Dir(bootclasspathDexFiles[0].String())))
+ for _, bootclasspathJar := range bootclasspathDexFiles {
+ cmd.FlagWithInput("-f ", bootclasspathJar)
+ }
+ for i := range global.SystemServerJars.Len() {
+ // Use "/system" path for JARs with "platform:" prefix. These JARs counterintuitively use
+ // "platform" prefix but they will be actually installed to /system partition.
+ // For the remaining system server JARs use the partition signified by the prefix.
+ // For example, prefix "system_ext:" will use "/system_ext" path.
+ dir := global.SystemServerJars.Apex(i)
+ if dir == "platform" {
+ dir = "system"
+ }
+ jar := global.SystemServerJars.Jar(i) + ".jar"
+ cmd.FlagWithArg("-e ", dir+"/framework/"+jar)
+ cmd.FlagWithInput("-f ", systemServerDexjarsDir.Join(ctx, jar))
+ }
+ cmd.Flag("-j")
+ cmd.FlagWithInput("-f ", bootZipMetadata)
+
+ builder.Command().BuiltTool("merge_zips").
+ Output(bootZip).
+ Input(bootZipFirstPart).
+ Input(dexPreoptImageZipBoot).
+ Input(dexPreoptImageZipArt).
+ Input(dexPreoptImageZipMainline)
+
+ builder.Build("boot_zip", "build boot.zip")
+
+ ctx.DistForGoal("droidcore", bootZipMetadata)
+ ctx.DistForGoal("droidcore", bootZip)
}
// GenerateSingletonBuildActions generates build rules for the dexpreopt config for Make.
@@ -711,7 +870,8 @@
modules := make([]apexJarModulePair, 0, imageConfig.modules.Len())
for i := 0; i < imageConfig.modules.Len(); i++ {
found := false
- for _, module := range gatherApexModulePairDepsWithTag(ctx, dexpreoptBootJarDepTag) {
+ dexpreoptBootJarModules, _ := gatherApexModulePairDepsWithTag(ctx, dexpreoptBootJar)
+ for _, module := range dexpreoptBootJarModules {
name := android.RemoveOptionalPrebuiltPrefix(module.Name())
if name == imageConfig.modules.Jar(i) {
modules = append(modules, apexJarModulePair{
@@ -794,11 +954,16 @@
"APEX '%[2]s' doesn't exist or is not added as a dependency of dex_bootjars",
pair.jarModule.Name(),
pair.apex)
+ return nil
}
bootclasspathFragmentInfo, _ := android.OtherModuleProvider(ctx, fragment, BootclasspathFragmentApexContentInfoProvider)
jar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(pair.jarModule)
if err != nil {
- ctx.ModuleErrorf("%s", err)
+ if ctx.Config().AllowMissingDependencies() {
+ ctx.AddMissingDependencies([]string{pair.jarModule.String()})
+ } else {
+ ctx.ModuleErrorf("%s", err)
+ }
}
return jar
}
@@ -957,9 +1122,16 @@
func getApexNameToApexExportsInfoMap(ctx android.ModuleContext) apexNameToApexExportsInfoMap {
apexNameToApexExportsInfoMap := apexNameToApexExportsInfoMap{}
- ctx.VisitDirectDepsWithTag(dexpreoptBootJarDepTag, func(am android.Module) {
- if info, exists := android.OtherModuleProvider(ctx, am, android.ApexExportsInfoProvider); exists {
- apexNameToApexExportsInfoMap[info.ApexName] = info
+
+ ctx.VisitDirectDeps(func(am android.Module) {
+ tag := ctx.OtherModuleDependencyTag(am)
+ if bcpTag, ok := tag.(bootclasspathDependencyTag); ok && bcpTag.typ == dexpreoptBootJar {
+ if bcpTag.moduleInApex == "" {
+ info, exists := android.OtherModuleProvider(ctx, am, android.ApexExportsInfoProvider)
+ if exists {
+ apexNameToApexExportsInfoMap[info.ApexName] = info
+ }
+ }
}
})
return apexNameToApexExportsInfoMap
@@ -1442,24 +1614,33 @@
func (dbj *artBootImages) DepsMutator(ctx android.BottomUpMutatorContext) {
// Create a dependency on `dex_bootjars` to access the intermediate locations of host art boot image.
- ctx.AddVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), dexpreoptBootJarDepTag, "dex_bootjars")
+ tag := bootclasspathDependencyTag{
+ typ: dexpreoptBootJar,
+ }
+ ctx.AddVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), tag, "dex_bootjars")
}
func (d *artBootImages) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- ctx.VisitDirectDepsWithTag(dexpreoptBootJarDepTag, func(m android.Module) {
- hostInstallsInfo, ok := android.OtherModuleProvider(ctx, m, artBootImageHostInfoProvider)
- if !ok {
- ctx.ModuleErrorf("Could not find information about the host variant of ART boot image")
- }
- installs := d.installFile(ctx, hostInstallsInfo.installs)
- if len(installs) > 0 {
- d.outputFile = android.OptionalPathForPath(installs[0])
- // Create a phony target that can ART run-tests can depend on.
- ctx.Phony(d.Name(), installs...)
- } else {
- // this might be true e.g. when building with `WITH_DEXPREOPT=false`
- // create an empty file so that the `art_boot_images` is known to the packaging system.
- d.outputFile = android.OptionalPathForPath(android.PathForModuleOut(ctx, "undefined_art_boot_images"))
+ ctx.VisitDirectDeps(func(m android.Module) {
+ tag := ctx.OtherModuleDependencyTag(m)
+ if bcpTag, ok := tag.(bootclasspathDependencyTag); ok && bcpTag.typ == dexpreoptBootJar {
+ if bcpTag.moduleInApex != "" {
+ panic("unhandled moduleInApex")
+ }
+ hostInstallsInfo, ok := android.OtherModuleProvider(ctx, m, artBootImageHostInfoProvider)
+ if !ok {
+ ctx.ModuleErrorf("Could not find information about the host variant of ART boot image")
+ }
+ installs := d.installFile(ctx, hostInstallsInfo.installs)
+ if len(installs) > 0 {
+ d.outputFile = android.OptionalPathForPath(installs[0])
+ // Create a phony target that can ART run-tests can depend on.
+ ctx.Phony(d.Name(), installs...)
+ } else {
+ // this might be true e.g. when building with `WITH_DEXPREOPT=false`
+ // create an empty file so that the `art_boot_images` is known to the packaging system.
+ d.outputFile = android.OptionalPathForPath(android.PathForModuleOut(ctx, "undefined_art_boot_images"))
+ }
}
})
}
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index dc0973c..fb5c325 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -67,15 +67,16 @@
// ART boot image for testing only. Do not rely on it to make any build-time decision.
artCfg := bootImageConfig{
- name: artBootImageName,
- enabledIfExists: "art-bootclasspath-fragment",
- stem: bootImageStem,
- installDir: "apex/art_boot_images/javalib",
- modules: global.TestOnlyArtBootImageJars,
- preloadedClassesFile: "art/build/boot/preloaded-classes",
- compilerFilter: "speed-profile",
- singleImage: false,
- profileImports: profileImports,
+ name: artBootImageName,
+ enabledIfExists: "art-bootclasspath-fragment",
+ stem: bootImageStem,
+ installDir: "apex/art_boot_images/javalib",
+ modules: global.TestOnlyArtBootImageJars,
+ preloadedClassesFile: "art/build/boot/preloaded-classes",
+ compilerFilter: "speed-profile",
+ singleImage: false,
+ profileImports: profileImports,
+ profileProviderModule: "art-bootclasspath-fragment",
}
// Framework config for the boot image extension.
diff --git a/java/dexpreopt_config_test.go b/java/dexpreopt_config_test.go
index 44d2127..99b1f23 100644
--- a/java/dexpreopt_config_test.go
+++ b/java/dexpreopt_config_test.go
@@ -23,6 +23,7 @@
)
func TestBootImageConfig(t *testing.T) {
+ t.Parallel()
if runtime.GOOS != "linux" {
t.Skipf("Skipping as boot image config test is only supported on linux not %s", runtime.GOOS)
}
diff --git a/java/dexpreopt_config_testing.go b/java/dexpreopt_config_testing.go
index 33c682b..241941e 100644
--- a/java/dexpreopt_config_testing.go
+++ b/java/dexpreopt_config_testing.go
@@ -1217,6 +1217,7 @@
}
t.Run(imageConfig.name, func(t *testing.T) {
+ t.Parallel()
nestedCheckBootImageConfig(t, result, imageConfig, mutated, expected)
})
}
@@ -1236,7 +1237,7 @@
android.AssertPathRelativeToTopEquals(t, "zip", expected.zip, imageConfig.zip)
if !mutated {
- dexBootJarModule := result.ModuleForTests("dex_bootjars", "android_common")
+ dexBootJarModule := result.ModuleForTests(t, "dex_bootjars", "android_common")
profileInstallInfo, _ := android.OtherModuleProvider(result, dexBootJarModule.Module(), profileInstallInfoProvider)
assertInstallsEqual(t, "profileInstalls", expected.profileInstalls, profileInstallInfo.profileInstalls)
android.AssertStringEquals(t, "profileLicenseMetadataFile", expected.profileLicenseMetadataFile, profileInstallInfo.profileLicenseMetadataFile.RelativeToTop().String())
@@ -1246,6 +1247,7 @@
for i, variant := range imageConfig.variants {
expectedVariant := expected.variants[i]
t.Run(variant.target.Arch.ArchType.String(), func(t *testing.T) {
+ t.Parallel()
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)
@@ -1279,7 +1281,7 @@
// 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 {
+ vars := result.MakeVarsForTesting(t, func(variable android.MakeVarVariable) bool {
return strings.HasPrefix(variable.Name(), "DEXPREOPT_")
})
diff --git a/java/dexpreopt_test.go b/java/dexpreopt_test.go
index 07d0595..f437da0 100644
--- a/java/dexpreopt_test.go
+++ b/java/dexpreopt_test.go
@@ -17,7 +17,6 @@
import (
"fmt"
"runtime"
- "strings"
"testing"
"android/soong/android"
@@ -30,6 +29,7 @@
}
func TestDexpreoptEnabled(t *testing.T) {
+ t.Parallel()
tests := []struct {
name string
bp string
@@ -219,6 +219,7 @@
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
+ t.Parallel()
preparers := android.GroupFixturePreparers(
PrepareForTestWithDexpreopt,
PrepareForTestWithFakeApexMutator,
@@ -238,7 +239,7 @@
variant += "_apex1000"
}
- dexpreopt := ctx.ModuleForTests(moduleName, variant).MaybeRule("dexpreopt")
+ dexpreopt := ctx.ModuleForTests(t, moduleName, variant).MaybeRule("dexpreopt")
enabled := dexpreopt.Rule != nil
if enabled != test.enabled {
@@ -258,6 +259,7 @@
}
func TestDex2oatToolDeps(t *testing.T) {
+ t.Parallel()
if runtime.GOOS != "linux" {
// The host binary paths checked below are build OS dependent.
t.Skipf("Unsupported build OS %s", runtime.GOOS)
@@ -273,6 +275,7 @@
name := fmt.Sprintf("sourceEnabled:%t,prebuiltEnabled:%t,prebuiltPreferred:%t",
sourceEnabled, prebuiltEnabled, prebuiltPreferred)
t.Run(name, func(t *testing.T) {
+ t.Parallel()
result := preparers.RunTestWithBp(t, fmt.Sprintf(`
cc_binary {
name: "dex2oatd",
@@ -296,7 +299,7 @@
})
}
- sourceDex2oatPath := "host/linux-x86/bin/dex2oatd"
+ sourceDex2oatPath := "../host/linux-x86/bin/dex2oatd"
prebuiltDex2oatPath := ".intermediates/prebuilt_dex2oatd/linux_glibc_x86_64/dex2oatd"
testDex2oatToolDep(true, false, false, sourceDex2oatPath)
@@ -305,7 +308,7 @@
testDex2oatToolDep(false, true, false, prebuiltDex2oatPath)
}
-func TestDexpreoptBuiltInstalledForApex(t *testing.T) {
+func TestApexSystemServerDexpreoptInstalls(t *testing.T) {
preparers := android.GroupFixturePreparers(
PrepareForTestWithDexpreopt,
PrepareForTestWithFakeApexMutator,
@@ -322,28 +325,38 @@
sdk_version: "current",
}`)
ctx := result.TestContext
- module := ctx.ModuleForTests("service-foo", "android_common_apex1000")
+ module := ctx.ModuleForTests(t, "service-foo", "android_common_apex1000")
library := module.Module().(*Library)
- installs := library.dexpreopter.DexpreoptBuiltInstalledForApex()
+ installs := library.dexpreopter.ApexSystemServerDexpreoptInstalls()
+ dexJars := library.dexpreopter.ApexSystemServerDexJars()
android.AssertIntEquals(t, "install count", 2, len(installs))
+ android.AssertIntEquals(t, "dexjar count", 1, len(dexJars))
- android.AssertStringEquals(t, "installs[0] FullModuleName",
- "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
- installs[0].FullModuleName())
+ android.AssertPathRelativeToTopEquals(t, "installs[0] OutputPathOnHost",
+ "out/soong/.intermediates/service-foo/android_common_apex1000/dexpreopt/service-foo/oat/arm64/javalib.odex",
+ installs[0].OutputPathOnHost)
- android.AssertStringEquals(t, "installs[0] SubModuleName",
- "-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
- installs[0].SubModuleName())
+ android.AssertPathRelativeToTopEquals(t, "installs[0] InstallDirOnDevice",
+ "out/target/product/test_device/system/framework/oat/arm64",
+ installs[0].InstallDirOnDevice)
- android.AssertStringEquals(t, "installs[1] FullModuleName",
- "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
- installs[1].FullModuleName())
+ android.AssertStringEquals(t, "installs[0] InstallFileOnDevice",
+ "apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
+ installs[0].InstallFileOnDevice)
- android.AssertStringEquals(t, "installs[1] SubModuleName",
- "-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
- installs[1].SubModuleName())
+ android.AssertPathRelativeToTopEquals(t, "installs[1] OutputPathOnHost",
+ "out/soong/.intermediates/service-foo/android_common_apex1000/dexpreopt/service-foo/oat/arm64/javalib.vdex",
+ installs[1].OutputPathOnHost)
+
+ android.AssertPathRelativeToTopEquals(t, "installs[1] InstallDirOnDevice",
+ "out/target/product/test_device/system/framework/oat/arm64",
+ installs[1].InstallDirOnDevice)
+
+ android.AssertStringEquals(t, "installs[1] InstallFileOnDevice",
+ "apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
+ installs[1].InstallFileOnDevice)
// Not an APEX system server jar.
result = preparers.RunTestWithBp(t, `
@@ -354,101 +367,14 @@
sdk_version: "current",
}`)
ctx = result.TestContext
- module = ctx.ModuleForTests("foo", "android_common")
+ module = ctx.ModuleForTests(t, "foo", "android_common")
library = module.Module().(*Library)
- installs = library.dexpreopter.DexpreoptBuiltInstalledForApex()
+ installs = library.dexpreopter.ApexSystemServerDexpreoptInstalls()
+ dexJars = library.dexpreopter.ApexSystemServerDexJars()
android.AssertIntEquals(t, "install count", 0, len(installs))
-}
-
-func filterDexpreoptEntriesList(entriesList []android.AndroidMkEntries) []android.AndroidMkEntries {
- var results []android.AndroidMkEntries
- for _, entries := range entriesList {
- if strings.Contains(entries.EntryMap["LOCAL_MODULE"][0], "-dexpreopt-") {
- results = append(results, entries)
- }
- }
- return results
-}
-
-func verifyEntries(t *testing.T, message string, expectedModule string,
- expectedPrebuiltModuleFile string, expectedModulePath string, expectedInstalledModuleStem string,
- entries android.AndroidMkEntries) {
- android.AssertStringEquals(t, message+" LOCAL_MODULE", expectedModule,
- entries.EntryMap["LOCAL_MODULE"][0])
-
- android.AssertStringEquals(t, message+" LOCAL_MODULE_CLASS", "ETC",
- entries.EntryMap["LOCAL_MODULE_CLASS"][0])
-
- android.AssertStringDoesContain(t, message+" LOCAL_PREBUILT_MODULE_FILE",
- entries.EntryMap["LOCAL_PREBUILT_MODULE_FILE"][0], expectedPrebuiltModuleFile)
-
- android.AssertStringDoesContain(t, message+" LOCAL_MODULE_PATH",
- entries.EntryMap["LOCAL_MODULE_PATH"][0], expectedModulePath)
-
- android.AssertStringEquals(t, message+" LOCAL_INSTALLED_MODULE_STEM",
- expectedInstalledModuleStem, entries.EntryMap["LOCAL_INSTALLED_MODULE_STEM"][0])
-
- android.AssertStringEquals(t, message+" LOCAL_NOT_AVAILABLE_FOR_PLATFORM",
- "false", entries.EntryMap["LOCAL_NOT_AVAILABLE_FOR_PLATFORM"][0])
-}
-
-func TestAndroidMkEntriesForApex(t *testing.T) {
- preparers := android.GroupFixturePreparers(
- PrepareForTestWithDexpreopt,
- PrepareForTestWithFakeApexMutator,
- dexpreopt.FixtureSetApexSystemServerJars("com.android.apex1:service-foo"),
- )
-
- // An APEX system server jar.
- result := preparers.RunTestWithBp(t, `
- java_library {
- name: "service-foo",
- installable: true,
- srcs: ["a.java"],
- apex_available: ["com.android.apex1"],
- sdk_version: "current",
- }`)
- ctx := result.TestContext
- module := ctx.ModuleForTests("service-foo", "android_common_apex1000")
-
- entriesList := android.AndroidMkEntriesForTest(t, ctx, module.Module())
- entriesList = filterDexpreoptEntriesList(entriesList)
-
- android.AssertIntEquals(t, "entries count", 2, len(entriesList))
-
- verifyEntries(t,
- "entriesList[0]",
- "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
- "/dexpreopt/service-foo/oat/arm64/javalib.odex",
- "/system/framework/oat/arm64",
- "apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
- entriesList[0])
-
- verifyEntries(t,
- "entriesList[1]",
- "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
- "/dexpreopt/service-foo/oat/arm64/javalib.vdex",
- "/system/framework/oat/arm64",
- "apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
- entriesList[1])
-
- // Not an APEX system server jar.
- result = preparers.RunTestWithBp(t, `
- java_library {
- name: "foo",
- installable: true,
- srcs: ["a.java"],
- sdk_version: "current",
- }`)
- ctx = result.TestContext
- module = ctx.ModuleForTests("foo", "android_common")
-
- entriesList = android.AndroidMkEntriesForTest(t, ctx, module.Module())
- entriesList = filterDexpreoptEntriesList(entriesList)
-
- android.AssertIntEquals(t, "entries count", 0, len(entriesList))
+ android.AssertIntEquals(t, "dexjar count", 0, len(dexJars))
}
func TestGenerateProfileEvenIfDexpreoptIsDisabled(t *testing.T) {
@@ -470,7 +396,7 @@
}`)
ctx := result.TestContext
- dexpreopt := ctx.ModuleForTests("foo", "android_common").MaybeRule("dexpreopt")
+ dexpreopt := ctx.ModuleForTests(t, "foo", "android_common").MaybeRule("dexpreopt")
expected := []string{"out/soong/.intermediates/foo/android_common/dexpreopt/foo/profile.prof"}
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 2dda72b..3faf294 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -19,6 +19,7 @@
"path/filepath"
"strings"
+ "github.com/google/blueprint"
"github.com/google/blueprint/proptools"
"android/soong/android"
@@ -194,6 +195,9 @@
"them instead.")
}
return false
+ } else if ctx.Config().PartialCompileFlags().Disable_stub_validation &&
+ !ctx.Config().BuildFromTextStub() {
+ return false
} else if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
return true
} else if String(apiToCheck.Api_file) != "" {
@@ -357,7 +361,7 @@
deps.aidlPreprocess = sdkDep.aidl
}
- ctx.VisitDirectDeps(func(module android.Module) {
+ ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
otherName := ctx.OtherModuleName(module)
tag := ctx.OtherModuleDependencyTag(module)
@@ -381,9 +385,9 @@
deps.classpath = append(deps.classpath, dep.HeaderJars...)
deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.AconfigIntermediateCacheOutputPaths...)
- } else if dep, ok := module.(android.SourceFileProducer); ok {
- checkProducesJars(ctx, dep)
- deps.classpath = append(deps.classpath, dep.Srcs()...)
+ } else if dep, ok := android.OtherModuleProvider(ctx, module, android.SourceFilesInfoProvider); ok {
+ checkProducesJars(ctx, dep, module)
+ deps.classpath = append(deps.classpath, dep.Srcs...)
} else {
ctx.ModuleErrorf("depends on non-java module %q", otherName)
}
@@ -874,6 +878,13 @@
Path *string
}
+type ExportedDroiddocDirInfo struct {
+ Deps android.Paths
+ Dir android.Path
+}
+
+var ExportedDroiddocDirInfoProvider = blueprint.NewProvider[ExportedDroiddocDirInfo]()
+
type ExportedDroiddocDir struct {
android.ModuleBase
@@ -897,6 +908,11 @@
path := String(d.properties.Path)
d.dir = android.PathForModuleSrc(ctx, path)
d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
+
+ android.SetProvider(ctx, ExportedDroiddocDirInfoProvider, ExportedDroiddocDirInfo{
+ Dir: d.dir,
+ Deps: d.deps,
+ })
}
// Defaults
diff --git a/java/droiddoc_test.go b/java/droiddoc_test.go
index 9e1ebbe..0c977bc 100644
--- a/java/droiddoc_test.go
+++ b/java/droiddoc_test.go
@@ -23,6 +23,7 @@
)
func TestDroiddoc(t *testing.T) {
+ t.Parallel()
ctx, _ := testJavaWithFS(t, `
droiddoc_exported_dir {
name: "droiddoc-templates-sdk",
@@ -69,13 +70,13 @@
"bar-doc/a.java": nil,
"bar-doc/b.java": nil,
})
- barStubsOutputs := ctx.ModuleForTests("bar-stubs", "android_common").OutputFiles(ctx, t, "")
+ barStubsOutputs := ctx.ModuleForTests(t, "bar-stubs", "android_common").OutputFiles(ctx, t, "")
if len(barStubsOutputs) != 1 {
t.Errorf("Expected one output from \"bar-stubs\" got %s", barStubsOutputs)
}
barStubsOutput := barStubsOutputs[0]
- barDoc := ctx.ModuleForTests("bar-doc", "android_common")
+ barDoc := ctx.ModuleForTests(t, "bar-doc", "android_common")
javaDoc := barDoc.Rule("javadoc")
if g, w := android.PathsRelativeToTop(javaDoc.Implicits), android.PathRelativeToTop(barStubsOutput); !inList(w, g) {
t.Errorf("implicits of bar-doc must contain %q, but was %q.", w, g)
@@ -97,6 +98,7 @@
}
func TestDroiddocArgsAndFlagsCausesError(t *testing.T) {
+ t.Parallel()
testJavaError(t, "flags is set. Cannot set args", `
droiddoc_exported_dir {
name: "droiddoc-templates-sdk",
diff --git a/java/droidstubs.go b/java/droidstubs.go
index e955949..b30c844 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -20,6 +20,7 @@
"regexp"
"strings"
+ "github.com/google/blueprint"
"github.com/google/blueprint/proptools"
"android/soong/android"
@@ -27,6 +28,28 @@
"android/soong/remoteexec"
)
+type StubsInfo struct {
+ ApiVersionsXml android.Path
+ AnnotationsZip android.Path
+ ApiFile android.Path
+ RemovedApiFile android.Path
+}
+
+type DroidStubsInfo struct {
+ CurrentApiTimestamp android.Path
+ EverythingStubsInfo StubsInfo
+ ExportableStubsInfo StubsInfo
+}
+
+var DroidStubsInfoProvider = blueprint.NewProvider[DroidStubsInfo]()
+
+type StubsSrcInfo struct {
+ EverythingStubsSrcJar android.Path
+ ExportableStubsSrcJar android.Path
+}
+
+var StubsSrcInfoProvider = blueprint.NewProvider[StubsSrcInfo]()
+
// The values allowed for Droidstubs' Api_levels_sdk_type
var allowedApiLevelSdkTypes = []string{"public", "system", "module-lib", "system-server"}
@@ -498,9 +521,9 @@
}
func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
- ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
- if t, ok := m.(*ExportedDroiddocDir); ok {
- cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
+ ctx.VisitDirectDepsProxyWithTag(metalavaMergeAnnotationsDirTag, func(m android.ModuleProxy) {
+ if t, ok := android.OtherModuleProvider(ctx, m, ExportedDroiddocDirInfoProvider); ok {
+ cmd.FlagWithArg("--merge-qualifier-annotations ", t.Dir.String()).Implicits(t.Deps)
} else {
ctx.PropertyErrorf("merge_annotations_dirs",
"module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
@@ -509,9 +532,9 @@
}
func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
- ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
- if t, ok := m.(*ExportedDroiddocDir); ok {
- cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
+ ctx.VisitDirectDepsProxyWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.ModuleProxy) {
+ if t, ok := android.OtherModuleProvider(ctx, m, ExportedDroiddocDirInfoProvider); ok {
+ cmd.FlagWithArg("--merge-inclusion-annotations ", t.Dir.String()).Implicits(t.Deps)
} else {
ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
"module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
@@ -525,12 +548,12 @@
d.apiLevelsGenerationFlags(ctx, cmd, stubsType, apiVersionsXml)
apiVersions = apiVersionsXml
} else {
- ctx.VisitDirectDepsWithTag(metalavaAPILevelsModuleTag, func(m android.Module) {
- if s, ok := m.(*Droidstubs); ok {
+ ctx.VisitDirectDepsProxyWithTag(metalavaAPILevelsModuleTag, func(m android.ModuleProxy) {
+ if s, ok := android.OtherModuleProvider(ctx, m, DroidStubsInfoProvider); ok {
if stubsType == Everything {
- apiVersions = s.everythingArtifacts.apiVersionsXml
+ apiVersions = s.EverythingStubsInfo.ApiVersionsXml
} else if stubsType == Exportable {
- apiVersions = s.exportableArtifacts.apiVersionsXml
+ apiVersions = s.ExportableStubsInfo.ApiVersionsXml
} else {
ctx.ModuleErrorf("%s stubs type does not generate api-versions.xml file", stubsType.String())
}
@@ -541,7 +564,15 @@
})
}
if apiVersions != nil {
- cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion().String())
+ // We are migrating from a single API level to major.minor
+ // versions and PlatformSdkVersionFull is not yet set in all
+ // release configs. If it is not set, fall back on the single
+ // API level.
+ if fullSdkVersion := ctx.Config().PlatformSdkVersionFull(); len(fullSdkVersion) > 0 {
+ cmd.FlagWithArg("--current-version ", fullSdkVersion)
+ } else {
+ cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion().String())
+ }
cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
cmd.FlagWithInput("--apply-api-levels ", apiVersions)
}
@@ -603,18 +634,18 @@
var dirs []string
var extensions_dir string
- ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
- if t, ok := m.(*ExportedDroiddocDir); ok {
- extRegex := regexp.MustCompile(t.dir.String() + extensionsPattern)
+ ctx.VisitDirectDepsProxyWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.ModuleProxy) {
+ if t, ok := android.OtherModuleProvider(ctx, m, ExportedDroiddocDirInfoProvider); ok {
+ extRegex := regexp.MustCompile(t.Dir.String() + extensionsPattern)
// Grab the first extensions_dir and we find while scanning ExportedDroiddocDir.deps;
// ideally this should be read from prebuiltApis.properties.Extensions_*
- for _, dep := range t.deps {
+ for _, dep := range t.Deps {
// Check to see if it matches an extension first.
depBase := dep.Base()
if extRegex.MatchString(dep.String()) && d.properties.Extensions_info_file != nil {
if extensions_dir == "" {
- extensions_dir = t.dir.String() + "/extensions"
+ extensions_dir = t.Dir.String() + "/extensions"
}
cmd.Implicit(dep)
} else if depBase == filename {
@@ -622,23 +653,17 @@
cmd.Implicit(dep)
} else if depBase == AndroidPlusUpdatableJar && d.properties.Extensions_info_file != nil {
// The output api-versions.xml has been requested to include information on SDK
- // extensions. That means it also needs to include
- // so
- // The module-lib and system-server directories should use `android-plus-updatable.jar`
- // instead of `android.jar`. See AndroidPlusUpdatableJar for more information.
- cmd.Implicit(dep)
- } else if filename != "android.jar" && depBase == "android.jar" {
- // Metalava implicitly searches these patterns:
- // prebuilts/tools/common/api-versions/android-%/android.jar
- // prebuilts/sdk/%/public/android.jar
- // Add android.jar files from the api_levels_annotations_dirs directories to try
- // to satisfy these patterns. If Metalava can't find a match for an API level
- // between 1 and 28 in at least one pattern it will fail.
+ // extensions, i.e. updatable Apis. That means it also needs to include the history of
+ // those updatable APIs. Usually, they would be included in the `android.jar` file but
+ // unfortunately, the `module-lib` and `system-server` cannot as it would lead to build
+ // cycles. So, the module-lib and system-server directories contain an
+ // `android-plus-updatable.jar` that should be used instead of `android.jar`. See
+ // AndroidPlusUpdatableJar for more information.
cmd.Implicit(dep)
}
}
- dirs = append(dirs, t.dir.String())
+ dirs = append(dirs, t.Dir.String())
} else {
ctx.PropertyErrorf("api_levels_annotations_dirs",
"module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
@@ -646,11 +671,11 @@
})
// Generate the list of --android-jar-pattern options. The order matters so the first one which
- // matches will be the one that is used for a specific api level..
+ // matches will be the one that is used for a specific api level.
for _, sdkDir := range sdkDirs {
for _, dir := range dirs {
addPattern := func(jarFilename string) {
- cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/%%/%s/%s", dir, sdkDir, jarFilename))
+ cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/{version:major.minor?}/%s/%s", dir, sdkDir, jarFilename))
}
if sdkDir == "module-lib" || sdkDir == "system-server" {
@@ -665,6 +690,10 @@
addPattern(filename)
}
+
+ if extensions_dir != "" {
+ cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/{version:extension}/%s/{module}.jar", extensions_dir, sdkDir))
+ }
}
if d.properties.Extensions_info_file != nil {
@@ -673,7 +702,6 @@
}
info_file := android.PathForModuleSrc(ctx, *d.properties.Extensions_info_file)
cmd.Implicit(info_file)
- cmd.FlagWithArg("--sdk-extensions-root ", extensions_dir)
cmd.FlagWithArg("--sdk-extensions-info ", info_file.String())
}
}
@@ -700,7 +728,8 @@
}
func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
- srcJarList android.Path, homeDir android.WritablePath, params stubsCommandConfigParams, configFiles android.Paths) *android.RuleBuilderCommand {
+ srcJarList android.Path, homeDir android.WritablePath, params stubsCommandConfigParams,
+ configFiles android.Paths, apiSurface *string) *android.RuleBuilderCommand {
rule.Command().Text("rm -rf").Flag(homeDir.String())
rule.Command().Text("mkdir -p").Flag(homeDir.String())
@@ -746,6 +775,8 @@
addMetalavaConfigFilesToCmd(cmd, configFiles)
+ addOptionalApiSurfaceToCmd(cmd, apiSurface)
+
return cmd
}
@@ -764,6 +795,14 @@
cmd.FlagForEachInput("--config-file ", configFiles)
}
+// addOptionalApiSurfaceToCmd adds --api-surface option is apiSurface is not `nil`.
+func addOptionalApiSurfaceToCmd(cmd *android.RuleBuilderCommand, apiSurface *string) {
+ if apiSurface != nil {
+ cmd.Flag("--api-surface")
+ cmd.Flag(*apiSurface)
+ }
+}
+
// Pass flagged apis related flags to metalava. When aconfig_declarations property is not
// defined for a module, simply revert all flagged apis annotations. If aconfig_declarations
// property is defined, apply transformations and only revert the flagged apis that are not
@@ -790,19 +829,17 @@
}
}
- if len(aconfigFlagsPaths) == 0 {
- // This argument should not be added for "everything" stubs
- cmd.Flag("--revert-annotation android.annotation.FlaggedApi")
- return
- }
+ // If aconfigFlagsPaths is empty then it is still important to generate the
+ // Metalava flags config file, albeit with an empty set of flags, so that all
+ // flagged APIs will be reverted.
- releasedFlaggedApisFile := android.PathForModuleOut(ctx, fmt.Sprintf("released-flagged-apis-%s.txt", stubsType.String()))
- revertAnnotationsFile := android.PathForModuleOut(ctx, fmt.Sprintf("revert-annotations-%s.txt", stubsType.String()))
+ releasedFlagsFile := android.PathForModuleOut(ctx, fmt.Sprintf("released-flags-%s.pb", stubsType.String()))
+ metalavaFlagsConfigFile := android.PathForModuleOut(ctx, fmt.Sprintf("flags-config-%s.xml", stubsType.String()))
ctx.Build(pctx, android.BuildParams{
Rule: gatherReleasedFlaggedApisRule,
Inputs: aconfigFlagsPaths,
- Output: releasedFlaggedApisFile,
+ Output: releasedFlagsFile,
Description: fmt.Sprintf("%s gather aconfig flags", stubsType),
Args: map[string]string{
"flags_path": android.JoinPathsWithPrefix(aconfigFlagsPaths, "--cache "),
@@ -812,12 +849,12 @@
ctx.Build(pctx, android.BuildParams{
Rule: generateMetalavaRevertAnnotationsRule,
- Input: releasedFlaggedApisFile,
- Output: revertAnnotationsFile,
- Description: fmt.Sprintf("%s revert annotations", stubsType),
+ Input: releasedFlagsFile,
+ Output: metalavaFlagsConfigFile,
+ Description: fmt.Sprintf("%s metalava flags config", stubsType),
})
- cmd.FlagWithInput("@", revertAnnotationsFile)
+ cmd.FlagWithInput("--config-file ", metalavaFlagsConfigFile)
}
func (d *Droidstubs) commonMetalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
@@ -838,7 +875,8 @@
configFiles := android.PathsForModuleSrc(ctx, d.properties.ConfigFiles)
- cmd := metalavaCmd(ctx, rule, d.Javadoc.srcFiles, srcJarList, homeDir, params.stubConfig, configFiles)
+ cmd := metalavaCmd(ctx, rule, d.Javadoc.srcFiles, srcJarList, homeDir, params.stubConfig,
+ configFiles, d.properties.Api_surface)
cmd.Implicits(d.Javadoc.implicits)
d.stubsFlags(ctx, cmd, params.stubsDir, params.stubConfig.stubsType, params.stubConfig.checkApi)
@@ -1177,6 +1215,34 @@
rule.Build(fmt.Sprintf("metalava_%s", params.stubConfig.stubsType.String()), "metalava merged")
}
+func (d *Droidstubs) setPhonyRules(ctx android.ModuleContext) {
+ if d.apiFile != nil {
+ ctx.Phony(d.Name(), d.apiFile)
+ ctx.Phony(fmt.Sprintf("%s.txt", d.Name()), d.apiFile)
+ }
+ if d.removedApiFile != nil {
+ ctx.Phony(d.Name(), d.removedApiFile)
+ ctx.Phony(fmt.Sprintf("%s.txt", d.Name()), d.removedApiFile)
+ }
+ if d.checkCurrentApiTimestamp != nil {
+ ctx.Phony(fmt.Sprintf("%s-check-current-api", d.Name()), d.checkCurrentApiTimestamp)
+ ctx.Phony("checkapi", d.checkCurrentApiTimestamp)
+ }
+ if d.updateCurrentApiTimestamp != nil {
+ ctx.Phony(fmt.Sprintf("%s-update-current-api", d.Name()), d.updateCurrentApiTimestamp)
+ ctx.Phony("update-api", d.updateCurrentApiTimestamp)
+ }
+ if d.checkLastReleasedApiTimestamp != nil {
+ ctx.Phony(fmt.Sprintf("%s-check-last-released-api", d.Name()), d.checkLastReleasedApiTimestamp)
+ }
+ if d.apiLintTimestamp != nil {
+ ctx.Phony(fmt.Sprintf("%s-api-lint", d.Name()), d.apiLintTimestamp)
+ }
+ if d.checkNullabilityWarningsTimestamp != nil {
+ ctx.Phony(fmt.Sprintf("%s-check-nullability-warnings", d.Name()), d.checkNullabilityWarningsTimestamp)
+ }
+}
+
func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
deps := d.Javadoc.collectDeps(ctx)
@@ -1185,7 +1251,7 @@
// Add options for the other optional tasks: API-lint and check-released.
// We generate separate timestamp files for them.
- doApiLint := BoolDefault(d.properties.Check_api.Api_lint.Enabled, false)
+ doApiLint := BoolDefault(d.properties.Check_api.Api_lint.Enabled, false) && !ctx.Config().PartialCompileFlags().Disable_api_lint
doCheckReleased := apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released")
writeSdkValues := Bool(d.properties.Write_sdk_values)
@@ -1220,6 +1286,41 @@
stubCmdParams.stubsType = Exportable
d.exportableStubCmd(ctx, stubCmdParams)
+ if String(d.properties.Check_nullability_warnings) != "" {
+ if d.everythingArtifacts.nullabilityWarningsFile == nil {
+ ctx.PropertyErrorf("check_nullability_warnings",
+ "Cannot specify check_nullability_warnings unless validating nullability")
+ }
+
+ checkNullabilityWarningsPath := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
+
+ d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_nullability_warnings.timestamp")
+
+ msg := fmt.Sprintf(`\n******************************\n`+
+ `The warnings encountered during nullability annotation validation did\n`+
+ `not match the checked in file of expected warnings. The diffs are shown\n`+
+ `above. You have two options:\n`+
+ ` 1. Resolve the differences by editing the nullability annotations.\n`+
+ ` 2. Update the file of expected warnings by running:\n`+
+ ` cp %s %s\n`+
+ ` and submitting the updated file as part of your change.`,
+ d.everythingArtifacts.nullabilityWarningsFile, checkNullabilityWarningsPath)
+
+ rule := android.NewRuleBuilder(pctx, ctx)
+
+ rule.Command().
+ Text("(").
+ Text("diff").Input(checkNullabilityWarningsPath).Input(d.everythingArtifacts.nullabilityWarningsFile).
+ Text("&&").
+ Text("touch").Output(d.checkNullabilityWarningsTimestamp).
+ Text(") || (").
+ Text("echo").Flag("-e").Flag(`"` + msg + `"`).
+ Text("; exit 38").
+ Text(")")
+
+ rule.Build("nullabilityWarningsCheck", "nullability warnings check")
+ }
+
if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
if len(d.Javadoc.properties.Out) > 0 {
@@ -1269,13 +1370,25 @@
`Note that DISABLE_STUB_VALIDATION=true does not bypass checkapi.\n`+
`******************************\n`, ctx.ModuleName())
- rule.Command().
+ cmd := rule.Command().
Text("touch").Output(d.checkCurrentApiTimestamp).
Text(") || (").
Text("echo").Flag("-e").Flag(`"` + msg + `"`).
Text("; exit 38").
Text(")")
+ if d.apiLintTimestamp != nil {
+ cmd.Validation(d.apiLintTimestamp)
+ }
+
+ if d.checkLastReleasedApiTimestamp != nil {
+ cmd.Validation(d.checkLastReleasedApiTimestamp)
+ }
+
+ if d.checkNullabilityWarningsTimestamp != nil {
+ cmd.Validation(d.checkNullabilityWarningsTimestamp)
+ }
+
rule.Build("metalavaCurrentApiCheck", "check current API")
d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "update_current_api.timestamp")
@@ -1305,42 +1418,49 @@
rule.Build("metalavaCurrentApiUpdate", "update current API")
}
- if String(d.properties.Check_nullability_warnings) != "" {
- if d.everythingArtifacts.nullabilityWarningsFile == nil {
- ctx.PropertyErrorf("check_nullability_warnings",
- "Cannot specify check_nullability_warnings unless validating nullability")
- }
-
- checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
-
- d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_nullability_warnings.timestamp")
-
- msg := fmt.Sprintf(`\n******************************\n`+
- `The warnings encountered during nullability annotation validation did\n`+
- `not match the checked in file of expected warnings. The diffs are shown\n`+
- `above. You have two options:\n`+
- ` 1. Resolve the differences by editing the nullability annotations.\n`+
- ` 2. Update the file of expected warnings by running:\n`+
- ` cp %s %s\n`+
- ` and submitting the updated file as part of your change.`,
- d.everythingArtifacts.nullabilityWarningsFile, checkNullabilityWarnings)
-
- rule := android.NewRuleBuilder(pctx, ctx)
-
- rule.Command().
- Text("(").
- Text("diff").Input(checkNullabilityWarnings).Input(d.everythingArtifacts.nullabilityWarningsFile).
- Text("&&").
- Text("touch").Output(d.checkNullabilityWarningsTimestamp).
- Text(") || (").
- Text("echo").Flag("-e").Flag(`"` + msg + `"`).
- Text("; exit 38").
- Text(")")
-
- rule.Build("nullabilityWarningsCheck", "nullability warnings check")
+ droidInfo := DroidStubsInfo{
+ CurrentApiTimestamp: d.CurrentApiTimestamp(),
+ EverythingStubsInfo: StubsInfo{},
+ ExportableStubsInfo: StubsInfo{},
}
+ setDroidInfo(ctx, d, &droidInfo.EverythingStubsInfo, Everything)
+ setDroidInfo(ctx, d, &droidInfo.ExportableStubsInfo, Exportable)
+ android.SetProvider(ctx, DroidStubsInfoProvider, droidInfo)
+
+ android.SetProvider(ctx, StubsSrcInfoProvider, StubsSrcInfo{
+ EverythingStubsSrcJar: d.stubsSrcJar,
+ ExportableStubsSrcJar: d.exportableStubsSrcJar,
+ })
d.setOutputFiles(ctx)
+
+ d.setPhonyRules(ctx)
+
+ if d.apiLintTimestamp != nil {
+ if d.apiLintReport != nil {
+ ctx.DistForGoalsWithFilename(
+ []string{fmt.Sprintf("%s-api-lint", d.Name()), "droidcore"},
+ d.apiLintReport,
+ fmt.Sprintf("apilint/%s-lint-report.txt", d.Name()),
+ )
+ }
+ }
+}
+
+func setDroidInfo(ctx android.ModuleContext, d *Droidstubs, info *StubsInfo, typ StubsType) {
+ if typ == Everything {
+ info.ApiFile = d.apiFile
+ info.RemovedApiFile = d.removedApiFile
+ info.AnnotationsZip = d.everythingArtifacts.annotationsZip
+ info.ApiVersionsXml = d.everythingArtifacts.apiVersionsXml
+ } else if typ == Exportable {
+ info.ApiFile = d.exportableApiFile
+ info.RemovedApiFile = d.exportableRemovedApiFile
+ info.AnnotationsZip = d.exportableArtifacts.annotationsZip
+ info.ApiVersionsXml = d.exportableArtifacts.apiVersionsXml
+ } else {
+ ctx.ModuleErrorf("failed to set ApiVersionsXml, stubs type not supported: %d", typ)
+ }
}
// This method sets the outputFiles property, which is used to set the
@@ -1508,6 +1628,11 @@
p.stubsSrcJar = outPath
}
+ android.SetProvider(ctx, StubsSrcInfoProvider, StubsSrcInfo{
+ EverythingStubsSrcJar: p.stubsSrcJar,
+ ExportableStubsSrcJar: p.stubsSrcJar,
+ })
+
ctx.SetOutputFiles(android.Paths{p.stubsSrcJar}, "")
// prebuilt droidstubs does not output "exportable" stubs.
// Output the "everything" stubs srcjar file if the tag is ".exportable".
diff --git a/java/droidstubs_test.go b/java/droidstubs_test.go
index 1e8362c..1f9d223 100644
--- a/java/droidstubs_test.go
+++ b/java/droidstubs_test.go
@@ -27,6 +27,7 @@
)
func TestDroidstubs(t *testing.T) {
+ t.Parallel()
ctx, _ := testJavaWithFS(t, `
droiddoc_exported_dir {
name: "droiddoc-templates-sdk",
@@ -82,13 +83,13 @@
},
}
for _, c := range testcases {
- m := ctx.ModuleForTests(c.moduleName, "android_common")
+ m := ctx.ModuleForTests(t, c.moduleName, "android_common")
manifest := m.Output("metalava.sbox.textproto")
sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx, manifest)
cmdline := String(sboxProto.Commands[0].Command)
android.AssertStringContainsEquals(t, "api-versions generation flag", cmdline, "--generate-api-levels", c.generate_xml)
if c.expectedJarFilename != "" {
- expected := "--android-jar-pattern ./%/public/" + c.expectedJarFilename
+ expected := "--android-jar-pattern ./{version:major.minor?}/public/" + c.expectedJarFilename
if !strings.Contains(cmdline, expected) {
t.Errorf("For %q, expected metalava argument %q, but was not found %q", c.moduleName, expected, cmdline)
}
@@ -131,7 +132,7 @@
"foo-doc/a.java": nil,
})
- m := ctx.ModuleForTests("foo-stubs", "android_common")
+ m := ctx.ModuleForTests(t, "foo-stubs", "android_common")
manifest := m.Output("metalava.sbox.textproto")
cmd := String(android.RuleBuilderSboxProtoForTests(t, ctx, manifest).Commands[0].Command)
r := regexp.MustCompile(`--android-jar-pattern [^ ]+/android.jar`)
@@ -139,35 +140,38 @@
}
func TestPublicDroidstubs(t *testing.T) {
+ t.Parallel()
patterns := getAndroidJarPatternsForDroidstubs(t, "public")
android.AssertArrayString(t, "order of patterns", []string{
- "--android-jar-pattern somedir/%/public/android.jar",
- "--android-jar-pattern someotherdir/%/public/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/public/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/public/android.jar",
}, patterns)
}
func TestSystemDroidstubs(t *testing.T) {
+ t.Parallel()
patterns := getAndroidJarPatternsForDroidstubs(t, "system")
android.AssertArrayString(t, "order of patterns", []string{
- "--android-jar-pattern somedir/%/system/android.jar",
- "--android-jar-pattern someotherdir/%/system/android.jar",
- "--android-jar-pattern somedir/%/public/android.jar",
- "--android-jar-pattern someotherdir/%/public/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/system/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/system/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/public/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/public/android.jar",
}, patterns)
}
func TestModuleLibDroidstubs(t *testing.T) {
+ t.Parallel()
patterns := getAndroidJarPatternsForDroidstubs(t, "module-lib")
android.AssertArrayString(t, "order of patterns", []string{
- "--android-jar-pattern somedir/%/module-lib/android.jar",
- "--android-jar-pattern someotherdir/%/module-lib/android.jar",
- "--android-jar-pattern somedir/%/system/android.jar",
- "--android-jar-pattern someotherdir/%/system/android.jar",
- "--android-jar-pattern somedir/%/public/android.jar",
- "--android-jar-pattern someotherdir/%/public/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/module-lib/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/module-lib/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/system/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/system/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/public/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/public/android.jar",
}, patterns)
}
@@ -175,14 +179,14 @@
patterns := getAndroidJarPatternsForDroidstubs(t, "system-server")
android.AssertArrayString(t, "order of patterns", []string{
- "--android-jar-pattern somedir/%/system-server/android.jar",
- "--android-jar-pattern someotherdir/%/system-server/android.jar",
- "--android-jar-pattern somedir/%/module-lib/android.jar",
- "--android-jar-pattern someotherdir/%/module-lib/android.jar",
- "--android-jar-pattern somedir/%/system/android.jar",
- "--android-jar-pattern someotherdir/%/system/android.jar",
- "--android-jar-pattern somedir/%/public/android.jar",
- "--android-jar-pattern someotherdir/%/public/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/system-server/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/system-server/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/module-lib/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/module-lib/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/system/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/system/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/public/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/public/android.jar",
}, patterns)
}
@@ -206,7 +210,7 @@
"bar-doc/a.java": nil,
})
- m := ctx.ModuleForTests("bar-stubs", "android_common")
+ m := ctx.ModuleForTests(t, "bar-stubs", "android_common")
metalava := m.Rule("metalava")
if g, w := metalava.Inputs.Strings(), []string{"bar-doc/a.java"}; !reflect.DeepEqual(w, g) {
t.Errorf("Expected inputs %q, got %q", w, g)
@@ -267,7 +271,7 @@
}
func checkSystemModulesUseByDroidstubs(t *testing.T, ctx *android.TestContext, moduleName string, systemJar string) {
- metalavaRule := ctx.ModuleForTests(moduleName, "android_common").Rule("metalava")
+ metalavaRule := ctx.ModuleForTests(t, moduleName, "android_common").Rule("metalava")
var systemJars []string
for _, i := range metalavaRule.Implicits {
systemJars = append(systemJars, i.Base())
@@ -300,10 +304,10 @@
"sdk/extensions/1/public/some-mainline-module-stubs.jar": nil,
"sdk/extensions/info.txt": nil,
})
- m := ctx.ModuleForTests("baz-stubs", "android_common")
+ m := ctx.ModuleForTests(t, "baz-stubs", "android_common")
manifest := m.Output("metalava.sbox.textproto")
cmdline := String(android.RuleBuilderSboxProtoForTests(t, ctx, manifest).Commands[0].Command)
- android.AssertStringDoesContain(t, "sdk-extensions-root present", cmdline, "--sdk-extensions-root sdk/extensions")
+ android.AssertStringDoesContain(t, "android-jar-pattern present", cmdline, "--android-jar-pattern sdk/extensions/{version:extension}/public/{module}.jar")
android.AssertStringDoesContain(t, "sdk-extensions-info present", cmdline, "--sdk-extensions-info sdk/extensions/info.txt")
}
@@ -328,7 +332,7 @@
},
)
- ctx.ModuleForTests("foo.api.contribution", "")
+ ctx.ModuleForTests(t, "foo.api.contribution", "")
}
func TestGeneratedApiContributionVisibilityTest(t *testing.T) {
@@ -362,7 +366,7 @@
},
)
- ctx.ModuleForTests("bar", "android_common")
+ ctx.ModuleForTests(t, "bar", "android_common")
}
func TestAconfigDeclarations(t *testing.T) {
@@ -404,14 +408,14 @@
android.AssertBoolEquals(t, "foo expected to depend on bar",
CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "bar"), true)
- m := result.ModuleForTests("foo", "android_common")
+ m := result.ModuleForTests(t, "foo", "android_common")
android.AssertStringDoesContain(t, "foo generates revert annotations file",
- strings.Join(m.AllOutputs(), ""), "revert-annotations-exportable.txt")
+ strings.Join(m.AllOutputs(), ""), "flags-config-exportable.xml")
// revert-annotations.txt passed to exportable stubs generation metalava command
manifest := m.Output("metalava_exportable.sbox.textproto")
cmdline := String(android.RuleBuilderSboxProtoForTests(t, result.TestContext, manifest).Commands[0].Command)
- android.AssertStringDoesContain(t, "flagged api hide command not included", cmdline, "revert-annotations-exportable.txt")
+ android.AssertStringDoesContain(t, "flagged api hide command not included", cmdline, "flags-config-exportable.xml")
android.AssertStringDoesContain(t, "foo generates exportable stubs jar",
strings.Join(m.AllOutputs(), ""), "exportable/foo-stubs.srcjar")
@@ -454,9 +458,9 @@
}
`)
- m := result.ModuleForTests("foo", "android_common")
+ m := result.ModuleForTests(t, "foo", "android_common")
- rule := m.Output("released-flagged-apis-exportable.txt")
+ rule := m.Output("released-flags-exportable.pb")
exposeWritableApisFilter := "--filter='state:ENABLED+permission:READ_ONLY' --filter='permission:READ_WRITE'"
android.AssertStringEquals(t, "Filter argument expected to contain READ_WRITE permissions", exposeWritableApisFilter, rule.Args["filter_args"])
}
diff --git a/java/fuzz.go b/java/fuzz.go
index 90f09a8..0e239f0 100644
--- a/java/fuzz.go
+++ b/java/fuzz.go
@@ -63,7 +63,7 @@
module.Module.properties.Installable = proptools.BoolPtr(true)
module.Module.dexpreopter.isTest = true
- module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
+ module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
module.Module.sourceProperties.Test_only = proptools.BoolPtr(true)
module.Module.sourceProperties.Top_level_test_target = true
@@ -107,23 +107,7 @@
}
func (j *JavaFuzzTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- if j.fuzzPackagedModule.FuzzProperties.Corpus != nil {
- j.fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, j.fuzzPackagedModule.FuzzProperties.Corpus)
- }
- if j.fuzzPackagedModule.FuzzProperties.Device_common_corpus != nil {
- j.fuzzPackagedModule.Corpus = append(j.fuzzPackagedModule.Corpus, android.PathsForModuleSrc(ctx, j.fuzzPackagedModule.FuzzProperties.Device_common_corpus)...)
- }
- if j.fuzzPackagedModule.FuzzProperties.Data != nil {
- j.fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, j.fuzzPackagedModule.FuzzProperties.Data)
- }
- if j.fuzzPackagedModule.FuzzProperties.Dictionary != nil {
- j.fuzzPackagedModule.Dictionary = android.PathForModuleSrc(ctx, *j.fuzzPackagedModule.FuzzProperties.Dictionary)
- }
- if j.fuzzPackagedModule.FuzzProperties.Fuzz_config != nil {
- configPath := android.PathForModuleOut(ctx, "config").Join(ctx, "config.json")
- android.WriteFileRule(ctx, configPath, j.fuzzPackagedModule.FuzzProperties.Fuzz_config.String())
- j.fuzzPackagedModule.Config = configPath
- }
+ j.fuzzPackagedModule = cc.PackageFuzzModule(ctx, j.fuzzPackagedModule)
_, sharedDeps := cc.CollectAllSharedDependencies(ctx)
for _, dep := range sharedDeps {
@@ -148,6 +132,8 @@
}
j.Test.GenerateAndroidBuildActions(ctx)
+
+ fuzz.SetFuzzPackagedModuleInfo(ctx, &j.fuzzPackagedModule)
}
type javaFuzzPackager struct {
@@ -169,6 +155,10 @@
if !ok {
return
}
+ fuzzInfo, ok := android.OtherModuleProvider(ctx, module, fuzz.FuzzPackagedModuleInfoProvider)
+ if !ok {
+ return
+ }
hostOrTargetString := "target"
if javaFuzzModule.Target().HostCross {
@@ -195,7 +185,7 @@
builder := android.NewRuleBuilder(pctx, ctx)
// Package the artifacts (data, corpus, config and dictionary) into a zipfile.
- files = s.PackageArtifacts(ctx, module, javaFuzzModule.fuzzPackagedModule, archDir, builder)
+ files = s.PackageArtifacts(ctx, module, &fuzzInfo, archDir, builder)
// Add .jar
if !javaFuzzModule.Host() {
@@ -209,7 +199,7 @@
files = append(files, fuzz.FileToZip{SourceFilePath: fPath})
}
- archDirs[archOs], ok = s.BuildZipFile(ctx, module, javaFuzzModule.fuzzPackagedModule, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
+ archDirs[archOs], ok = s.BuildZipFile(ctx, module, &fuzzInfo, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
if !ok {
return
}
diff --git a/java/fuzz_test.go b/java/fuzz_test.go
index f29c913..735b8da 100644
--- a/java/fuzz_test.go
+++ b/java/fuzz_test.go
@@ -30,6 +30,7 @@
)
func TestJavaFuzz(t *testing.T) {
+ t.Parallel()
result := prepForJavaFuzzTest.RunTestWithBp(t, `
java_fuzz {
name: "foo",
@@ -63,16 +64,16 @@
osCommonTarget := result.Config.BuildOSCommonTarget.String()
- javac := result.ModuleForTests("foo", osCommonTarget).Rule("javac")
- combineJar := result.ModuleForTests("foo", osCommonTarget).Description("for javac")
+ javac := result.ModuleForTests(t, "foo", osCommonTarget).Rule("javac")
+ combineJar := result.ModuleForTests(t, "foo", osCommonTarget).Description("for javac")
if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
}
- baz := result.ModuleForTests("baz", osCommonTarget).Rule("javac").Output.String()
- barOut := filepath.Join("out", "soong", ".intermediates", "bar", osCommonTarget, "javac-header", "bar.jar")
- bazOut := filepath.Join("out", "soong", ".intermediates", "baz", osCommonTarget, "javac-header", "baz.jar")
+ baz := result.ModuleForTests(t, "baz", osCommonTarget).Rule("javac").Output.String()
+ barOut := filepath.Join("out", "soong", ".intermediates", "bar", osCommonTarget, "local-javac-header", "bar.jar")
+ bazOut := filepath.Join("out", "soong", ".intermediates", "baz", osCommonTarget, "local-javac-header", "baz.jar")
android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], barOut)
android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], bazOut)
@@ -82,7 +83,7 @@
}
ctx := result.TestContext
- foo := ctx.ModuleForTests("foo", osCommonTarget).Module().(*JavaFuzzTest)
+ foo := ctx.ModuleForTests(t, "foo", osCommonTarget).Module().(*JavaFuzzTest)
expected := "lib64/libjni.so"
if runtime.GOOS == "darwin" {
diff --git a/java/gen.go b/java/gen.go
index 1b4f4c7..aab8418 100644
--- a/java/gen.go
+++ b/java/gen.go
@@ -26,15 +26,14 @@
)
func init() {
- pctx.SourcePathVariable("logtagsCmd", "build/make/tools/java-event-log-tags.py")
- pctx.SourcePathVariable("logtagsLib", "build/make/tools/event_log_tags.py")
+ pctx.HostBinToolVariable("logtagsCmd", "java-event-log-tags")
}
var (
logtags = pctx.AndroidStaticRule("logtags",
blueprint.RuleParams{
Command: "$logtagsCmd -o $out $in",
- CommandDeps: []string{"$logtagsCmd", "$logtagsLib"},
+ CommandDeps: []string{"$logtagsCmd"},
})
)
diff --git a/java/generated_java_library_test.go b/java/generated_java_library_test.go
index a5c4be1..e5ee586 100644
--- a/java/generated_java_library_test.go
+++ b/java/generated_java_library_test.go
@@ -52,6 +52,7 @@
}
func TestGenLib(t *testing.T) {
+ t.Parallel()
bp := `
test_java_gen_lib {
name: "javagenlibtest",
@@ -60,6 +61,6 @@
`
result := testGenLib(t, android.FixtureExpectsNoErrors, bp)
- javagenlibtest := result.ModuleForTests("javagenlibtest", "android_common").Module().(*GeneratedJavaLibraryModule)
+ javagenlibtest := result.ModuleForTests(t, "javagenlibtest", "android_common").Module().(*GeneratedJavaLibraryModule)
android.AssertPathsEndWith(t, "Generated_srcjars", []string{"/blah.srcjar"}, javagenlibtest.Library.properties.Generated_srcjars)
}
diff --git a/java/genrule_combiner.go b/java/genrule_combiner.go
new file mode 100644
index 0000000..357dc2c
--- /dev/null
+++ b/java/genrule_combiner.go
@@ -0,0 +1,252 @@
+// Copyright 2019 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 (
+ "fmt"
+ "io"
+
+ "android/soong/android"
+ "android/soong/dexpreopt"
+
+ "github.com/google/blueprint/depset"
+ "github.com/google/blueprint/proptools"
+)
+
+type GenruleCombiner struct {
+ android.ModuleBase
+ android.DefaultableModuleBase
+
+ genruleCombinerProperties GenruleCombinerProperties
+
+ headerJars android.Paths
+ implementationJars android.Paths
+ implementationAndResourceJars android.Paths
+ resourceJars android.Paths
+ aconfigProtoFiles android.Paths
+
+ srcJarArgs []string
+ srcJarDeps android.Paths
+
+ headerDirs android.Paths
+
+ combinedHeaderJar android.Path
+ combinedImplementationJar android.Path
+}
+
+type GenruleCombinerProperties struct {
+ // List of modules whose implementation (and resources) jars will be visible to modules
+ // that depend on this module.
+ Static_libs proptools.Configurable[[]string] `android:"arch_variant"`
+
+ // List of modules whose header jars will be visible to modules that depend on this module.
+ Headers proptools.Configurable[[]string] `android:"arch_variant"`
+}
+
+// java_genrule_combiner provides the implementation and resource jars from `static_libs`, with
+// the header jars from `headers`.
+//
+// This is useful when a java_genrule is used to change the implementation of a java library
+// without requiring a change in the header jars.
+func GenruleCombinerFactory() android.Module {
+ module := &GenruleCombiner{}
+
+ module.AddProperties(&module.genruleCombinerProperties)
+ InitJavaModule(module, android.HostAndDeviceSupported)
+ return module
+}
+
+var genruleCombinerHeaderDepTag = dependencyTag{name: "genrule_combiner_header"}
+
+func (j *GenruleCombiner) DepsMutator(ctx android.BottomUpMutatorContext) {
+ ctx.AddVariationDependencies(nil, staticLibTag,
+ j.genruleCombinerProperties.Static_libs.GetOrDefault(ctx, nil)...)
+ ctx.AddVariationDependencies(nil, genruleCombinerHeaderDepTag,
+ j.genruleCombinerProperties.Headers.GetOrDefault(ctx, nil)...)
+}
+
+func (j *GenruleCombiner) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ if len(j.genruleCombinerProperties.Static_libs.GetOrDefault(ctx, nil)) < 1 {
+ ctx.PropertyErrorf("static_libs", "at least one dependency is required")
+ }
+
+ if len(j.genruleCombinerProperties.Headers.GetOrDefault(ctx, nil)) < 1 {
+ ctx.PropertyErrorf("headers", "at least one dependency is required")
+ }
+
+ var transitiveHeaderJars []depset.DepSet[android.Path]
+ var transitiveImplementationJars []depset.DepSet[android.Path]
+ var transitiveResourceJars []depset.DepSet[android.Path]
+ var sdkVersion android.SdkSpec
+ var stubsLinkType StubsLinkType
+ moduleWithSdkDepInfo := &ModuleWithSdkDepInfo{}
+
+ // Collect the headers first, so that aconfig flag values for the libraries will override
+ // values from the headers (if they are different).
+ ctx.VisitDirectDepsWithTag(genruleCombinerHeaderDepTag, func(m android.Module) {
+ if dep, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
+ j.headerJars = append(j.headerJars, dep.HeaderJars...)
+
+ j.srcJarArgs = append(j.srcJarArgs, dep.SrcJarArgs...)
+ j.srcJarDeps = append(j.srcJarDeps, dep.SrcJarDeps...)
+ j.aconfigProtoFiles = append(j.aconfigProtoFiles, dep.AconfigIntermediateCacheOutputPaths...)
+ sdkVersion = dep.SdkVersion
+ stubsLinkType = dep.StubsLinkType
+ *moduleWithSdkDepInfo = *dep.ModuleWithSdkDepInfo
+
+ transitiveHeaderJars = append(transitiveHeaderJars, dep.TransitiveStaticLibsHeaderJars)
+ } else if dep, ok := android.OtherModuleProvider(ctx, m, android.CodegenInfoProvider); ok {
+ j.aconfigProtoFiles = append(j.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...)
+ } else {
+ ctx.PropertyErrorf("headers", "module %q cannot be used as a dependency", ctx.OtherModuleName(m))
+ }
+ })
+ ctx.VisitDirectDepsWithTag(staticLibTag, func(m android.Module) {
+ if dep, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
+ j.implementationJars = append(j.implementationJars, dep.ImplementationJars...)
+ j.implementationAndResourceJars = append(j.implementationAndResourceJars, dep.ImplementationAndResourcesJars...)
+ j.resourceJars = append(j.resourceJars, dep.ResourceJars...)
+
+ transitiveImplementationJars = append(transitiveImplementationJars, dep.TransitiveStaticLibsImplementationJars)
+ transitiveResourceJars = append(transitiveResourceJars, dep.TransitiveStaticLibsResourceJars)
+ j.aconfigProtoFiles = append(j.aconfigProtoFiles, dep.AconfigIntermediateCacheOutputPaths...)
+ } else if dep, ok := android.OtherModuleProvider(ctx, m, android.OutputFilesProvider); ok {
+ // This is provided by `java_genrule` modules.
+ j.implementationJars = append(j.implementationJars, dep.DefaultOutputFiles...)
+ j.implementationAndResourceJars = append(j.implementationAndResourceJars, dep.DefaultOutputFiles...)
+ stubsLinkType = Implementation
+ } else {
+ ctx.PropertyErrorf("static_libs", "module %q cannot be used as a dependency", ctx.OtherModuleName(m))
+ }
+ })
+
+ jarName := ctx.ModuleName() + ".jar"
+
+ if len(j.implementationAndResourceJars) > 1 {
+ outputFile := android.PathForModuleOut(ctx, "combined", jarName)
+ TransformJarsToJar(ctx, outputFile, "combine", j.implementationAndResourceJars,
+ android.OptionalPath{}, false, nil, nil)
+ j.combinedImplementationJar = outputFile
+ } else if len(j.implementationAndResourceJars) == 1 {
+ j.combinedImplementationJar = j.implementationAndResourceJars[0]
+ }
+
+ if len(j.headerJars) > 1 {
+ outputFile := android.PathForModuleOut(ctx, "turbine-combined", jarName)
+ TransformJarsToJar(ctx, outputFile, "turbine combine", j.headerJars,
+ android.OptionalPath{}, false, nil, []string{"META-INF/TRANSITIVE"})
+ j.combinedHeaderJar = outputFile
+ j.headerDirs = append(j.headerDirs, android.PathForModuleOut(ctx, "turbine-combined"))
+ } else if len(j.headerJars) == 1 {
+ j.combinedHeaderJar = j.headerJars[0]
+ }
+
+ javaInfo := &JavaInfo{
+ HeaderJars: android.Paths{j.combinedHeaderJar},
+ LocalHeaderJars: android.Paths{j.combinedHeaderJar},
+ TransitiveStaticLibsHeaderJars: depset.New(depset.PREORDER, android.Paths{j.combinedHeaderJar}, transitiveHeaderJars),
+ TransitiveStaticLibsImplementationJars: depset.New(depset.PREORDER, android.Paths{j.combinedImplementationJar}, transitiveImplementationJars),
+ TransitiveStaticLibsResourceJars: depset.New(depset.PREORDER, nil, transitiveResourceJars),
+ GeneratedSrcjars: android.Paths{j.combinedImplementationJar},
+ ImplementationAndResourcesJars: android.Paths{j.combinedImplementationJar},
+ ImplementationJars: android.Paths{j.combinedImplementationJar},
+ ModuleWithSdkDepInfo: moduleWithSdkDepInfo,
+ ResourceJars: j.resourceJars,
+ OutputFile: j.combinedImplementationJar,
+ SdkVersion: sdkVersion,
+ SrcJarArgs: j.srcJarArgs,
+ SrcJarDeps: j.srcJarDeps,
+ StubsLinkType: stubsLinkType,
+ AconfigIntermediateCacheOutputPaths: j.aconfigProtoFiles,
+ }
+ setExtraJavaInfo(ctx, j, javaInfo)
+ ctx.SetOutputFiles(android.Paths{javaInfo.OutputFile}, "")
+ ctx.SetOutputFiles(android.Paths{javaInfo.OutputFile}, android.DefaultDistTag)
+ ctx.SetOutputFiles(javaInfo.ImplementationAndResourcesJars, ".jar")
+ ctx.SetOutputFiles(javaInfo.HeaderJars, ".hjar")
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+
+}
+
+func (j *GenruleCombiner) GeneratedSourceFiles() android.Paths {
+ return append(android.Paths{}, j.combinedImplementationJar)
+}
+
+func (j *GenruleCombiner) GeneratedHeaderDirs() android.Paths {
+ return append(android.Paths{}, j.headerDirs...)
+}
+
+func (j *GenruleCombiner) GeneratedDeps() android.Paths {
+ return append(android.Paths{}, j.combinedImplementationJar)
+}
+
+func (j *GenruleCombiner) Srcs() android.Paths {
+ return append(android.Paths{}, j.implementationAndResourceJars...)
+}
+
+func (j *GenruleCombiner) HeaderJars() android.Paths {
+ return j.headerJars
+}
+
+func (j *GenruleCombiner) ImplementationAndResourcesJars() android.Paths {
+ return j.implementationAndResourceJars
+}
+
+func (j *GenruleCombiner) DexJarBuildPath(ctx android.ModuleErrorfContext) android.Path {
+ return nil
+}
+
+func (j *GenruleCombiner) DexJarInstallPath() android.Path {
+ return nil
+}
+
+func (j *GenruleCombiner) AidlIncludeDirs() android.Paths {
+ return nil
+}
+
+func (j *GenruleCombiner) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
+ return nil
+}
+
+func (j *GenruleCombiner) JacocoReportClassesFile() android.Path {
+ return nil
+}
+
+func (j *GenruleCombiner) AndroidMk() android.AndroidMkData {
+ return android.AndroidMkData{
+ Class: "JAVA_LIBRARIES",
+ OutputFile: android.OptionalPathForPath(j.combinedImplementationJar),
+ // Make does not support Windows Java modules
+ Disabled: j.Os() == android.Windows,
+ Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
+ Extra: []android.AndroidMkExtraFunc{
+ func(w io.Writer, outputFile android.Path) {
+ fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
+ fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", j.combinedHeaderJar.String())
+ fmt.Fprintln(w, "LOCAL_SOONG_CLASSES_JAR :=", j.combinedImplementationJar.String())
+ },
+ },
+ }
+}
+
+// implement the following interface for IDE completion.
+var _ android.IDEInfo = (*GenruleCombiner)(nil)
+
+func (j *GenruleCombiner) IDEInfo(ctx android.BaseModuleContext, ideInfo *android.IdeInfo) {
+ ideInfo.Deps = append(ideInfo.Deps, j.genruleCombinerProperties.Static_libs.GetOrDefault(ctx, nil)...)
+ ideInfo.Libs = append(ideInfo.Libs, j.genruleCombinerProperties.Static_libs.GetOrDefault(ctx, nil)...)
+ ideInfo.Deps = append(ideInfo.Deps, j.genruleCombinerProperties.Headers.GetOrDefault(ctx, nil)...)
+ ideInfo.Libs = append(ideInfo.Libs, j.genruleCombinerProperties.Headers.GetOrDefault(ctx, nil)...)
+}
diff --git a/java/genrule_combiner_test.go b/java/genrule_combiner_test.go
new file mode 100644
index 0000000..7d024cf
--- /dev/null
+++ b/java/genrule_combiner_test.go
@@ -0,0 +1,237 @@
+// Copyright 2018 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 (
+ "reflect"
+ "testing"
+
+ "android/soong/android"
+)
+
+func TestJarGenruleCombinerSingle(t *testing.T) {
+ t.Parallel()
+ t.Helper()
+ ctx := prepareForJavaTest.RunTestWithBp(t, `
+ java_library {
+ name: "foo",
+ srcs: ["a.java"],
+ }
+
+ java_genrule {
+ name: "gen",
+ tool_files: ["b.java"],
+ cmd: "$(location b.java) $(in) $(out)",
+ out: ["gen.jar"],
+ srcs: [":foo"],
+ }
+
+ java_genrule_combiner {
+ name: "jarcomb",
+ static_libs: ["gen"],
+ headers: ["foo"],
+ }
+
+ java_library {
+ name: "bar",
+ static_libs: ["jarcomb"],
+ srcs: ["c.java"],
+ }
+
+ java_library {
+ name: "baz",
+ libs: ["jarcomb"],
+ srcs: ["c.java"],
+ }
+ `).TestContext
+
+ fooMod := ctx.ModuleForTests(t, "foo", "android_common")
+ fooCombined := fooMod.Output("turbine-combined/foo.jar")
+ fooOutputFiles, _ := android.OtherModuleProvider(ctx.OtherModuleProviderAdaptor(), fooMod.Module(), android.OutputFilesProvider)
+ fooHeaderJars := fooOutputFiles.TaggedOutputFiles[".hjar"]
+
+ genMod := ctx.ModuleForTests(t, "gen", "android_common")
+ gen := genMod.Output("gen.jar")
+
+ jarcombMod := ctx.ModuleForTests(t, "jarcomb", "android_common")
+ jarcombInfo, _ := android.OtherModuleProvider(ctx.OtherModuleProviderAdaptor(), jarcombMod.Module(), JavaInfoProvider)
+ jarcombOutputFiles, _ := android.OtherModuleProvider(ctx.OtherModuleProviderAdaptor(), jarcombMod.Module(), android.OutputFilesProvider)
+
+ // Confirm that jarcomb simply forwards the jarcomb implementation and the foo headers.
+ if len(jarcombOutputFiles.DefaultOutputFiles) != 1 ||
+ android.PathRelativeToTop(jarcombOutputFiles.DefaultOutputFiles[0]) != android.PathRelativeToTop(gen.Output) {
+ t.Errorf("jarcomb Implementation %v is not [%q]",
+ android.PathsRelativeToTop(jarcombOutputFiles.DefaultOutputFiles), android.PathRelativeToTop(gen.Output))
+ }
+ jarcombHeaderJars := jarcombOutputFiles.TaggedOutputFiles[".hjar"]
+ if !reflect.DeepEqual(jarcombHeaderJars, fooHeaderJars) {
+ t.Errorf("jarcomb Header jar %v is not %q",
+ jarcombHeaderJars, fooHeaderJars)
+ }
+
+ // Confirm that JavaInfoProvider agrees.
+ if len(jarcombInfo.ImplementationJars) != 1 ||
+ android.PathRelativeToTop(jarcombInfo.ImplementationJars[0]) != android.PathRelativeToTop(gen.Output) {
+ t.Errorf("jarcomb ImplementationJars %v is not [%q]",
+ android.PathsRelativeToTop(jarcombInfo.ImplementationJars), android.PathRelativeToTop(gen.Output))
+ }
+ if len(jarcombInfo.HeaderJars) != 1 ||
+ android.PathRelativeToTop(jarcombInfo.HeaderJars[0]) != android.PathRelativeToTop(fooCombined.Output) {
+ t.Errorf("jarcomb HeaderJars %v is not [%q]",
+ android.PathsRelativeToTop(jarcombInfo.HeaderJars), android.PathRelativeToTop(fooCombined.Output))
+ }
+
+ barMod := ctx.ModuleForTests(t, "bar", "android_common")
+ bar := barMod.Output("javac/bar.jar")
+ barCombined := barMod.Output("combined/bar.jar")
+
+ // Confirm that bar uses the Implementation from gen and headerJars from foo.
+ if len(barCombined.Inputs) != 2 ||
+ barCombined.Inputs[0].String() != bar.Output.String() ||
+ barCombined.Inputs[1].String() != gen.Output.String() {
+ t.Errorf("bar combined jar inputs %v is not [%q, %q]",
+ barCombined.Inputs.Strings(), bar.Output.String(), gen.Output.String())
+ }
+
+ bazMod := ctx.ModuleForTests(t, "baz", "android_common")
+ baz := bazMod.Output("javac/baz.jar")
+
+ string_in_list := func(s string, l []string) bool {
+ for _, v := range l {
+ if s == v {
+ return true
+ }
+ }
+ return false
+ }
+
+ // Confirm that baz uses the headerJars from foo.
+ bazImplicitsRel := android.PathsRelativeToTop(baz.Implicits)
+ for _, v := range android.PathsRelativeToTop(fooHeaderJars) {
+ if !string_in_list(v, bazImplicitsRel) {
+ t.Errorf("baz Implicits %v does not contain %q", bazImplicitsRel, v)
+ }
+ }
+}
+
+func TestJarGenruleCombinerMulti(t *testing.T) {
+ t.Parallel()
+ t.Helper()
+ ctx := prepareForJavaTest.RunTestWithBp(t, `
+ java_library {
+ name: "foo1",
+ srcs: ["foo1_a.java"],
+ }
+
+ java_library {
+ name: "foo2",
+ srcs: ["foo2_a.java"],
+ }
+
+ java_genrule {
+ name: "gen1",
+ tool_files: ["b.java"],
+ cmd: "$(location b.java) $(in) $(out)",
+ out: ["gen1.jar"],
+ srcs: [":foo1"],
+ }
+
+ java_genrule {
+ name: "gen2",
+ tool_files: ["b.java"],
+ cmd: "$(location b.java) $(in) $(out)",
+ out: ["gen2.jar"],
+ srcs: [":foo2"],
+ }
+
+ // Combine multiple java_genrule modules.
+ java_genrule_combiner {
+ name: "jarcomb",
+ static_libs: ["gen1", "gen2"],
+ headers: ["foo1", "foo2"],
+ }
+
+ java_library {
+ name: "bar",
+ static_libs: ["jarcomb"],
+ srcs: ["c.java"],
+ }
+
+ java_library {
+ name: "baz",
+ libs: ["jarcomb"],
+ srcs: ["c.java"],
+ }
+ `).TestContext
+
+ gen1Mod := ctx.ModuleForTests(t, "gen1", "android_common")
+ gen1 := gen1Mod.Output("gen1.jar")
+ gen2Mod := ctx.ModuleForTests(t, "gen2", "android_common")
+ gen2 := gen2Mod.Output("gen2.jar")
+
+ jarcombMod := ctx.ModuleForTests(t, "jarcomb", "android_common")
+ jarcomb := jarcombMod.Output("combined/jarcomb.jar")
+ jarcombTurbine := jarcombMod.Output("turbine-combined/jarcomb.jar")
+ _ = jarcombTurbine
+ jarcombInfo, _ := android.OtherModuleProvider(ctx.OtherModuleProviderAdaptor(), jarcombMod.Module(), JavaInfoProvider)
+ _ = jarcombInfo
+ jarcombOutputFiles, _ := android.OtherModuleProvider(ctx.OtherModuleProviderAdaptor(), jarcombMod.Module(), android.OutputFilesProvider)
+ jarcombHeaderJars := jarcombOutputFiles.TaggedOutputFiles[".hjar"]
+
+ if len(jarcomb.Inputs) != 2 ||
+ jarcomb.Inputs[0].String() != gen1.Output.String() ||
+ jarcomb.Inputs[1].String() != gen2.Output.String() {
+ t.Errorf("jarcomb inputs %v are not [%q, %q]",
+ jarcomb.Inputs.Strings(), gen1.Output.String(), gen2.Output.String())
+ }
+
+ if len(jarcombHeaderJars) != 1 ||
+ android.PathRelativeToTop(jarcombHeaderJars[0]) != android.PathRelativeToTop(jarcombTurbine.Output) {
+ t.Errorf("jarcomb Header jars %v is not [%q]",
+ android.PathsRelativeToTop(jarcombHeaderJars), android.PathRelativeToTop(jarcombTurbine.Output))
+ }
+
+ barMod := ctx.ModuleForTests(t, "bar", "android_common")
+ bar := barMod.Output("javac/bar.jar")
+ barCombined := barMod.Output("combined/bar.jar")
+
+ // Confirm that bar uses the Implementation and Headers from jarcomb.
+ if len(barCombined.Inputs) != 2 ||
+ barCombined.Inputs[0].String() != bar.Output.String() ||
+ barCombined.Inputs[1].String() != jarcomb.Output.String() {
+ t.Errorf("bar combined jar inputs %v is not [%q, %q]",
+ barCombined.Inputs.Strings(), bar.Output.String(), jarcomb.Output.String())
+ }
+
+ bazMod := ctx.ModuleForTests(t, "baz", "android_common")
+ baz := bazMod.Output("javac/baz.jar")
+
+ string_in_list := func(s string, l []string) bool {
+ for _, v := range l {
+ if s == v {
+ return true
+ }
+ }
+ return false
+ }
+
+ // Confirm that baz uses the headerJars from foo.
+ bazImplicitsRel := android.PathsRelativeToTop(baz.Implicits)
+ for _, v := range android.PathsRelativeToTop(jarcombHeaderJars) {
+ if !string_in_list(v, bazImplicitsRel) {
+ t.Errorf("baz Implicits %v does not contain %q", bazImplicitsRel, v)
+ }
+ }
+}
diff --git a/java/genrule_test.go b/java/genrule_test.go
index 1c294b2..c112e45 100644
--- a/java/genrule_test.go
+++ b/java/genrule_test.go
@@ -31,6 +31,7 @@
}
func TestGenruleCmd(t *testing.T) {
+ t.Parallel()
fs := map[string][]byte{
"tool": nil,
"foo": nil,
@@ -56,7 +57,7 @@
t.Fatal(errs)
}
- gen := ctx.ModuleForTests("gen", "android_common").Output("out")
+ gen := ctx.ModuleForTests(t, "gen", "android_common").Output("out")
expected := []string{"foo"}
if !reflect.DeepEqual(expected, gen.Implicits.Strings()[:len(expected)]) {
t.Errorf(`want arm inputs %v, got %v`, expected, gen.Implicits.Strings())
@@ -64,6 +65,7 @@
}
func TestJarGenrules(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -91,11 +93,11 @@
}
`)
- foo := ctx.ModuleForTests("foo", "android_common").Output("javac/foo.jar")
- jargen := ctx.ModuleForTests("jargen", "android_common").Output("jargen.jar")
- bar := ctx.ModuleForTests("bar", "android_common").Output("javac/bar.jar")
- baz := ctx.ModuleForTests("baz", "android_common").Output("javac/baz.jar")
- barCombined := ctx.ModuleForTests("bar", "android_common").Output("combined/bar.jar")
+ foo := ctx.ModuleForTests(t, "foo", "android_common").Output("javac/foo.jar")
+ jargen := ctx.ModuleForTests(t, "jargen", "android_common").Output("jargen.jar")
+ bar := ctx.ModuleForTests(t, "bar", "android_common").Output("javac/bar.jar")
+ baz := ctx.ModuleForTests(t, "baz", "android_common").Output("javac/baz.jar")
+ barCombined := ctx.ModuleForTests(t, "bar", "android_common").Output("combined/bar.jar")
if g, w := jargen.Implicits.Strings(), foo.Output.String(); !android.InList(w, g) {
t.Errorf("expected jargen inputs [%q], got %q", w, g)
diff --git a/java/hiddenapi.go b/java/hiddenapi.go
index b1a9deb..c9a1f2b 100644
--- a/java/hiddenapi.go
+++ b/java/hiddenapi.go
@@ -97,7 +97,7 @@
// Save the classes jars even if this is not active as they may be used by modular hidden API
// processing.
classesJars := android.Paths{classesJar}
- ctx.VisitDirectDepsWithTag(hiddenApiAnnotationsTag, func(dep android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(hiddenApiAnnotationsTag, func(dep android.ModuleProxy) {
if javaInfo, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok {
classesJars = append(classesJars, javaInfo.ImplementationJars...)
}
diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go
index 7d21b7a..2c86942 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -171,11 +171,11 @@
// Now match the apex part of the boot image configuration.
requiredApex := configuredBootJars.Apex(index)
if android.IsConfiguredJarForPlatform(requiredApex) {
- if len(apexInfo.InApexVariants) != 0 {
+ if apexInfo.ApexVariationName != "" {
// A platform variant is required but this is for an apex so ignore it.
return false
}
- } else if !apexInfo.InApexVariant(requiredApex) {
+ } else if apexInfo.BaseApexName != requiredApex {
// An apex variant for a specific apex is required but this is the wrong apex.
return false
}
diff --git a/java/hiddenapi_singleton_test.go b/java/hiddenapi_singleton_test.go
index afe8b4c..147f326 100644
--- a/java/hiddenapi_singleton_test.go
+++ b/java/hiddenapi_singleton_test.go
@@ -44,6 +44,7 @@
)
func TestHiddenAPISingleton(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
hiddenApiFixtureFactory,
FixtureConfigureBootJars("platform:foo"),
@@ -56,13 +57,14 @@
}
`)
- hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common")
+ hiddenAPI := result.ModuleForTests(t, "platform-bootclasspath", "android_common")
hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags")
want := "--boot-dex=out/soong/.intermediates/foo/android_common/aligned/foo.jar"
android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, want)
}
func TestHiddenAPISingletonWithSourceAndPrebuiltPreferredButNoDex(t *testing.T) {
+ t.Parallel()
expectedErrorMessage := "module prebuilt_foo{os:android,arch:common} does not provide a dex jar"
android.GroupFixturePreparers(
@@ -86,6 +88,7 @@
}
func TestHiddenAPISingletonWithPrebuilt(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
hiddenApiFixtureFactory,
FixtureConfigureBootJars("platform:foo"),
@@ -98,13 +101,14 @@
}
`)
- hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common")
+ hiddenAPI := result.ModuleForTests(t, "platform-bootclasspath", "android_common")
hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags")
want := "--boot-dex=out/soong/.intermediates/foo/android_common/aligned/foo.jar"
android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, want)
}
func TestHiddenAPISingletonWithPrebuiltUseSource(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
hiddenApiFixtureFactory,
FixtureConfigureBootJars("platform:foo"),
@@ -124,7 +128,7 @@
}
`)
- hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common")
+ hiddenAPI := result.ModuleForTests(t, "platform-bootclasspath", "android_common")
hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags")
fromSourceJarArg := "--boot-dex=out/soong/.intermediates/foo/android_common/aligned/foo.jar"
android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, fromSourceJarArg)
@@ -134,6 +138,7 @@
}
func TestHiddenAPISingletonWithPrebuiltOverrideSource(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
hiddenApiFixtureFactory,
FixtureConfigureBootJars("platform:foo"),
@@ -153,7 +158,7 @@
}
`)
- hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common")
+ hiddenAPI := result.ModuleForTests(t, "platform-bootclasspath", "android_common")
hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags")
prebuiltJarArg := "--boot-dex=out/soong/.intermediates/prebuilt_foo/android_common/dex/foo.jar"
android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, prebuiltJarArg)
@@ -163,6 +168,7 @@
}
func TestHiddenAPISingletonSdks(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
unbundledBuild bool
@@ -213,7 +219,7 @@
}
`)
- hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common")
+ hiddenAPI := result.ModuleForTests(t, "platform-bootclasspath", "android_common")
hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags")
wantPublicStubs := "--public-stub-classpath=" + generateSdkDexPath(tc.publicStub, tc.unbundledBuild)
android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, wantPublicStubs)
@@ -246,6 +252,7 @@
}
func TestHiddenAPISingletonWithPrebuiltCsvFile(t *testing.T) {
+ t.Parallel()
// The idea behind this test is to ensure that when the build is
// confugured with a PrebuiltHiddenApiDir that the rules for the
@@ -272,9 +279,9 @@
expectedCpOutput := "out/soong/hiddenapi/hiddenapi-flags.csv"
expectedFlagsCsv := "out/soong/hiddenapi/hiddenapi-flags.csv"
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
- hiddenAPI := result.SingletonForTests("hiddenapi")
+ hiddenAPI := result.SingletonForTests(t, "hiddenapi")
cpRule := hiddenAPI.Rule("Cp")
actualCpInput := cpRule.BuildParams.Input
actualCpOutput := cpRule.BuildParams.Output
@@ -289,6 +296,7 @@
}
func TestHiddenAPIEncoding_JavaSdkLibrary(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
hiddenApiFixtureFactory,
@@ -310,7 +318,7 @@
`)
checkDexEncoded := func(t *testing.T, name, unencodedDexJar, encodedDexJar string) {
- moduleForTests := result.ModuleForTests(name+".impl", "android_common")
+ moduleForTests := result.ModuleForTests(t, name+".impl", "android_common")
encodeDexRule := moduleForTests.Rule("hiddenAPIEncodeDex")
actualUnencodedDexJar := encodeDexRule.Input
@@ -324,10 +332,7 @@
android.AssertPathRelativeToTopEquals(t, "encode embedded java_library", encodedDexJar, exportedDexJar)
}
- // The java_library embedded with the java_sdk_library must be dex encoded.
- t.Run("foo", func(t *testing.T) {
- expectedUnencodedDexJar := "out/soong/.intermediates/foo.impl/android_common/aligned/foo.jar"
- expectedEncodedDexJar := "out/soong/.intermediates/foo.impl/android_common/hiddenapi/foo.jar"
- checkDexEncoded(t, "foo", expectedUnencodedDexJar, expectedEncodedDexJar)
- })
+ expectedUnencodedDexJar := "out/soong/.intermediates/foo.impl/android_common/aligned/foo.jar"
+ expectedEncodedDexJar := "out/soong/.intermediates/foo.impl/android_common/hiddenapi/foo.jar"
+ checkDexEncoded(t, "foo", expectedUnencodedDexJar, expectedEncodedDexJar)
}
diff --git a/java/jacoco_test.go b/java/jacoco_test.go
index 1882908..58a091e 100644
--- a/java/jacoco_test.go
+++ b/java/jacoco_test.go
@@ -17,6 +17,7 @@
import "testing"
func TestJacocoFilterToSpecs(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name, in, out string
}{
@@ -54,6 +55,7 @@
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
got, err := jacocoFilterToSpec(testCase.in)
if err != nil {
t.Error(err)
@@ -66,6 +68,7 @@
}
func TestJacocoFiltersToZipCommand(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
includes, excludes []string
@@ -96,6 +99,7 @@
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
got := jacocoFiltersToZipCommand(testCase.includes, testCase.excludes)
if got != testCase.out {
t.Errorf("expected %q got %q", testCase.out, got)
diff --git a/java/jarjar_test.go b/java/jarjar_test.go
index 82bfa2b..b689761 100644
--- a/java/jarjar_test.go
+++ b/java/jarjar_test.go
@@ -22,7 +22,7 @@
)
func AssertJarJarRename(t *testing.T, result *android.TestResult, libName, original, expectedRename string) {
- module := result.ModuleForTests(libName, "android_common")
+ module := result.ModuleForTests(t, libName, "android_common")
provider, found := android.OtherModuleProvider(result.OtherModuleProviderAdaptor(), module.Module(), JarJarProvider)
android.AssertBoolEquals(t, fmt.Sprintf("found provider (%s)", libName), true, found)
diff --git a/java/java.go b/java/java.go
index e1cfea5..2e14b82 100644
--- a/java/java.go
+++ b/java/java.go
@@ -64,6 +64,7 @@
ctx.RegisterModuleType("java_api_library", ApiLibraryFactory)
ctx.RegisterModuleType("java_api_contribution", ApiContributionFactory)
ctx.RegisterModuleType("java_api_contribution_import", ApiContributionImportFactory)
+ ctx.RegisterModuleType("java_genrule_combiner", GenruleCombinerFactory)
// This mutator registers dependencies on dex2oat for modules that should be
// dexpreopted. This is done late when the final variants have been
@@ -250,6 +251,36 @@
var ProguardSpecInfoProvider = blueprint.NewProvider[ProguardSpecInfo]()
+type AndroidLibraryDependencyInfo struct {
+ ExportPackage android.Path
+ ResourcesNodeDepSet depset.DepSet[*resourcesNode]
+ RRODirsDepSet depset.DepSet[rroDir]
+ ManifestsDepSet depset.DepSet[android.Path]
+}
+
+type UsesLibraryDependencyInfo struct {
+ DexJarInstallPath android.Path
+ ClassLoaderContexts dexpreopt.ClassLoaderContextMap
+}
+
+type SdkLibraryComponentDependencyInfo struct {
+ // The name of the implementation library for the optional SDK library or nil, if there isn't one.
+ OptionalSdkLibraryImplementation *string
+}
+
+type ProvidesUsesLibInfo struct {
+ ProvidesUsesLib *string
+}
+
+type ModuleWithUsesLibraryInfo struct {
+ UsesLibrary *usesLibrary
+}
+
+type ModuleWithSdkDepInfo struct {
+ SdkLinkType sdkLinkType
+ Stubs bool
+}
+
// JavaInfo contains information about a java module for use by modules that depend on it.
type JavaInfo struct {
// HeaderJars is a list of jars that can be passed as the javac classpath in order to link
@@ -328,10 +359,109 @@
AconfigIntermediateCacheOutputPaths android.Paths
SdkVersion android.SdkSpec
+
+ // output file of the module, which may be a classes jar or a dex jar
+ OutputFile android.Path
+
+ ExtraOutputFiles android.Paths
+
+ AndroidLibraryDependencyInfo *AndroidLibraryDependencyInfo
+
+ UsesLibraryDependencyInfo *UsesLibraryDependencyInfo
+
+ SdkLibraryComponentDependencyInfo *SdkLibraryComponentDependencyInfo
+
+ ProvidesUsesLibInfo *ProvidesUsesLibInfo
+
+ MissingOptionalUsesLibs []string
+
+ ModuleWithSdkDepInfo *ModuleWithSdkDepInfo
+
+ // output file containing classes.dex and resources
+ DexJarFile OptionalDexJarPath
+
+ // installed file for binary dependency
+ InstallFile android.Path
+
+ // The path to the dex jar that is in the boot class path. If this is unset then the associated
+ // module is not a boot jar, but could be one of the <x>-hiddenapi modules that provide additional
+ // annotations for the <x> boot dex jar but which do not actually provide a boot dex jar
+ // themselves.
+ //
+ // This must be the path to the unencoded dex jar as the encoded dex jar indirectly depends on
+ // this file so using the encoded dex jar here would result in a cycle in the ninja rules.
+ BootDexJarPath OptionalDexJarPath
+
+ // The compressed state of the dex file being encoded. This is used to ensure that the encoded
+ // dex file has the same state.
+ UncompressDexState *bool
+
+ // True if the module containing this structure contributes to the hiddenapi information or has
+ // that information encoded within it.
+ Active bool
+
+ BuiltInstalled string
+
+ // The config is used for two purposes:
+ // - Passing dexpreopt information about libraries from Soong to Make. This is needed when
+ // a <uses-library> is defined in Android.bp, but used in Android.mk (see dex_preopt_config_merger.py).
+ // Note that dexpreopt.config might be needed even if dexpreopt is disabled for the library itself.
+ // - Dexpreopt post-processing (using dexpreopt artifacts from a prebuilt system image to incrementally
+ // dexpreopt another partition).
+ ConfigPath android.WritablePath
+
+ LogtagsSrcs android.Paths
+
+ ProguardDictionary android.OptionalPath
+
+ ProguardUsageZip android.OptionalPath
+
+ LinterReports android.Paths
+
+ // installed file for hostdex copy
+ HostdexInstallFile android.InstallPath
+
+ // Additional srcJars tacked in by GeneratedJavaLibraryModule
+ GeneratedSrcjars []android.Path
+
+ // True if profile-guided optimization is actually enabled.
+ ProfileGuided bool
+
+ Stem string
+
+ DexJarBuildPath OptionalDexJarPath
+
+ DexpreopterInfo *DexpreopterInfo
+
+ XrefJavaFiles android.Paths
+ XrefKotlinFiles android.Paths
}
var JavaInfoProvider = blueprint.NewProvider[*JavaInfo]()
+type DexpreopterInfo struct {
+ // The path to the profile on host that dexpreopter generates. This is used as the input for
+ // dex2oat.
+ OutputProfilePathOnHost android.Path
+ // If the java module is to be installed into an APEX, this list contains information about the
+ // dexpreopt outputs to be installed on devices. Note that these dexpreopt outputs are installed
+ // outside of the APEX.
+ ApexSystemServerDexpreoptInstalls []DexpreopterInstall
+
+ // ApexSystemServerDexJars returns the list of dex jars if this is an apex system server jar.
+ ApexSystemServerDexJars android.Paths
+}
+
+type JavaLibraryInfo struct {
+ Prebuilt bool
+}
+
+var JavaLibraryInfoProvider = blueprint.NewProvider[JavaLibraryInfo]()
+
+type JavaDexImportInfo struct{}
+
+var JavaDexImportInfoProvider = blueprint.NewProvider[JavaDexImportInfo]()
+
// SyspropPublicStubInfo contains info about the sysprop public stub library that corresponds to
// the sysprop implementation library.
type SyspropPublicStubInfo struct {
@@ -449,6 +579,7 @@
extraLintCheckTag = dependencyTag{name: "extra-lint-check", toolchain: true}
jniLibTag = dependencyTag{name: "jnilib", runtimeLinked: true}
r8LibraryJarTag = dependencyTag{name: "r8-libraryjar", runtimeLinked: true}
+ traceReferencesTag = dependencyTag{name: "trace-references"}
syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"}
javaApiContributionTag = dependencyTag{name: "java-api-contribution"}
aconfigDeclarationTag = dependencyTag{name: "aconfig-declaration"}
@@ -479,11 +610,12 @@
kotlinPluginTag,
syspropPublicStubDepTag,
instrumentationForTag,
+ traceReferencesTag,
}
)
func IsLibDepTag(depTag blueprint.DependencyTag) bool {
- return depTag == libTag || depTag == sdkLibTag
+ return depTag == libTag
}
func IsStaticLibDepTag(depTag blueprint.DependencyTag) bool {
@@ -540,12 +672,12 @@
ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...)
ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...)
ctx.AddVariationDependencies(nil, sdkLibTag, sdkDep.classpath...)
- if d.effectiveOptimizeEnabled() && sdkDep.hasStandardLibs() {
+ if d.effectiveOptimizeEnabled(ctx) && sdkDep.hasStandardLibs() {
ctx.AddVariationDependencies(nil, proguardRaiseTag,
config.LegacyCorePlatformBootclasspathLibraries...,
)
}
- if d.effectiveOptimizeEnabled() && sdkDep.hasFrameworkLibs() {
+ if d.effectiveOptimizeEnabled(ctx) && sdkDep.hasFrameworkLibs() {
ctx.AddVariationDependencies(nil, proguardRaiseTag, config.FrameworkLibraries...)
}
}
@@ -599,11 +731,11 @@
transitiveStaticLibsResourceJars []depset.DepSet[android.Path]
}
-func checkProducesJars(ctx android.ModuleContext, dep android.SourceFileProducer) {
- for _, f := range dep.Srcs() {
+func checkProducesJars(ctx android.ModuleContext, dep android.SourceFilesInfo, module android.ModuleProxy) {
+ for _, f := range dep.Srcs {
if f.Ext() != ".jar" {
ctx.ModuleErrorf("genrule %q must generate files ending with .jar to be used as a libs or static_libs dependency",
- ctx.OtherModuleName(dep.(blueprint.Module)))
+ ctx.OtherModuleName(module))
}
}
}
@@ -721,6 +853,8 @@
combinedExportedProguardFlagsFile android.Path
InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.InstallPaths)
+
+ apiXmlFile android.WritablePath
}
var _ android.ApexModule = (*Library)(nil)
@@ -1008,7 +1142,7 @@
j.dexpreopter.disableDexpreopt()
}
}
- j.compile(ctx, nil, nil, nil, nil)
+ javaInfo := j.compile(ctx, nil, nil, nil, nil)
j.setInstallRules(ctx)
@@ -1017,7 +1151,97 @@
TopLevelTarget: j.sourceProperties.Top_level_test_target,
})
+ android.SetProvider(ctx, JavaLibraryInfoProvider, JavaLibraryInfo{
+ Prebuilt: false,
+ })
+
+ if javaInfo != nil {
+ setExtraJavaInfo(ctx, j, javaInfo)
+ javaInfo.ExtraOutputFiles = j.extraOutputFiles
+ javaInfo.DexJarFile = j.dexJarFile
+ javaInfo.InstallFile = j.installFile
+ javaInfo.BootDexJarPath = j.bootDexJarPath
+ javaInfo.UncompressDexState = j.uncompressDexState
+ javaInfo.Active = j.active
+ javaInfo.BuiltInstalled = j.builtInstalled
+ javaInfo.ConfigPath = j.configPath
+ javaInfo.LogtagsSrcs = j.logtagsSrcs
+ javaInfo.ProguardDictionary = j.proguardDictionary
+ javaInfo.ProguardUsageZip = j.proguardUsageZip
+ javaInfo.LinterReports = j.reports
+ javaInfo.HostdexInstallFile = j.hostdexInstallFile
+ javaInfo.GeneratedSrcjars = j.properties.Generated_srcjars
+ javaInfo.ProfileGuided = j.dexpreopter.dexpreoptProperties.Dex_preopt_result.Profile_guided
+
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+ }
+
setOutputFiles(ctx, j.Module)
+
+ j.javaLibraryModuleInfoJSON(ctx)
+
+ buildComplianceMetadata(ctx)
+
+ j.createApiXmlFile(ctx)
+
+ if j.dexer.proguardDictionary.Valid() {
+ android.SetProvider(ctx, ProguardProvider, ProguardInfo{
+ ModuleName: ctx.ModuleName(),
+ Class: "JAVA_LIBRARIES",
+ ProguardDictionary: j.dexer.proguardDictionary.Path(),
+ ProguardUsageZip: j.dexer.proguardUsageZip.Path(),
+ ClassesJar: j.implementationAndResourcesJar,
+ })
+ }
+}
+
+func (j *Library) javaLibraryModuleInfoJSON(ctx android.ModuleContext) *android.ModuleInfoJSON {
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Class = []string{"JAVA_LIBRARIES"}
+ if j.implementationAndResourcesJar != nil {
+ moduleInfoJSON.ClassesJar = []string{j.implementationAndResourcesJar.String()}
+ }
+ moduleInfoJSON.SystemSharedLibs = []string{"none"}
+
+ if j.hostDexNeeded() {
+ hostDexModuleInfoJSON := ctx.ExtraModuleInfoJSON()
+ hostDexModuleInfoJSON.SubName = "-hostdex"
+ hostDexModuleInfoJSON.Class = []string{"JAVA_LIBRARIES"}
+ if j.implementationAndResourcesJar != nil {
+ hostDexModuleInfoJSON.ClassesJar = []string{j.implementationAndResourcesJar.String()}
+ }
+ hostDexModuleInfoJSON.SystemSharedLibs = []string{"none"}
+ hostDexModuleInfoJSON.SupportedVariantsOverride = []string{"HOST"}
+ }
+
+ if j.hideApexVariantFromMake {
+ moduleInfoJSON.Disabled = true
+ }
+ return moduleInfoJSON
+}
+
+func buildComplianceMetadata(ctx android.ModuleContext) {
+ // Dump metadata that can not be done in android/compliance-metadata.go
+ complianceMetadataInfo := ctx.ComplianceMetadataInfo()
+ builtFiles := ctx.GetOutputFiles().DefaultOutputFiles.Strings()
+ for _, paths := range ctx.GetOutputFiles().TaggedOutputFiles {
+ builtFiles = append(builtFiles, paths.Strings()...)
+ }
+ complianceMetadataInfo.SetListValue(android.ComplianceMetadataProp.BUILT_FILES, android.SortedUniqueStrings(builtFiles))
+
+ // Static deps
+ staticDepNames := make([]string, 0)
+ staticDepFiles := android.Paths{}
+ ctx.VisitDirectDepsWithTag(staticLibTag, func(module android.Module) {
+ if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
+ staticDepNames = append(staticDepNames, module.Name())
+ staticDepFiles = append(staticDepFiles, dep.ImplementationJars...)
+ staticDepFiles = append(staticDepFiles, dep.HeaderJars...)
+ staticDepFiles = append(staticDepFiles, dep.ResourceJars...)
+ }
+ })
+ complianceMetadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEPS, android.SortedUniqueStrings(staticDepNames))
+ complianceMetadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEP_FILES, android.SortedUniqueStrings(staticDepFiles.Strings()))
}
func (j *Library) getJarInstallDir(ctx android.ModuleContext) android.InstallPath {
@@ -1073,6 +1297,28 @@
}
}
+var apiXMLGeneratingApiSurfaces = []android.SdkKind{
+ android.SdkPublic,
+ android.SdkSystem,
+ android.SdkModule,
+ android.SdkSystemServer,
+ android.SdkTest,
+}
+
+func (j *Library) createApiXmlFile(ctx android.ModuleContext) {
+ if kind, ok := android.JavaLibraryNameToSdkKind(ctx.ModuleName()); ok && android.InList(kind, apiXMLGeneratingApiSurfaces) {
+ scopePrefix := AllApiScopes.matchingScopeFromSdkKind(kind).apiFilePrefix
+ j.apiXmlFile = android.PathForModuleOut(ctx, fmt.Sprintf("%sapi.xml", scopePrefix))
+ ctx.Build(pctx, android.BuildParams{
+ Rule: generateApiXMLRule,
+ // LOCAL_SOONG_CLASSES_JAR
+ Input: j.implementationAndResourcesJar,
+ Output: j.apiXmlFile,
+ })
+ ctx.DistForGoal("dist_files", j.apiXmlFile)
+ }
+}
+
const (
aidlIncludeDir = "aidl"
javaDir = "java"
@@ -1314,6 +1560,11 @@
// host test.
Device_first_prefer32_data []string `android:"path_device_first_prefer32"`
+ // Same as data, but will add dependencies on modules using the host's os variation and
+ // the common arch variation. Useful for a device test that wants to depend on a host
+ // module, for example to include a custom Tradefed test runner.
+ Host_common_data []string `android:"path_host_common"`
+
// Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
// doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
// explicitly.
@@ -1576,6 +1827,11 @@
MkInclude: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
MkAppClass: "JAVA_LIBRARIES",
})
+
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ if proptools.Bool(j.testProperties.Test_options.Unit_test) {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "host-unit-tests")
+ }
}
func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -1607,20 +1863,21 @@
j.data = append(j.data, android.PathsForModuleSrc(ctx, j.testProperties.Device_common_data)...)
j.data = append(j.data, android.PathsForModuleSrc(ctx, j.testProperties.Device_first_data)...)
j.data = append(j.data, android.PathsForModuleSrc(ctx, j.testProperties.Device_first_prefer32_data)...)
+ j.data = append(j.data, android.PathsForModuleSrc(ctx, j.testProperties.Host_common_data)...)
j.extraTestConfigs = android.PathsForModuleSrc(ctx, j.testProperties.Test_options.Extra_test_configs)
- ctx.VisitDirectDepsWithTag(dataNativeBinsTag, func(dep android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(dataNativeBinsTag, func(dep android.ModuleProxy) {
j.data = append(j.data, android.OutputFileForModule(ctx, dep, ""))
})
- ctx.VisitDirectDepsWithTag(dataDeviceBinsTag, func(dep android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(dataDeviceBinsTag, func(dep android.ModuleProxy) {
j.data = append(j.data, android.OutputFileForModule(ctx, dep, ""))
})
var directImplementationDeps android.Paths
var transitiveImplementationDeps []depset.DepSet[android.Path]
- ctx.VisitDirectDepsWithTag(jniLibTag, func(dep android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(jniLibTag, func(dep android.ModuleProxy) {
sharedLibInfo, _ := android.OtherModuleProvider(ctx, dep, cc.SharedLibraryInfoProvider)
if sharedLibInfo.SharedLibrary != nil {
// Copy to an intermediate output directory to append "lib[64]" to the path,
@@ -1653,10 +1910,82 @@
})
j.Library.GenerateAndroidBuildActions(ctx)
+
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ // LOCAL_MODULE_TAGS
+ moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests")
+ var allTestConfigs android.Paths
+ if j.testConfig != nil {
+ allTestConfigs = append(allTestConfigs, j.testConfig)
+ }
+ allTestConfigs = append(allTestConfigs, j.extraTestConfigs...)
+ if len(allTestConfigs) > 0 {
+ moduleInfoJSON.TestConfig = allTestConfigs.Strings()
+ } else {
+ optionalConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "AndroidTest.xml")
+ if optionalConfig.Valid() {
+ moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, optionalConfig.String())
+ }
+ }
+ if len(j.testProperties.Test_suites) > 0 {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, j.testProperties.Test_suites...)
+ } else {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
+ }
+ if _, ok := j.testConfig.(android.WritablePath); ok {
+ moduleInfoJSON.AutoTestConfig = []string{"true"}
+ }
+ if proptools.Bool(j.testProperties.Test_options.Unit_test) {
+ moduleInfoJSON.IsUnitTest = "true"
+ if ctx.Host() {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "host-unit-tests")
+ }
+ }
+ moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, j.testProperties.Test_mainline_modules...)
+
+ // Install test deps
+ if !ctx.Config().KatiEnabled() {
+ pathInTestCases := android.PathForModuleInstall(ctx, "testcases", ctx.ModuleName())
+ if j.testConfig != nil {
+ ctx.InstallFile(pathInTestCases, ctx.ModuleName()+".config", j.testConfig)
+ }
+ dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml")
+ if dynamicConfig.Valid() {
+ ctx.InstallFile(pathInTestCases, ctx.ModuleName()+".dynamic", dynamicConfig.Path())
+ }
+ testDeps := append(j.data, j.extraTestConfigs...)
+ for _, data := range android.SortedUniquePaths(testDeps) {
+ dataPath := android.DataPath{SrcPath: data}
+ ctx.InstallTestData(pathInTestCases, []android.DataPath{dataPath})
+ }
+ if j.outputFile != nil {
+ ctx.InstallFile(pathInTestCases, ctx.ModuleName()+".jar", j.outputFile)
+ }
+ }
+
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: j.testProperties.Test_suites,
+ })
}
func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.Library.GenerateAndroidBuildActions(ctx)
+
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests")
+ if len(j.testHelperLibraryProperties.Test_suites) > 0 {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, j.testHelperLibraryProperties.Test_suites...)
+ } else {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
+ }
+ optionalConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "AndroidTest.xml")
+ if optionalConfig.Valid() {
+ moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, optionalConfig.String())
+ }
+
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: j.testHelperLibraryProperties.Test_suites,
+ })
}
func (j *JavaTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -1746,7 +2075,7 @@
module.Module.properties.Installable = proptools.BoolPtr(true)
module.Module.dexpreopter.isTest = true
- module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
+ module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
module.Module.sourceProperties.Test_only = proptools.BoolPtr(true)
module.Module.sourceProperties.Top_level_test_target = true
@@ -1763,7 +2092,7 @@
module.Module.properties.Installable = proptools.BoolPtr(true)
module.Module.dexpreopter.isTest = true
- module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
+ module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
module.Module.sourceProperties.Test_only = proptools.BoolPtr(true)
InitJavaModule(module, android.HostAndDeviceSupported)
@@ -1910,13 +2239,13 @@
// Set the jniLibs of this binary.
// These will be added to `LOCAL_REQUIRED_MODULES`, and the kati packaging system will
// install these alongside the java binary.
- ctx.VisitDirectDepsWithTag(jniInstallTag, func(jni android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(jniInstallTag, func(jni android.ModuleProxy) {
// Use the BaseModuleName of the dependency (without any prebuilt_ prefix)
- bmn, _ := jni.(interface{ BaseModuleName() string })
- j.androidMkNamesOfJniLibs = append(j.androidMkNamesOfJniLibs, bmn.BaseModuleName()+":"+jni.Target().Arch.ArchType.Bitness())
+ commonInfo := android.OtherModulePointerProviderOrDefault(ctx, jni, android.CommonModuleInfoProvider)
+ j.androidMkNamesOfJniLibs = append(j.androidMkNamesOfJniLibs, commonInfo.BaseModuleName+":"+commonInfo.Target.Arch.ArchType.Bitness())
})
// Check that native libraries are not listed in `required`. Prompt users to use `jni_libs` instead.
- ctx.VisitDirectDepsWithTag(android.RequiredDepTag, func(dep android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(android.RequiredDepTag, func(dep android.ModuleProxy) {
if _, hasSharedLibraryInfo := android.OtherModuleProvider(ctx, dep, cc.SharedLibraryInfoProvider); hasSharedLibraryInfo {
ctx.ModuleErrorf("cc_library %s is no longer supported in `required` of java_binary modules. Please use jni_libs instead.", dep.Name())
}
@@ -2135,7 +2464,7 @@
func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
srcs android.Paths, homeDir android.WritablePath,
- classpath android.Paths, configFiles android.Paths) *android.RuleBuilderCommand {
+ classpath android.Paths, configFiles android.Paths, apiSurface *string) *android.RuleBuilderCommand {
rule.Command().Text("rm -rf").Flag(homeDir.String())
rule.Command().Text("mkdir -p").Flag(homeDir.String())
@@ -2176,6 +2505,8 @@
addMetalavaConfigFilesToCmd(cmd, configFiles)
+ addOptionalApiSurfaceToCmd(cmd, apiSurface)
+
if len(classpath) == 0 {
// The main purpose of the `--api-class-resolution api` option is to force metalava to ignore
// classes on the classpath when an API file contains missing classes. However, as this command
@@ -2215,6 +2546,7 @@
apiContributions := al.properties.Api_contributions
addValidations := !ctx.Config().IsEnvTrue("DISABLE_STUB_VALIDATION") &&
!ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") &&
+ !ctx.Config().PartialCompileFlags().Disable_stub_validation &&
proptools.BoolDefault(al.properties.Enable_validation, true)
for _, apiContributionName := range apiContributions {
ctx.AddDependency(ctx.Module(), javaApiContributionTag, apiContributionName)
@@ -2259,6 +2591,17 @@
var scopeOrderMap = AllApiScopes.MapToIndex(
func(s *apiScope) string { return s.name })
+// Add some extra entries into scopeOrderMap for some special api surface names needed by libcore,
+// external/conscrypt and external/icu and java/core-libraries.
+func init() {
+ count := len(scopeOrderMap)
+ scopeOrderMap["core"] = count + 1
+ scopeOrderMap["core-platform"] = count + 2
+ scopeOrderMap["intra-core"] = count + 3
+ scopeOrderMap["core-platform-plus-public"] = count + 4
+ scopeOrderMap["core-platform-legacy"] = count + 5
+}
+
func (al *ApiLibrary) sortApiFilesByApiScope(ctx android.ModuleContext, srcFilesInfo []JavaApiImportInfo) []JavaApiImportInfo {
for _, srcFileInfo := range srcFilesInfo {
if srcFileInfo.ApiSurface == "" {
@@ -2307,7 +2650,7 @@
var bootclassPaths android.Paths
var staticLibs android.Paths
var systemModulesPaths android.Paths
- ctx.VisitDirectDeps(func(dep android.Module) {
+ ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) {
tag := ctx.OtherModuleDependencyTag(dep)
switch tag {
case javaApiContributionTag:
@@ -2336,8 +2679,8 @@
systemModulesPaths = append(systemModulesPaths, sm.HeaderJars...)
}
case metalavaCurrentApiTimestampTag:
- if currentApiTimestampProvider, ok := dep.(currentApiTimestampProvider); ok {
- al.validationPaths = append(al.validationPaths, currentApiTimestampProvider.CurrentApiTimestamp())
+ if currentApiTimestampProvider, ok := android.OtherModuleProvider(ctx, dep, DroidStubsInfoProvider); ok {
+ al.validationPaths = append(al.validationPaths, currentApiTimestampProvider.CurrentApiTimestamp)
}
case aconfigDeclarationTag:
if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
@@ -2369,7 +2712,7 @@
combinedPaths := append(([]android.Path)(nil), systemModulesPaths...)
combinedPaths = append(combinedPaths, classPaths...)
combinedPaths = append(combinedPaths, bootclassPaths...)
- cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir, combinedPaths, configFiles)
+ cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir, combinedPaths, configFiles, al.properties.Api_surface)
al.stubsFlags(ctx, cmd, stubsDir)
@@ -2433,7 +2776,7 @@
ctx.Phony(ctx.ModuleName(), al.stubsJar)
- android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
+ javaInfo := &JavaInfo{
HeaderJars: android.PathsIfNonNil(al.stubsJar),
LocalHeaderJars: android.PathsIfNonNil(al.stubsJar),
TransitiveStaticLibsHeaderJars: depset.New(depset.PREORDER, android.PathsIfNonNil(al.stubsJar), nil),
@@ -2443,7 +2786,9 @@
AidlIncludeDirs: android.Paths{},
StubsLinkType: Stubs,
// No aconfig libraries on api libraries
- })
+ }
+ setExtraJavaInfo(ctx, al, javaInfo)
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
}
func (al *ApiLibrary) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
@@ -2711,7 +3056,7 @@
var staticJars android.Paths
var staticResourceJars android.Paths
var staticHeaderJars android.Paths
- ctx.VisitDirectDeps(func(module android.Module) {
+ ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
tag := ctx.OtherModuleDependencyTag(module)
if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
switch tag {
@@ -2763,12 +3108,7 @@
// file of the module to be named jarName.
var outputFile android.Path
combinedImplementationJar := android.PathForModuleOut(ctx, "combined", jarName)
- var implementationJars android.Paths
- if ctx.Config().UseTransitiveJarsInClasspath() {
- implementationJars = completeStaticLibsImplementationJars.ToList()
- } else {
- implementationJars = append(slices.Clone(localJars), staticJars...)
- }
+ implementationJars := completeStaticLibsImplementationJars.ToList()
TransformJarsToJar(ctx, combinedImplementationJar, "combine prebuilt implementation jars", implementationJars, android.OptionalPath{},
false, j.properties.Exclude_files, j.properties.Exclude_dirs)
outputFile = combinedImplementationJar
@@ -2791,12 +3131,7 @@
if reuseImplementationJarAsHeaderJar {
headerJar = outputFile
} else {
- var headerJars android.Paths
- if ctx.Config().UseTransitiveJarsInClasspath() {
- headerJars = completeStaticLibsHeaderJars.ToList()
- } else {
- headerJars = append(slices.Clone(localJars), staticHeaderJars...)
- }
+ headerJars := completeStaticLibsHeaderJars.ToList()
headerOutputFile := android.PathForModuleOut(ctx, "turbine-combined", jarName)
TransformJarsToJar(ctx, headerOutputFile, "combine prebuilt header jars", headerJars, android.OptionalPath{},
false, j.properties.Exclude_files, j.properties.Exclude_dirs)
@@ -2833,6 +3168,23 @@
outputFile = combinedJar
}
+ proguardFlags := android.PathForModuleOut(ctx, "proguard_flags")
+ TransformJarToR8Rules(ctx, proguardFlags, outputFile)
+
+ transitiveProguardFlags, transitiveUnconditionalExportedFlags := collectDepProguardSpecInfo(ctx)
+ android.SetProvider(ctx, ProguardSpecInfoProvider, ProguardSpecInfo{
+ ProguardFlagsFiles: depset.New[android.Path](
+ depset.POSTORDER,
+ android.Paths{proguardFlags},
+ transitiveProguardFlags,
+ ),
+ UnconditionallyExportedProguardFlags: depset.New[android.Path](
+ depset.POSTORDER,
+ nil,
+ transitiveUnconditionalExportedFlags,
+ ),
+ })
+
// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource.
// Also strip the relative path from the header output file so that the reuseImplementationJarAsHeaderJar check
// in a module that depends on this module considers them equal.
@@ -2843,11 +3195,7 @@
j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs)
- if ctx.Config().UseTransitiveJarsInClasspath() {
- ctx.CheckbuildFile(localJars...)
- } else {
- ctx.CheckbuildFile(outputFile)
- }
+ ctx.CheckbuildFile(localJars...)
if ctx.Device() {
// Shared libraries deapexed from prebuilt apexes are no longer supported.
@@ -2901,7 +3249,7 @@
}
}
- android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
+ javaInfo := &JavaInfo{
HeaderJars: android.PathsIfNonNil(j.combinedHeaderFile),
LocalHeaderJars: android.PathsIfNonNil(j.combinedHeaderFile),
TransitiveLibsHeaderJarsForR8: j.transitiveLibsHeaderJarsForR8,
@@ -2915,10 +3263,18 @@
AidlIncludeDirs: j.exportAidlIncludeDirs,
StubsLinkType: j.stubsLinkType,
// TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
+ }
+ setExtraJavaInfo(ctx, j, javaInfo)
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+
+ android.SetProvider(ctx, JavaLibraryInfoProvider, JavaLibraryInfo{
+ Prebuilt: true,
})
ctx.SetOutputFiles(android.Paths{j.combinedImplementationFile}, "")
ctx.SetOutputFiles(android.Paths{j.combinedImplementationFile}, ".jar")
+
+ buildComplianceMetadata(ctx)
}
func (j *Import) maybeInstall(ctx android.ModuleContext, jarName string, outputFile android.Path) {
@@ -2965,26 +3321,29 @@
var _ android.ApexModule = (*Import)(nil)
// Implements android.ApexModule
-func (j *Import) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
- return j.depIsInSameApex(ctx, dep)
+func (m *Import) GetDepInSameApexChecker() android.DepInSameApexChecker {
+ return JavaImportDepInSameApexChecker{}
+}
+
+type JavaImportDepInSameApexChecker struct {
+ android.BaseDepInSameApexChecker
+}
+
+func (m JavaImportDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
+ return depIsInSameApex(tag)
}
// Implements android.ApexModule
-func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
- sdkVersion android.ApiLevel) error {
+func (j *Import) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
sdkVersionSpec := j.SdkVersion(ctx)
minSdkVersion := j.MinSdkVersion(ctx)
- if !minSdkVersion.Specified() {
- return fmt.Errorf("min_sdk_version is not specified")
- }
+
// If the module is compiling against core (via sdk_version), skip comparison check.
if sdkVersionSpec.Kind == android.SdkCore {
- return nil
+ return android.MinApiLevel
}
- if minSdkVersion.GreaterThan(sdkVersion) {
- return fmt.Errorf("newer SDK(%v)", minSdkVersion)
- }
- return nil
+
+ return minSdkVersion
}
// requiredFilesFromPrebuiltApexForImport returns information about the files that a java_import or
@@ -3021,19 +3380,10 @@
// Add compile time check for interface implementation
var _ android.IDEInfo = (*Import)(nil)
-var _ android.IDECustomizedModuleName = (*Import)(nil)
// Collect information for opening IDE project files in java/jdeps.go.
-
func (j *Import) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
- dpInfo.Jars = append(dpInfo.Jars, j.combinedHeaderFile.String())
-}
-
-func (j *Import) IDECustomizedModuleName() string {
- // TODO(b/113562217): Extract the base module name from the Import name, often the Import name
- // has a prefix "prebuilt_". Remove the prefix explicitly if needed until we find a better
- // solution to get the Import name.
- return android.RemoveOptionalPrebuiltPrefix(j.Name())
+ dpInfo.Jars = append(dpInfo.Jars, j.combinedImplementationFile.String())
}
var _ android.PrebuiltInterface = (*Import)(nil)
@@ -3191,6 +3541,12 @@
ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
j.Stem()+".jar", dexOutputFile)
}
+
+ javaInfo := &JavaInfo{}
+ setExtraJavaInfo(ctx, j, javaInfo)
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+
+ android.SetProvider(ctx, JavaDexImportInfoProvider, JavaDexImportInfo{})
}
func (j *DexImport) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
@@ -3200,10 +3556,8 @@
var _ android.ApexModule = (*DexImport)(nil)
// Implements android.ApexModule
-func (j *DexImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
- sdkVersion android.ApiLevel) error {
- // we don't check prebuilt modules for sdk_version
- return nil
+func (m *DexImport) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
+ return android.MinApiLevel
}
// dex_import imports a `.jar` file containing classes.dex files.
@@ -3225,7 +3579,6 @@
type Defaults struct {
android.ModuleBase
android.DefaultsModuleBase
- android.ApexModuleBase
}
// java_defaults provides a set of properties that can be inherited by other java or android modules.
@@ -3289,6 +3642,8 @@
&bootclasspathFragmentProperties{},
&SourceOnlyBootclasspathProperties{},
&ravenwoodTestProperties{},
+ &AndroidAppImportProperties{},
+ &UsesLibraryProperties{},
)
android.InitDefaultsModule(module)
@@ -3305,10 +3660,10 @@
func (ks *kytheExtractJavaSingleton) GenerateBuildActions(ctx android.SingletonContext) {
var xrefTargets android.Paths
var xrefKotlinTargets android.Paths
- ctx.VisitAllModules(func(module android.Module) {
- if javaModule, ok := module.(xref); ok {
- xrefTargets = append(xrefTargets, javaModule.XrefJavaFiles()...)
- xrefKotlinTargets = append(xrefKotlinTargets, javaModule.XrefKotlinFiles()...)
+ ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
+ if javaInfo, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
+ xrefTargets = append(xrefTargets, javaInfo.XrefJavaFiles...)
+ xrefKotlinTargets = append(xrefKotlinTargets, javaInfo.XrefKotlinFiles...)
}
})
// TODO(asmundak): perhaps emit a rule to output a warning if there were no xrefTargets
@@ -3326,11 +3681,11 @@
var inList = android.InList[string]
// Add class loader context (CLC) of a given dependency to the current CLC.
-func addCLCFromDep(ctx android.ModuleContext, depModule android.Module,
+func addCLCFromDep(ctx android.ModuleContext, depModule android.ModuleProxy,
clcMap dexpreopt.ClassLoaderContextMap) {
- dep, ok := depModule.(UsesLibraryDependency)
- if !ok {
+ dep, ok := android.OtherModuleProvider(ctx, depModule, JavaInfoProvider)
+ if !ok || dep.UsesLibraryDependencyInfo == nil {
return
}
@@ -3340,14 +3695,14 @@
if lib, ok := android.OtherModuleProvider(ctx, depModule, SdkLibraryInfoProvider); ok && lib.SharedLibrary {
// A shared SDK library. This should be added as a top-level CLC element.
sdkLib = &depName
- } else if lib, ok := depModule.(SdkLibraryComponentDependency); ok && lib.OptionalSdkLibraryImplementation() != nil {
- if depModule.Name() == proptools.String(lib.OptionalSdkLibraryImplementation())+".impl" {
- sdkLib = lib.OptionalSdkLibraryImplementation()
+ } else if lib := dep.SdkLibraryComponentDependencyInfo; lib != nil && lib.OptionalSdkLibraryImplementation != nil {
+ if depModule.Name() == proptools.String(lib.OptionalSdkLibraryImplementation)+".impl" {
+ sdkLib = lib.OptionalSdkLibraryImplementation
}
- } else if ulib, ok := depModule.(ProvidesUsesLib); ok {
+ } else if ulib := dep.ProvidesUsesLibInfo; ulib != nil {
// A non-SDK library disguised as an SDK library by the means of `provides_uses_lib`
// property. This should be handled in the same way as a shared SDK library.
- sdkLib = ulib.ProvidesUsesLib()
+ sdkLib = ulib.ProvidesUsesLib
}
depTag := ctx.OtherModuleDependencyTag(depModule)
@@ -3379,21 +3734,22 @@
}
}
clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, optional,
- dep.DexJarBuildPath(ctx).PathOrNil(), dep.DexJarInstallPath(), dep.ClassLoaderContexts())
+ dep.DexJarBuildPath.PathOrNil(),
+ dep.UsesLibraryDependencyInfo.DexJarInstallPath, dep.UsesLibraryDependencyInfo.ClassLoaderContexts)
} else {
- clcMap.AddContextMap(dep.ClassLoaderContexts(), depName)
+ clcMap.AddContextMap(dep.UsesLibraryDependencyInfo.ClassLoaderContexts, depName)
}
}
-func addMissingOptionalUsesLibsFromDep(ctx android.ModuleContext, depModule android.Module,
+func addMissingOptionalUsesLibsFromDep(ctx android.ModuleContext, depModule android.ModuleProxy,
usesLibrary *usesLibrary) {
- dep, ok := depModule.(ModuleWithUsesLibrary)
+ dep, ok := android.OtherModuleProvider(ctx, depModule, JavaInfoProvider)
if !ok {
return
}
- for _, lib := range dep.UsesLibrary().usesLibraryProperties.Missing_optional_uses_libs {
+ for _, lib := range dep.MissingOptionalUsesLibs {
if !android.InList(lib, usesLibrary.usesLibraryProperties.Missing_optional_uses_libs) {
usesLibrary.usesLibraryProperties.Missing_optional_uses_libs =
append(usesLibrary.usesLibraryProperties.Missing_optional_uses_libs, lib)
@@ -3449,3 +3805,68 @@
func (ap *JavaApiContributionImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
ap.JavaApiContribution.GenerateAndroidBuildActions(ctx)
}
+
+func setExtraJavaInfo(ctx android.ModuleContext, module android.Module, javaInfo *JavaInfo) {
+ if alDep, ok := module.(AndroidLibraryDependency); ok {
+ javaInfo.AndroidLibraryDependencyInfo = &AndroidLibraryDependencyInfo{
+ ExportPackage: alDep.ExportPackage(),
+ ResourcesNodeDepSet: alDep.ResourcesNodeDepSet(),
+ RRODirsDepSet: alDep.RRODirsDepSet(),
+ ManifestsDepSet: alDep.ManifestsDepSet(),
+ }
+ }
+
+ if ulDep, ok := module.(UsesLibraryDependency); ok {
+ javaInfo.UsesLibraryDependencyInfo = &UsesLibraryDependencyInfo{
+ DexJarInstallPath: ulDep.DexJarInstallPath(),
+ ClassLoaderContexts: ulDep.ClassLoaderContexts(),
+ }
+ }
+
+ if slcDep, ok := module.(SdkLibraryComponentDependency); ok {
+ javaInfo.SdkLibraryComponentDependencyInfo = &SdkLibraryComponentDependencyInfo{
+ OptionalSdkLibraryImplementation: slcDep.OptionalSdkLibraryImplementation(),
+ }
+ }
+
+ if pul, ok := module.(ProvidesUsesLib); ok {
+ javaInfo.ProvidesUsesLibInfo = &ProvidesUsesLibInfo{
+ ProvidesUsesLib: pul.ProvidesUsesLib(),
+ }
+ }
+
+ if mwul, ok := module.(ModuleWithUsesLibrary); ok {
+ javaInfo.MissingOptionalUsesLibs = mwul.UsesLibrary().usesLibraryProperties.Missing_optional_uses_libs
+ }
+
+ if mwsd, ok := module.(moduleWithSdkDep); ok {
+ linkType, stubs := mwsd.getSdkLinkType(ctx, ctx.ModuleName())
+ javaInfo.ModuleWithSdkDepInfo = &ModuleWithSdkDepInfo{
+ SdkLinkType: linkType,
+ Stubs: stubs,
+ }
+ }
+
+ if st, ok := module.(ModuleWithStem); ok {
+ javaInfo.Stem = st.Stem()
+ }
+
+ if mm, ok := module.(interface {
+ DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath
+ }); ok {
+ javaInfo.DexJarBuildPath = mm.DexJarBuildPath(ctx)
+ }
+
+ if di, ok := module.(DexpreopterInterface); ok {
+ javaInfo.DexpreopterInfo = &DexpreopterInfo{
+ OutputProfilePathOnHost: di.OutputProfilePathOnHost(),
+ ApexSystemServerDexpreoptInstalls: di.ApexSystemServerDexpreoptInstalls(),
+ ApexSystemServerDexJars: di.ApexSystemServerDexJars(),
+ }
+ }
+
+ if xr, ok := module.(xref); ok {
+ javaInfo.XrefJavaFiles = xr.XrefJavaFiles()
+ javaInfo.XrefKotlinFiles = xr.XrefKotlinFiles()
+ }
+}
diff --git a/java/java_test.go b/java/java_test.go
index d415679..1ba78d4 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -110,13 +110,14 @@
case strings.HasSuffix(name, ".jar"):
return name
default:
- return filepath.Join("out", "soong", ".intermediates", defaultJavaDir, name, "android_common", "turbine-combined", name+".jar")
+ return filepath.Join("out", "soong", ".intermediates", defaultJavaDir, name, "android_common", "turbine", name+".jar")
}
}
// Test that the PrepareForTestWithJavaDefaultModules provides all the files that it uses by
// running it in a fixture that requires all source files to exist.
func TestPrepareForTestWithJavaDefaultModules(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.PrepareForTestDisallowNonExistentPaths,
@@ -124,6 +125,7 @@
}
func TestJavaLinkType(t *testing.T) {
+ t.Parallel()
testJava(t, `
java_library {
name: "foo",
@@ -212,6 +214,7 @@
}
func TestSimple(t *testing.T) {
+ t.Parallel()
bp := `
java_library {
name: "foo",
@@ -237,11 +240,6 @@
srcs: ["d.java"],
}`
- frameworkTurbineCombinedJars := []string{
- "out/soong/.intermediates/default/java/ext/android_common/turbine-combined/ext.jar",
- "out/soong/.intermediates/default/java/framework/android_common/turbine-combined/framework.jar",
- }
-
frameworkTurbineJars := []string{
"out/soong/.intermediates/default/java/ext/android_common/turbine/ext.jar",
"out/soong/.intermediates/default/java/framework/android_common/turbine/framework.jar",
@@ -267,43 +265,6 @@
preparer: android.NullFixturePreparer,
fooJavacInputs: []string{"a.java"},
fooJavacClasspath: slices.Concat(
- frameworkTurbineCombinedJars,
- []string{
- "out/soong/.intermediates/bar/android_common/turbine-combined/bar.jar",
- "out/soong/.intermediates/baz/android_common/turbine-combined/baz.jar",
- },
- ),
- fooCombinedInputs: []string{
- "out/soong/.intermediates/foo/android_common/javac/foo.jar",
- "out/soong/.intermediates/baz/android_common/combined/baz.jar",
- },
-
- fooHeaderCombinedInputs: []string{
- "out/soong/.intermediates/foo/android_common/turbine/foo.jar",
- "out/soong/.intermediates/baz/android_common/turbine-combined/baz.jar",
- },
-
- barJavacInputs: []string{"b.java"},
- barJavacClasspath: slices.Concat(
- frameworkTurbineCombinedJars,
- []string{
- "out/soong/.intermediates/quz/android_common/turbine-combined/quz.jar",
- },
- ),
- barCombinedInputs: []string{
- "out/soong/.intermediates/bar/android_common/javac/bar.jar",
- "out/soong/.intermediates/quz/android_common/javac/quz.jar",
- },
- barHeaderCombinedInputs: []string{
- "out/soong/.intermediates/bar/android_common/turbine/bar.jar",
- "out/soong/.intermediates/quz/android_common/turbine-combined/quz.jar",
- },
- },
- {
- name: "transitive classpath",
- preparer: PrepareForTestWithTransitiveClasspathEnabled,
- fooJavacInputs: []string{"a.java"},
- fooJavacClasspath: slices.Concat(
frameworkTurbineJars,
[]string{
"out/soong/.intermediates/bar/android_common/turbine/bar.jar",
@@ -341,11 +302,12 @@
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
tt.preparer,
).RunTestWithBp(t, bp)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
fooJavac := foo.Rule("javac")
android.AssertPathsRelativeToTopEquals(t, "foo javac inputs", tt.fooJavacInputs, fooJavac.Inputs)
@@ -360,7 +322,7 @@
fooCombinedHeaderJar := foo.Output("turbine-combined/foo.jar")
android.AssertPathsRelativeToTopEquals(t, "foo header combined inputs", tt.fooHeaderCombinedInputs, fooCombinedHeaderJar.Inputs)
- bar := result.ModuleForTests("bar", "android_common")
+ bar := result.ModuleForTests(t, "bar", "android_common")
barJavac := bar.Rule("javac")
android.AssertPathsRelativeToTopEquals(t, "bar javac inputs", tt.barJavacInputs, barJavac.Inputs)
@@ -378,6 +340,7 @@
}
func TestExportedPlugins(t *testing.T) {
+ t.Parallel()
type Result struct {
library string
processors string
@@ -456,6 +419,7 @@
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_plugin {
name: "plugin",
@@ -469,11 +433,11 @@
`+test.extra)
for _, want := range test.results {
- javac := ctx.ModuleForTests(want.library, "android_common").Rule("javac")
+ javac := ctx.ModuleForTests(t, want.library, "android_common").Rule("javac")
if javac.Args["processor"] != want.processors {
t.Errorf("For library %v, expected %v, found %v", want.library, want.processors, javac.Args["processor"])
}
- turbine := ctx.ModuleForTests(want.library, "android_common").MaybeRule("turbine")
+ turbine := ctx.ModuleForTests(t, want.library, "android_common").MaybeRule("turbine")
disableTurbine := turbine.BuildParams.Rule == nil
if disableTurbine != want.disableTurbine {
t.Errorf("For library %v, expected disableTurbine %v, found %v", want.library, want.disableTurbine, disableTurbine)
@@ -484,6 +448,7 @@
}
func TestSdkVersionByPartition(t *testing.T) {
+ t.Parallel()
testJavaError(t, "sdk_version must have a value when the module is located at vendor or product", `
java_library {
name: "foo",
@@ -525,6 +490,7 @@
}
func TestArchSpecific(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -537,13 +503,14 @@
}
`)
- javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
+ javac := ctx.ModuleForTests(t, "foo", "android_common").Rule("javac")
if len(javac.Inputs) != 2 || javac.Inputs[0].String() != "a.java" || javac.Inputs[1].String() != "b.java" {
t.Errorf(`foo inputs %v != ["a.java", "b.java"]`, javac.Inputs)
}
}
func TestBinary(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library_host {
name: "foo",
@@ -567,11 +534,11 @@
buildOS := ctx.Config().BuildOS.String()
- bar := ctx.ModuleForTests("bar", buildOS+"_common")
+ bar := ctx.ModuleForTests(t, "bar", buildOS+"_common")
barJar := bar.Output("bar.jar").Output.String()
barWrapperDeps := bar.Output("bar").Implicits.Strings()
- libjni := ctx.ModuleForTests("libjni", buildOS+"_x86_64_shared")
+ libjni := ctx.ModuleForTests(t, "libjni", buildOS+"_x86_64_shared")
libjniSO := libjni.Rule("Cp").Output.String()
// Test that the install binary wrapper depends on the installed jar file
@@ -586,6 +553,7 @@
}
func TestTest(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_test_host {
name: "foo",
@@ -603,7 +571,7 @@
buildOS := ctx.Config().BuildOS.String()
- foo := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost)
+ foo := ctx.ModuleForTests(t, "foo", buildOS+"_common").Module().(*TestHost)
expected := "lib64/libjni.so"
if runtime.GOOS == "darwin" {
@@ -617,7 +585,31 @@
}
}
+func TestHostCommonData(t *testing.T) {
+ t.Parallel()
+ ctx, _ := testJava(t, `
+ java_library_host {
+ name: "host",
+ srcs: ["a.java"],
+ }
+
+ java_test {
+ name: "foo",
+ srcs: ["a.java"],
+ host_common_data: [":host"],
+ }
+ `)
+
+ foo := ctx.ModuleForTests(t, "foo", "android_common").Module().(*Test)
+ host := ctx.ModuleForTests(t, "host", ctx.Config().BuildOSCommonTarget.String()).Module().(*Library)
+
+ if g, w := foo.data.RelativeToTop().Strings(), []string{host.outputFile.RelativeToTop().String()}; !slices.Equal(g, w) {
+ t.Errorf("expected test data %q, got %q\n", w, g)
+ }
+}
+
func TestHostBinaryNoJavaDebugInfoOverride(t *testing.T) {
+ t.Parallel()
bp := `
java_library {
name: "target_library",
@@ -638,7 +630,7 @@
).RunTestWithBp(t, bp)
// first, check that the -g flag is added to target modules
- targetLibrary := result.ModuleForTests("target_library", "android_common")
+ targetLibrary := result.ModuleForTests(t, "target_library", "android_common")
targetJavaFlags := targetLibrary.Module().VariablesForTests()["javacFlags"]
if !strings.Contains(targetJavaFlags, "-g:source,lines") {
t.Errorf("target library javac flags %v should contain "+
@@ -647,7 +639,7 @@
// check that -g is not overridden for host modules
buildOS := result.Config.BuildOS.String()
- hostBinary := result.ModuleForTests("host_binary", buildOS+"_common")
+ hostBinary := result.ModuleForTests(t, "host_binary", buildOS+"_common")
hostJavaFlags := hostBinary.Module().VariablesForTests()["javacFlags"]
if strings.Contains(hostJavaFlags, "-g:source,lines") {
t.Errorf("java_binary_host javac flags %v should not have "+
@@ -665,6 +657,7 @@
var _ android.ModuleErrorfContext = (*moduleErrorfTestCtx)(nil)
func TestPrebuilts(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -710,15 +703,15 @@
}
`)
- fooModule := ctx.ModuleForTests("foo", "android_common")
+ fooModule := ctx.ModuleForTests(t, "foo", "android_common")
javac := fooModule.Rule("javac")
- combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac")
- barModule := ctx.ModuleForTests("bar", "android_common")
- barJar := barModule.Output("combined/bar.jar").Output
- bazModule := ctx.ModuleForTests("baz", "android_common")
- bazJar := bazModule.Output("combined/baz.jar").Output
- sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs", "android_common").
- Output("combined/sdklib.stubs.jar").Output
+ combineJar := ctx.ModuleForTests(t, "foo", "android_common").Description("for javac")
+ barModule := ctx.ModuleForTests(t, "bar", "android_common")
+ barJar := barModule.Output("local-combined/bar.jar").Output
+ bazModule := ctx.ModuleForTests(t, "baz", "android_common")
+ bazJar := bazModule.Output("local-combined/baz.jar").Output
+ sdklibStubsJar := ctx.ModuleForTests(t, "sdklib.stubs", "android_common").
+ Output("local-combined/sdklib.stubs.jar").Output
fooLibrary := fooModule.Module().(*Library)
assertDeepEquals(t, "foo unique sources incorrect",
@@ -750,7 +743,7 @@
expectedDexJar := "out/soong/.intermediates/baz/android_common/dex/baz.jar"
android.AssertPathRelativeToTopEquals(t, "baz dex jar build path", expectedDexJar, bazDexJar)
- ctx.ModuleForTests("qux", "android_common").Rule("Cp")
+ ctx.ModuleForTests(t, "qux", "android_common").Rule("Cp")
entries := android.AndroidMkEntriesForTest(t, ctx, fooModule.Module())[0]
android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_library", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
@@ -765,6 +758,7 @@
}
func TestPrebuiltStubsSources(t *testing.T) {
+ t.Parallel()
test := func(t *testing.T, sourcesPath string, expectedInputs []string) {
ctx, _ := testJavaWithFS(t, fmt.Sprintf(`
prebuilt_stubs_sources {
@@ -775,17 +769,19 @@
"stubs/sources/pkg/B.java": nil,
})
- zipSrc := ctx.ModuleForTests("stubs-source", "android_common").Rule("zip_src")
+ zipSrc := ctx.ModuleForTests(t, "stubs-source", "android_common").Rule("zip_src")
if expected, actual := expectedInputs, zipSrc.Inputs.Strings(); !reflect.DeepEqual(expected, actual) {
t.Errorf("mismatch of inputs to soong_zip: expected %q, actual %q", expected, actual)
}
}
t.Run("empty/missing directory", func(t *testing.T) {
+ t.Parallel()
test(t, "empty-directory", nil)
})
t.Run("non-empty set of sources", func(t *testing.T) {
+ t.Parallel()
test(t, "stubs/sources", []string{
"stubs/sources/pkg/A.java",
"stubs/sources/pkg/B.java",
@@ -794,6 +790,7 @@
}
func TestDefaults(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_defaults {
name: "defaults",
@@ -835,40 +832,41 @@
}
`)
- javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
- combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac")
+ javac := ctx.ModuleForTests(t, "foo", "android_common").Rule("javac")
+ combineJar := ctx.ModuleForTests(t, "foo", "android_common").Description("for javac")
if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
}
- barTurbine := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine-combined", "bar.jar")
+ barTurbine := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine", "bar.jar")
if !strings.Contains(javac.Args["classpath"], barTurbine) {
t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barTurbine)
}
- baz := ctx.ModuleForTests("baz", "android_common").Rule("javac").Output.String()
+ baz := ctx.ModuleForTests(t, "baz", "android_common").Rule("javac").Output.String()
if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != baz {
t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, baz)
}
- atestOptimize := ctx.ModuleForTests("atestOptimize", "android_common").MaybeRule("r8")
+ atestOptimize := ctx.ModuleForTests(t, "atestOptimize", "android_common").MaybeRule("r8")
if atestOptimize.Output == nil {
t.Errorf("atestOptimize should optimize APK")
}
- atestNoOptimize := ctx.ModuleForTests("atestNoOptimize", "android_common").MaybeRule("d8")
+ atestNoOptimize := ctx.ModuleForTests(t, "atestNoOptimize", "android_common").MaybeRule("d8")
if atestNoOptimize.Output == nil {
t.Errorf("atestNoOptimize should not optimize APK")
}
- atestDefault := ctx.ModuleForTests("atestDefault", "android_common").MaybeRule("d8")
+ atestDefault := ctx.ModuleForTests(t, "atestDefault", "android_common").MaybeRule("d8")
if atestDefault.Output == nil {
t.Errorf("atestDefault should not optimize APK")
}
}
func TestResources(t *testing.T) {
+ t.Parallel()
var table = []struct {
name string
prop string
@@ -940,6 +938,7 @@
for _, test := range table {
t.Run(test.name, func(t *testing.T) {
+ t.Parallel()
ctx, _ := testJavaWithFS(t, `
java_library {
name: "foo",
@@ -958,8 +957,8 @@
},
)
- foo := ctx.ModuleForTests("foo", "android_common").Output("withres/foo.jar")
- fooRes := ctx.ModuleForTests("foo", "android_common").Output("res/foo.jar")
+ foo := ctx.ModuleForTests(t, "foo", "android_common").Output("withres/foo.jar")
+ fooRes := ctx.ModuleForTests(t, "foo", "android_common").Output("res/foo.jar")
if !inList(fooRes.Output.String(), foo.Inputs.Strings()) {
t.Errorf("foo combined jars %v does not contain %q",
@@ -975,6 +974,7 @@
}
func TestIncludeSrcs(t *testing.T) {
+ t.Parallel()
ctx, _ := testJavaWithFS(t, `
java_library {
name: "foo",
@@ -1003,8 +1003,8 @@
})
// Test a library with include_srcs: true
- foo := ctx.ModuleForTests("foo", "android_common").Output("withres/foo.jar")
- fooSrcJar := ctx.ModuleForTests("foo", "android_common").Output("foo.srcjar")
+ foo := ctx.ModuleForTests(t, "foo", "android_common").Output("withres/foo.jar")
+ fooSrcJar := ctx.ModuleForTests(t, "foo", "android_common").Output("foo.srcjar")
if g, w := fooSrcJar.Output.String(), foo.Inputs.Strings(); !inList(g, w) {
t.Errorf("foo combined jars %v does not contain %q", w, g)
@@ -1015,10 +1015,10 @@
}
// Test a library with include_srcs: true and resources
- bar := ctx.ModuleForTests("bar", "android_common").Output("withres/bar.jar")
- barResCombined := ctx.ModuleForTests("bar", "android_common").Output("res-combined/bar.jar")
- barRes := ctx.ModuleForTests("bar", "android_common").Output("res/bar.jar")
- barSrcJar := ctx.ModuleForTests("bar", "android_common").Output("bar.srcjar")
+ bar := ctx.ModuleForTests(t, "bar", "android_common").Output("withres/bar.jar")
+ barResCombined := ctx.ModuleForTests(t, "bar", "android_common").Output("res-combined/bar.jar")
+ barRes := ctx.ModuleForTests(t, "bar", "android_common").Output("res/bar.jar")
+ barSrcJar := ctx.ModuleForTests(t, "bar", "android_common").Output("bar.srcjar")
if g, w := barSrcJar.Output.String(), barResCombined.Inputs.Strings(); !inList(g, w) {
t.Errorf("bar combined resource jars %v does not contain %q", w, g)
@@ -1028,7 +1028,7 @@
t.Errorf("bar combined resource jars %v does not contain %q", w, g)
}
- if g, w := barResCombined.Output.String(), bar.Inputs.Strings(); !inList(g, w) {
+ if g, w := barRes.Output.String(), bar.Inputs.Strings(); !inList(g, w) {
t.Errorf("bar combined jars %v does not contain %q", w, g)
}
@@ -1042,6 +1042,7 @@
}
func TestGeneratedSources(t *testing.T) {
+ t.Parallel()
ctx, _ := testJavaWithFS(t, `
java_library {
name: "foo",
@@ -1062,8 +1063,8 @@
"b.java": nil,
})
- javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
- genrule := ctx.ModuleForTests("gen", "").Rule("generator")
+ javac := ctx.ModuleForTests(t, "foo", "android_common").Rule("javac")
+ genrule := ctx.ModuleForTests(t, "gen", "").Rule("generator")
if filepath.Base(genrule.Output.String()) != "gen.java" {
t.Fatalf(`gen output file %v is not ".../gen.java"`, genrule.Output.String())
@@ -1078,6 +1079,7 @@
}
func TestTurbine(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest, FixtureWithPrebuiltApis(map[string][]string{"14": {"foo"}})).
RunTestWithBp(t, `
@@ -1102,15 +1104,15 @@
}
`)
- fooTurbine := result.ModuleForTests("foo", "android_common").Rule("turbine")
- barTurbine := result.ModuleForTests("bar", "android_common").Rule("turbine")
- barJavac := result.ModuleForTests("bar", "android_common").Rule("javac")
- barTurbineCombined := result.ModuleForTests("bar", "android_common").Description("for turbine")
- bazJavac := result.ModuleForTests("baz", "android_common").Rule("javac")
+ fooTurbine := result.ModuleForTests(t, "foo", "android_common").Rule("turbine")
+ barTurbine := result.ModuleForTests(t, "bar", "android_common").Rule("turbine")
+ barJavac := result.ModuleForTests(t, "bar", "android_common").Rule("javac")
+ barTurbineCombined := result.ModuleForTests(t, "bar", "android_common").Description("for turbine")
+ bazJavac := result.ModuleForTests(t, "baz", "android_common").Rule("javac")
android.AssertPathsRelativeToTopEquals(t, "foo inputs", []string{"a.java"}, fooTurbine.Inputs)
- fooHeaderJar := filepath.Join("out", "soong", ".intermediates", "foo", "android_common", "turbine-combined", "foo.jar")
+ fooHeaderJar := filepath.Join("out", "soong", ".intermediates", "foo", "android_common", "turbine", "foo.jar")
barTurbineJar := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine", "bar.jar")
android.AssertStringDoesContain(t, "bar turbine classpath", barTurbine.Args["turbineFlags"], fooHeaderJar)
android.AssertStringDoesContain(t, "bar javac classpath", barJavac.Args["classpath"], fooHeaderJar)
@@ -1119,6 +1121,7 @@
}
func TestSharding(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "bar",
@@ -1129,7 +1132,7 @@
barHeaderJar := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine", "bar.jar")
for i := 0; i < 3; i++ {
- barJavac := ctx.ModuleForTests("bar", "android_common").Description("javac" + strconv.Itoa(i))
+ barJavac := ctx.ModuleForTests(t, "bar", "android_common").Description("javac" + strconv.Itoa(i))
if !strings.HasPrefix(barJavac.Args["classpath"], "-classpath "+barHeaderJar+":") {
t.Errorf("bar javac classpath %v does start with %q", barJavac.Args["classpath"], barHeaderJar)
}
@@ -1137,6 +1140,7 @@
}
func TestExcludeFileGroupInSrcs(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -1155,7 +1159,7 @@
}
`)
- javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
+ javac := ctx.ModuleForTests(t, "foo", "android_common").Rule("javac")
if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "java-fg/c.java" {
t.Errorf(`foo inputs %v != ["java-fg/c.java"]`, javac.Inputs)
@@ -1163,6 +1167,7 @@
}
func TestJavaLibraryOutputFiles(t *testing.T) {
+ t.Parallel()
testJavaWithFS(t, "", map[string][]byte{
"libcore/Android.bp": []byte(`
java_library {
@@ -1180,6 +1185,7 @@
}
func TestJavaImportOutputFiles(t *testing.T) {
+ t.Parallel()
testJavaWithFS(t, "", map[string][]byte{
"libcore/Android.bp": []byte(`
java_import {
@@ -1196,6 +1202,7 @@
}
func TestJavaImport(t *testing.T) {
+ t.Parallel()
bp := `
java_library {
name: "source_library",
@@ -1223,18 +1230,20 @@
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, bp)
- source := ctx.ModuleForTests("source_library", "android_common")
+ source := ctx.ModuleForTests(t, "source_library", "android_common")
sourceJar := source.Output("javac/source_library.jar")
- sourceHeaderJar := source.Output("turbine-combined/source_library.jar")
+ sourceHeaderJar := source.Output("turbine/source_library.jar")
+ sourceCombinedHeaderJar := source.Output("turbine-combined/source_library.jar")
sourceJavaInfo, _ := android.OtherModuleProvider(ctx, source.Module(), JavaInfoProvider)
// The source library produces separate implementation and header jars
android.AssertPathsRelativeToTopEquals(t, "source library implementation jar",
[]string{sourceJar.Output.String()}, sourceJavaInfo.ImplementationAndResourcesJars)
android.AssertPathsRelativeToTopEquals(t, "source library header jar",
- []string{sourceHeaderJar.Output.String()}, sourceJavaInfo.HeaderJars)
+ []string{sourceCombinedHeaderJar.Output.String()}, sourceJavaInfo.HeaderJars)
- importWithNoDeps := ctx.ModuleForTests("import_with_no_deps", "android_common")
+ importWithNoDeps := ctx.ModuleForTests(t, "import_with_no_deps", "android_common")
+ importWithNoDepsLocalJar := importWithNoDeps.Output("local-combined/import_with_no_deps.jar")
importWithNoDepsJar := importWithNoDeps.Output("combined/import_with_no_deps.jar")
importWithNoDepsJavaInfo, _ := android.OtherModuleProvider(ctx, importWithNoDeps.Module(), JavaInfoProvider)
@@ -1244,10 +1253,14 @@
android.AssertPathsRelativeToTopEquals(t, "import with no deps header jar",
[]string{importWithNoDepsJar.Output.String()}, importWithNoDepsJavaInfo.HeaderJars)
android.AssertPathsRelativeToTopEquals(t, "import with no deps combined inputs",
- []string{"no_deps.jar"}, importWithNoDepsJar.Inputs)
+ []string{importWithNoDepsLocalJar.Output.String()}, importWithNoDepsJar.Inputs)
+ android.AssertPathsRelativeToTopEquals(t, "import with no deps local combined inputs",
+ []string{"no_deps.jar"}, importWithNoDepsLocalJar.Inputs)
- importWithSourceDeps := ctx.ModuleForTests("import_with_source_deps", "android_common")
+ importWithSourceDeps := ctx.ModuleForTests(t, "import_with_source_deps", "android_common")
+ importWithSourceDepsLocalJar := importWithSourceDeps.Output("local-combined/import_with_source_deps.jar")
importWithSourceDepsJar := importWithSourceDeps.Output("combined/import_with_source_deps.jar")
+ importWithSourceDepsLocalHeaderJar := importWithSourceDeps.Output("local-combined/import_with_source_deps.jar")
importWithSourceDepsHeaderJar := importWithSourceDeps.Output("turbine-combined/import_with_source_deps.jar")
importWithSourceDepsJavaInfo, _ := android.OtherModuleProvider(ctx, importWithSourceDeps.Module(), JavaInfoProvider)
@@ -1257,11 +1270,16 @@
android.AssertPathsRelativeToTopEquals(t, "import with source deps header jar",
[]string{importWithSourceDepsHeaderJar.Output.String()}, importWithSourceDepsJavaInfo.HeaderJars)
android.AssertPathsRelativeToTopEquals(t, "import with source deps combined implementation jar inputs",
- []string{"source_deps.jar", sourceJar.Output.String()}, importWithSourceDepsJar.Inputs)
+ []string{importWithSourceDepsLocalJar.Output.String(), sourceJar.Output.String()}, importWithSourceDepsJar.Inputs)
android.AssertPathsRelativeToTopEquals(t, "import with source deps combined header jar inputs",
- []string{"source_deps.jar", sourceHeaderJar.Output.String()}, importWithSourceDepsHeaderJar.Inputs)
+ []string{importWithSourceDepsLocalHeaderJar.Output.String(), sourceHeaderJar.Output.String()}, importWithSourceDepsHeaderJar.Inputs)
+ android.AssertPathsRelativeToTopEquals(t, "import with source deps local combined implementation jar inputs",
+ []string{"source_deps.jar"}, importWithSourceDepsLocalJar.Inputs)
+ android.AssertPathsRelativeToTopEquals(t, "import with source deps local combined header jar inputs",
+ []string{"source_deps.jar"}, importWithSourceDepsLocalHeaderJar.Inputs)
- importWithImportDeps := ctx.ModuleForTests("import_with_import_deps", "android_common")
+ importWithImportDeps := ctx.ModuleForTests(t, "import_with_import_deps", "android_common")
+ importWithImportDepsLocalJar := importWithImportDeps.Output("local-combined/import_with_import_deps.jar")
importWithImportDepsJar := importWithImportDeps.Output("combined/import_with_import_deps.jar")
importWithImportDepsJavaInfo, _ := android.OtherModuleProvider(ctx, importWithImportDeps.Module(), JavaInfoProvider)
@@ -1271,7 +1289,9 @@
android.AssertPathsRelativeToTopEquals(t, "import with import deps header jar",
[]string{importWithImportDepsJar.Output.String()}, importWithImportDepsJavaInfo.HeaderJars)
android.AssertPathsRelativeToTopEquals(t, "import with import deps combined implementation jar inputs",
- []string{"import_deps.jar", importWithNoDepsJar.Output.String()}, importWithImportDepsJar.Inputs)
+ []string{importWithImportDepsLocalJar.Output.String(), importWithNoDepsLocalJar.Output.String()}, importWithImportDepsJar.Inputs)
+ android.AssertPathsRelativeToTopEquals(t, "import with import deps local combined implementation jar inputs",
+ []string{"import_deps.jar"}, importWithImportDepsLocalJar.Inputs)
}
var compilerFlagsTestCases = []struct {
@@ -1323,6 +1343,7 @@
}
func TestCompilerFlags(t *testing.T) {
+ t.Parallel()
for _, testCase := range compilerFlagsTestCases {
ctx := &mockContext{result: true}
CheckKotlincFlags(ctx, []string{testCase.in})
@@ -1337,7 +1358,8 @@
// TODO(jungjw): Consider making this more robust by ignoring path order.
func checkPatchModuleFlag(t *testing.T, ctx *android.TestContext, moduleName string, expected string) {
- variables := ctx.ModuleForTests(moduleName, "android_common").VariablesForTestsRelativeToTop()
+ t.Helper()
+ variables := ctx.ModuleForTests(t, moduleName, "android_common").VariablesForTestsRelativeToTop()
flags := strings.Split(variables["javacFlags"], " ")
got := ""
for _, flag := range flags {
@@ -1353,7 +1375,9 @@
}
func TestPatchModule(t *testing.T) {
+ t.Parallel()
t.Run("Java language level 8", func(t *testing.T) {
+ t.Parallel()
// Test with legacy javac -source 1.8 -target 1.8
bp := `
java_library {
@@ -1386,6 +1410,7 @@
})
t.Run("Java language level 9", func(t *testing.T) {
+ t.Parallel()
// Test with default javac -source 9 -target 9
bp := `
java_library {
@@ -1426,6 +1451,7 @@
}
func TestJavaLibraryWithSystemModules(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "lib-with-source-system-modules",
@@ -1474,7 +1500,7 @@
}
func checkBootClasspathForLibWithSystemModule(t *testing.T, ctx *android.TestContext, moduleName string, expectedSuffix string) {
- javacRule := ctx.ModuleForTests(moduleName, "android_common").Rule("javac")
+ javacRule := ctx.ModuleForTests(t, moduleName, "android_common").Rule("javac")
bootClasspath := javacRule.Args["bootClasspath"]
if strings.HasPrefix(bootClasspath, "--system ") && strings.HasSuffix(bootClasspath, expectedSuffix) {
t.Errorf("bootclasspath of %q must start with --system and end with %q, but was %#v.", moduleName, expectedSuffix, bootClasspath)
@@ -1482,6 +1508,7 @@
}
func TestAidlExportIncludeDirsFromImports(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -1498,7 +1525,7 @@
}
`)
- aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command
+ aidlCommand := ctx.ModuleForTests(t, "foo", "android_common").Rule("aidl").RuleParams.Command
expectedAidlFlag := "-Iaidl/bar"
if !strings.Contains(aidlCommand, expectedAidlFlag) {
t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
@@ -1506,6 +1533,7 @@
}
func TestAidlFlagsArePassedToTheAidlCompiler(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -1514,7 +1542,7 @@
}
`)
- aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command
+ aidlCommand := ctx.ModuleForTests(t, "foo", "android_common").Rule("aidl").RuleParams.Command
expectedAidlFlag := "-Werror"
if !strings.Contains(aidlCommand, expectedAidlFlag) {
t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
@@ -1522,6 +1550,7 @@
}
func TestAidlFlagsWithMinSdkVersion(t *testing.T) {
+ t.Parallel()
fixture := android.GroupFixturePreparers(
prepareForJavaTest, FixtureWithPrebuiltApis(map[string][]string{"14": {"foo"}}))
@@ -1535,6 +1564,7 @@
{"system_current", `sdk_version: "system_current"`, "current"},
} {
t.Run(tc.name, func(t *testing.T) {
+ t.Parallel()
ctx := fixture.RunTestWithBp(t, `
java_library {
name: "foo",
@@ -1542,7 +1572,7 @@
`+tc.sdkVersion+`
}
`)
- aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command
+ aidlCommand := ctx.ModuleForTests(t, "foo", "android_common").Rule("aidl").RuleParams.Command
expectedAidlFlag := "--min_sdk_version=" + tc.expected
if !strings.Contains(aidlCommand, expectedAidlFlag) {
t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
@@ -1552,6 +1582,7 @@
}
func TestAidlFlagsMinSdkVersionDroidstubs(t *testing.T) {
+ t.Parallel()
bpTemplate := `
droidstubs {
name: "foo-stubs",
@@ -1578,13 +1609,14 @@
}
for _, tc := range testCases {
ctx := prepareForJavaTest.RunTestWithBp(t, fmt.Sprintf(bpTemplate, tc.sdkVersionBp))
- aidlCmd := ctx.ModuleForTests("foo-stubs", "android_common").Rule("aidl").RuleParams.Command
+ aidlCmd := ctx.ModuleForTests(t, "foo-stubs", "android_common").Rule("aidl").RuleParams.Command
expected := "--min_sdk_version=" + tc.minSdkVersionExpected
android.AssertStringDoesContain(t, "aidl command conatins incorrect min_sdk_version for testCse: "+tc.desc, aidlCmd, expected)
}
}
func TestAidlEnforcePermissions(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -1593,7 +1625,7 @@
}
`)
- aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command
+ aidlCommand := ctx.ModuleForTests(t, "foo", "android_common").Rule("aidl").RuleParams.Command
expectedAidlFlag := "-Wmissing-permission-annotation -Werror"
if !strings.Contains(aidlCommand, expectedAidlFlag) {
t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
@@ -1601,6 +1633,7 @@
}
func TestAidlEnforcePermissionsException(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -1609,7 +1642,7 @@
}
`)
- aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command
+ aidlCommand := ctx.ModuleForTests(t, "foo", "android_common").Rule("aidl").RuleParams.Command
expectedAidlFlag := "$$FLAGS -Wmissing-permission-annotation -Werror aidl/foo/IFoo.aidl"
if !strings.Contains(aidlCommand, expectedAidlFlag) {
t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
@@ -1621,6 +1654,7 @@
}
func TestDataNativeBinaries(t *testing.T) {
+ t.Parallel()
ctx := android.GroupFixturePreparers(
prepareForJavaTest,
android.PrepareForTestWithAllowMissingDependencies).RunTestWithBp(t, `
@@ -1638,7 +1672,7 @@
buildOS := ctx.Config().BuildOS.String()
- test := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost)
+ test := ctx.ModuleForTests(t, "foo", buildOS+"_common").Module().(*TestHost)
entries := android.AndroidMkEntriesForTest(t, ctx, test)[0]
expected := []string{"out/soong/.intermediates/bin/" + buildOS + "_x86_64/bin:bin"}
actual := entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"]
@@ -1646,6 +1680,7 @@
}
func TestDefaultInstallable(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_test_host {
name: "foo"
@@ -1653,12 +1688,13 @@
`)
buildOS := ctx.Config().BuildOS.String()
- module := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost)
+ module := ctx.ModuleForTests(t, "foo", buildOS+"_common").Module().(*TestHost)
assertDeepEquals(t, "Default installable value should be true.", proptools.BoolPtr(true),
module.properties.Installable)
}
func TestErrorproneEnabled(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -1669,7 +1705,7 @@
}
`)
- javac := ctx.ModuleForTests("foo", "android_common").Description("javac")
+ javac := ctx.ModuleForTests(t, "foo", "android_common").Description("javac")
// Test that the errorprone plugins are passed to javac
expectedSubstring := "-Xplugin:ErrorProne"
@@ -1680,13 +1716,14 @@
// Modules with errorprone { enabled: true } will include errorprone checks
// in the main javac build rule. Only when RUN_ERROR_PRONE is true will
// the explicit errorprone build rule be created.
- errorprone := ctx.ModuleForTests("foo", "android_common").MaybeDescription("errorprone")
+ errorprone := ctx.ModuleForTests(t, "foo", "android_common").MaybeDescription("errorprone")
if errorprone.RuleParams.Description != "" {
t.Errorf("expected errorprone build rule to not exist, but it did")
}
}
func TestErrorproneDisabled(t *testing.T) {
+ t.Parallel()
bp := `
java_library {
name: "foo",
@@ -1703,7 +1740,7 @@
}),
).RunTestWithBp(t, bp)
- javac := ctx.ModuleForTests("foo", "android_common").Description("javac")
+ javac := ctx.ModuleForTests(t, "foo", "android_common").Description("javac")
// Test that the errorprone plugins are not passed to javac, like they would
// be if enabled was true.
@@ -1714,13 +1751,14 @@
// Check that no errorprone build rule is created, like there would be
// if enabled was unset and RUN_ERROR_PRONE was true.
- errorprone := ctx.ModuleForTests("foo", "android_common").MaybeDescription("errorprone")
+ errorprone := ctx.ModuleForTests(t, "foo", "android_common").MaybeDescription("errorprone")
if errorprone.RuleParams.Description != "" {
t.Errorf("expected errorprone build rule to not exist, but it did")
}
}
func TestErrorproneEnabledOnlyByEnvironmentVariable(t *testing.T) {
+ t.Parallel()
bp := `
java_library {
name: "foo",
@@ -1734,8 +1772,8 @@
}),
).RunTestWithBp(t, bp)
- javac := ctx.ModuleForTests("foo", "android_common").Description("javac")
- errorprone := ctx.ModuleForTests("foo", "android_common").Description("errorprone")
+ javac := ctx.ModuleForTests(t, "foo", "android_common").Description("javac")
+ errorprone := ctx.ModuleForTests(t, "foo", "android_common").Description("errorprone")
// Check that the errorprone plugins are not passed to javac, because they
// will instead be passed to the separate errorprone compilation
@@ -1751,6 +1789,7 @@
}
func TestDataDeviceBinsBuildsDeviceBinary(t *testing.T) {
+ t.Parallel()
testCases := []struct {
dataDeviceBinType string
depCompileMultilib string
@@ -1887,6 +1926,7 @@
testName := fmt.Sprintf(`data_device_bins_%s with compile_multilib:"%s"`, tc.dataDeviceBinType, tc.depCompileMultilib)
t.Run(testName, func(t *testing.T) {
+ t.Parallel()
ctx := android.GroupFixturePreparers(PrepareForIntegrationTestWithJava).
ExtendWithErrorHandler(errorHandler).
RunTestWithBp(t, bp)
@@ -1895,7 +1935,7 @@
}
buildOS := ctx.Config.BuildOS.String()
- fooVariant := ctx.ModuleForTests("foo", buildOS+"_common")
+ fooVariant := ctx.ModuleForTests(t, "foo", buildOS+"_common")
fooMod := fooVariant.Module().(*TestHost)
entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, fooMod)[0]
@@ -1907,7 +1947,7 @@
expectedData := []string{}
for _, variant := range tc.variants {
- barVariant := ctx.ModuleForTests("bar", variant)
+ barVariant := ctx.ModuleForTests(t, "bar", variant)
relocated := barVariant.Output("bar")
expectedInput := fmt.Sprintf("out/soong/.intermediates/bar/%s/unstripped/bar", variant)
android.AssertPathRelativeToTopEquals(t, "relocation input", expectedInput, relocated.Input)
@@ -1916,12 +1956,13 @@
}
actualData := entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"]
- android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_TEST_DATA", ctx.Config, expectedData, actualData)
+ android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_TEST_DATA", ctx.Config, android.SortedUniqueStrings(expectedData), android.SortedUniqueStrings(actualData))
})
}
}
func TestDeviceBinaryWrapperGeneration(t *testing.T) {
+ t.Parallel()
// Scenario 1: java_binary has main_class property in its bp
ctx, _ := testJava(t, `
java_binary {
@@ -1930,7 +1971,7 @@
main_class: "foo.bar.jb",
}
`)
- wrapperPath := fmt.Sprint(ctx.ModuleForTests("foo", "android_common").AllOutputs())
+ wrapperPath := fmt.Sprint(ctx.ModuleForTests(t, "foo", "android_common").AllOutputs())
if !strings.Contains(wrapperPath, "foo.sh") {
t.Errorf("wrapper file foo.sh is not generated")
}
@@ -1945,6 +1986,7 @@
}
func TestJavaApiContributionEmptyApiFile(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
android.FixtureMergeEnv(
@@ -1968,6 +2010,7 @@
}
func TestJavaApiLibraryAndProviderLink(t *testing.T) {
+ t.Parallel()
provider_bp_a := `
java_api_contribution {
name: "foo1",
@@ -2024,7 +2067,7 @@
},
}
for _, c := range testcases {
- m := ctx.ModuleForTests(c.moduleName, "android_common")
+ m := ctx.ModuleForTests(t, c.moduleName, "android_common")
manifest := m.Output("metalava.sbox.textproto")
sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, manifest)
manifestCommand := sboxProto.Commands[0].GetCommand()
@@ -2034,6 +2077,7 @@
}
func TestJavaApiLibraryAndDefaultsLink(t *testing.T) {
+ t.Parallel()
provider_bp_a := `
java_api_contribution {
name: "foo1",
@@ -2132,7 +2176,7 @@
},
}
for _, c := range testcases {
- m := ctx.ModuleForTests(c.moduleName, "android_common")
+ m := ctx.ModuleForTests(t, c.moduleName, "android_common")
manifest := m.Output("metalava.sbox.textproto")
sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, manifest)
manifestCommand := sboxProto.Commands[0].GetCommand()
@@ -2142,6 +2186,7 @@
}
func TestJavaApiLibraryJarGeneration(t *testing.T) {
+ t.Parallel()
provider_bp_a := `
java_api_contribution {
name: "foo1",
@@ -2199,7 +2244,7 @@
},
}
for _, c := range testcases {
- m := ctx.ModuleForTests(c.moduleName, "android_common")
+ m := ctx.ModuleForTests(t, c.moduleName, "android_common")
outputs := fmt.Sprint(m.AllOutputs())
if !strings.Contains(outputs, c.outputJarName) {
t.Errorf("Module output does not contain expected jar %s", c.outputJarName)
@@ -2208,6 +2253,7 @@
}
func TestJavaApiLibraryLibsLink(t *testing.T) {
+ t.Parallel()
provider_bp_a := `
java_api_contribution {
name: "foo1",
@@ -2284,7 +2330,7 @@
},
}
for _, c := range testcases {
- m := ctx.ModuleForTests(c.moduleName, "android_common")
+ m := ctx.ModuleForTests(t, c.moduleName, "android_common")
javacRules := m.Rule("javac")
classPathArgs := javacRules.Args["classpath"]
for _, jarName := range c.classPathJarNames {
@@ -2296,6 +2342,7 @@
}
func TestJavaApiLibraryStaticLibsLink(t *testing.T) {
+ t.Parallel()
provider_bp_a := `
java_api_contribution {
name: "foo1",
@@ -2372,7 +2419,7 @@
},
}
for _, c := range testcases {
- m := ctx.ModuleForTests(c.moduleName, "android_common")
+ m := ctx.ModuleForTests(t, c.moduleName, "android_common")
mergeZipsCommand := m.Rule("merge_zips").RuleParams.Command
for _, jarName := range c.staticLibJarNames {
if !strings.Contains(mergeZipsCommand, jarName) {
@@ -2383,6 +2430,7 @@
}
func TestTransitiveSrcFiles(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "a",
@@ -2399,13 +2447,14 @@
static_libs: ["b"],
}
`)
- c := ctx.ModuleForTests("c", "android_common").Module()
+ c := ctx.ModuleForTests(t, "c", "android_common").Module()
javaInfo, _ := android.OtherModuleProvider(ctx, c, JavaInfoProvider)
transitiveSrcFiles := android.Paths(javaInfo.TransitiveSrcFiles.ToList())
android.AssertArrayString(t, "unexpected jar deps", []string{"b.java", "c.java"}, transitiveSrcFiles.Strings())
}
func TestTradefedOptions(t *testing.T) {
+ t.Parallel()
result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, `
java_test_host {
name: "foo",
@@ -2421,7 +2470,7 @@
`)
buildOS := result.Config.BuildOS.String()
- args := result.ModuleForTests("foo", buildOS+"_common").
+ args := result.ModuleForTests(t, "foo", buildOS+"_common").
Output("out/soong/.intermediates/foo/" + buildOS + "_common/foo.config").Args
expected := proptools.NinjaAndShellEscape("<option name=\"exclude-path\" value=\"org/apache\" />")
if args["extraConfigs"] != expected {
@@ -2430,6 +2479,7 @@
}
func TestTestRunnerOptions(t *testing.T) {
+ t.Parallel()
result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, `
java_test_host {
name: "foo",
@@ -2445,7 +2495,7 @@
`)
buildOS := result.Config.BuildOS.String()
- args := result.ModuleForTests("foo", buildOS+"_common").
+ args := result.ModuleForTests(t, "foo", buildOS+"_common").
Output("out/soong/.intermediates/foo/" + buildOS + "_common/foo.config").Args
expected := proptools.NinjaAndShellEscape("<option name=\"test-timeout\" value=\"10m\" />\\n ")
if args["extraTestRunnerConfigs"] != expected {
@@ -2454,6 +2504,7 @@
}
func TestJavaLibraryWithResourcesStem(t *testing.T) {
+ t.Parallel()
ctx, _ := testJavaWithFS(t, `
java_library {
name: "foo",
@@ -2465,7 +2516,7 @@
"test-jar/test/resource.txt": nil,
})
- m := ctx.ModuleForTests("foo", "android_common")
+ m := ctx.ModuleForTests(t, "foo", "android_common")
outputs := fmt.Sprint(m.AllOutputs())
if !strings.Contains(outputs, "test.jar") {
t.Errorf("Module output does not contain expected jar %s", "test.jar")
@@ -2473,6 +2524,7 @@
}
func TestHeadersOnly(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -2481,16 +2533,17 @@
}
`)
- turbine := ctx.ModuleForTests("foo", "android_common").Rule("turbine")
+ turbine := ctx.ModuleForTests(t, "foo", "android_common").Rule("turbine")
if len(turbine.Inputs) != 1 || turbine.Inputs[0].String() != "a.java" {
t.Errorf(`foo inputs %v != ["a.java"]`, turbine.Inputs)
}
- javac := ctx.ModuleForTests("foo", "android_common").MaybeRule("javac")
+ javac := ctx.ModuleForTests(t, "foo", "android_common").MaybeRule("javac")
android.AssertDeepEquals(t, "javac rule", nil, javac.Rule)
}
func TestJavaApiContributionImport(t *testing.T) {
+ t.Parallel()
ctx := android.GroupFixturePreparers(
prepareForJavaTest,
android.FixtureMergeEnv(
@@ -2510,7 +2563,7 @@
api_surface: "public",
}
`)
- m := ctx.ModuleForTests("foo", "android_common")
+ m := ctx.ModuleForTests(t, "foo", "android_common")
manifest := m.Output("metalava.sbox.textproto")
sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, manifest)
manifestCommand := sboxProto.Commands[0].GetCommand()
@@ -2519,6 +2572,7 @@
}
func TestJavaApiLibraryApiFilesSorting(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_api_library {
name: "foo",
@@ -2532,7 +2586,7 @@
stubs_type: "everything",
}
`)
- m := ctx.ModuleForTests("foo", "android_common")
+ m := ctx.ModuleForTests(t, "foo", "android_common")
manifest := m.Output("metalava.sbox.textproto")
sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx, manifest)
manifestCommand := sboxProto.Commands[0].GetCommand()
@@ -2547,6 +2601,7 @@
}
func TestSdkLibraryProvidesSystemModulesToApiLibrary(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -2576,6 +2631,7 @@
}
func TestApiLibraryDroidstubsDependency(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -2605,9 +2661,9 @@
`)
currentApiTimestampPath := "api-stubs-docs-non-updatable/android_common/everything/check_current_api.timestamp"
- foo := result.ModuleForTests("foo", "android_common").Module().(*ApiLibrary)
+ foo := result.ModuleForTests(t, "foo", "android_common").Module().(*ApiLibrary)
fooValidationPathsString := strings.Join(foo.validationPaths.Strings(), " ")
- bar := result.ModuleForTests("bar", "android_common").Module().(*ApiLibrary)
+ bar := result.ModuleForTests(t, "bar", "android_common").Module().(*ApiLibrary)
barValidationPathsString := strings.Join(bar.validationPaths.Strings(), " ")
android.AssertStringDoesContain(t,
"Module expected to have validation",
@@ -2622,6 +2678,7 @@
}
func TestDisableFromTextStubForCoverageBuild(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -2651,6 +2708,7 @@
}
func TestMultiplePrebuilts(t *testing.T) {
+ t.Parallel()
bp := `
// an rdep
java_library {
@@ -2733,8 +2791,8 @@
).RunTestWithBp(t, fmt.Sprintf(bp, tc.selectedDependencyName))
// check that rdep gets the correct variation of dep
- foo := ctx.ModuleForTests("foo", "android_common")
- expectedDependency := ctx.ModuleForTests(tc.expectedDependencyName, "android_common")
+ foo := ctx.ModuleForTests(t, "foo", "android_common")
+ expectedDependency := ctx.ModuleForTests(t, tc.expectedDependencyName, "android_common")
android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", foo.Module().Name(), tc.expectedDependencyName), true, hasDep(ctx, foo.Module(), expectedDependency.Module()))
// check that output file of dep is always bar.jar
@@ -2749,6 +2807,7 @@
}
func TestMultiplePlatformCompatConfigPrebuilts(t *testing.T) {
+ t.Parallel()
bp := `
// multiple variations of platform_compat_config
// source
@@ -2802,13 +2861,14 @@
android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ADSERVICES", "myapex_contributions"),
).RunTestWithBp(t, fmt.Sprintf(bp, tc.selectedDependencyName))
- mergedGlobalConfig := ctx.SingletonForTests("platform_compat_config_singleton").Output("compat_config/merged_compat_config.xml")
+ mergedGlobalConfig := ctx.SingletonForTests(t, "platform_compat_config_singleton").Output("compat_config/merged_compat_config.xml")
android.AssertIntEquals(t, "The merged compat config file should only have a single dependency", 1, len(mergedGlobalConfig.Implicits))
android.AssertStringEquals(t, "The merged compat config file is missing the appropriate platform compat config", mergedGlobalConfig.Implicits[0].String(), tc.expectedPlatformCompatConfigXml)
}
}
func TestApiLibraryAconfigDeclarations(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
@@ -2850,14 +2910,14 @@
android.AssertBoolEquals(t, "foo expected to depend on bar",
CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "bar"), true)
- m := result.ModuleForTests("foo", "android_common")
+ m := result.ModuleForTests(t, "foo", "android_common")
android.AssertStringDoesContain(t, "foo generates revert annotations file",
- strings.Join(m.AllOutputs(), ""), "revert-annotations-exportable.txt")
+ strings.Join(m.AllOutputs(), ""), "flags-config-exportable.xml")
// revert-annotations.txt passed to exportable stubs generation metalava command
manifest := m.Output("metalava.sbox.textproto")
cmdline := String(android.RuleBuilderSboxProtoForTests(t, result.TestContext, manifest).Commands[0].Command)
- android.AssertStringDoesContain(t, "flagged api hide command not included", cmdline, "revert-annotations-exportable.txt")
+ android.AssertStringDoesContain(t, "flagged api hide command not included", cmdline, "flags-config-exportable.xml")
}
func TestTestOnly(t *testing.T) {
@@ -2919,6 +2979,7 @@
// Don't allow setting test-only on things that are always tests or never tests.
func TestInvalidTestOnlyTargets(t *testing.T) {
+ t.Parallel()
testCases := []string{
` java_test { name: "java-test", test_only: true, srcs: ["foo.java"], } `,
` java_test_host { name: "java-test-host", test_only: true, srcs: ["foo.java"], } `,
@@ -2954,6 +3015,7 @@
}
func TestJavaLibHostWithStem(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library_host {
name: "foo",
@@ -2963,7 +3025,7 @@
`)
buildOS := ctx.Config().BuildOS.String()
- foo := ctx.ModuleForTests("foo", buildOS+"_common")
+ foo := ctx.ModuleForTests(t, "foo", buildOS+"_common")
outputs := fmt.Sprint(foo.AllOutputs())
if !strings.Contains(outputs, "foo-new.jar") {
@@ -2972,6 +3034,7 @@
}
func TestJavaLibWithStem(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -2980,7 +3043,7 @@
}
`)
- foo := ctx.ModuleForTests("foo", "android_common")
+ foo := ctx.ModuleForTests(t, "foo", "android_common")
outputs := fmt.Sprint(foo.AllOutputs())
if !strings.Contains(outputs, "foo-new.jar") {
@@ -2989,6 +3052,7 @@
}
func TestJavaLibraryOutputFilesRel(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, `
@@ -3010,9 +3074,9 @@
}
`)
- foo := result.ModuleForTests("foo", "android_common")
- bar := result.ModuleForTests("bar", "android_common")
- baz := result.ModuleForTests("baz", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
+ bar := result.ModuleForTests(t, "bar", "android_common")
+ baz := result.ModuleForTests(t, "baz", "android_common")
fooOutputPaths := foo.OutputFiles(result.TestContext, t, "")
barOutputPaths := bar.OutputFiles(result.TestContext, t, "")
@@ -3034,10 +3098,10 @@
}
func TestCoverage(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
prepareForTestWithFrameworkJacocoInstrumentation,
- PrepareForTestWithTransitiveClasspathEnabled,
).RunTestWithBp(t, `
android_app {
name: "foo",
@@ -3054,8 +3118,8 @@
}
`)
- foo := result.ModuleForTests("foo", "android_common")
- androidCar := result.ModuleForTests("android.car", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
+ androidCar := result.ModuleForTests(t, "android.car", "android_common")
fooJacoco := foo.Rule("jacoco")
fooCombine := foo.Description("for javac")
@@ -3104,6 +3168,7 @@
// Test that a dependency edge is created to the matching variant of a native library listed in `jni_libs` of java_binary
func TestNativeRequiredDepOfJavaBinary(t *testing.T) {
+ t.Parallel()
findDepsOfModule := func(ctx *android.TestContext, module android.Module, depName string) []blueprint.Module {
var ret []blueprint.Module
ctx.VisitDirectDeps(module, func(dep blueprint.Module) {
@@ -3125,6 +3190,75 @@
}
`
res, _ := testJava(t, bp)
- deps := findDepsOfModule(res, res.ModuleForTests("myjavabin", "android_common").Module(), "mynativelib")
+ deps := findDepsOfModule(res, res.ModuleForTests(t, "myjavabin", "android_common").Module(), "mynativelib")
android.AssertIntEquals(t, "Create a dep on the first variant", 1, len(deps))
}
+
+func TestBootJarNotInUsesLibs(t *testing.T) {
+ t.Parallel()
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ PrepareForTestWithJavaSdkLibraryFiles,
+ FixtureWithLastReleaseApis("mysdklibrary", "myothersdklibrary"),
+ FixtureConfigureApexBootJars("myapex:mysdklibrary"),
+ ).RunTestWithBp(t, `
+ bootclasspath_fragment {
+ name: "myfragment",
+ contents: ["mysdklibrary"],
+ hidden_api: {
+ split_packages: ["*"],
+ },
+ }
+
+ java_sdk_library {
+ name: "mysdklibrary",
+ srcs: ["Test.java"],
+ compile_dex: true,
+ public: {enabled: true},
+ min_sdk_version: "2",
+ permitted_packages: ["mysdklibrary"],
+ sdk_version: "current",
+ }
+
+ java_sdk_library {
+ name: "myothersdklibrary",
+ srcs: ["Test.java"],
+ compile_dex: true,
+ public: {enabled: true},
+ min_sdk_version: "2",
+ permitted_packages: ["myothersdklibrary"],
+ sdk_version: "current",
+ }
+
+ java_library {
+ name: "foo",
+ libs: [
+ "bar",
+ "mysdklibrary.stubs",
+ ],
+ srcs: ["A.java"],
+ }
+
+ java_library {
+ name: "bar",
+ libs: [
+ "myothersdklibrary.stubs"
+ ],
+ }
+ `)
+ ctx := result.TestContext
+ fooModule := ctx.ModuleForTests(t, "foo", "android_common")
+
+ androidMkEntries := android.AndroidMkEntriesForTest(t, ctx, fooModule.Module())[0]
+ localExportSdkLibraries := androidMkEntries.EntryMap["LOCAL_EXPORT_SDK_LIBRARIES"]
+ android.AssertStringListDoesNotContain(t,
+ "boot jar should not be included in uses libs entries",
+ localExportSdkLibraries,
+ "mysdklibrary",
+ )
+ android.AssertStringListContains(t,
+ "non boot jar is included in uses libs entries",
+ localExportSdkLibraries,
+ "myothersdklibrary",
+ )
+}
diff --git a/java/jdeps.go b/java/jdeps.go
index c2ce503..56142c8 100644
--- a/java/jdeps.go
+++ b/java/jdeps.go
@@ -37,8 +37,6 @@
outputPath android.Path
}
-var _ android.SingletonMakeVarsProvider = (*jdepsGeneratorSingleton)(nil)
-
const (
jdepsJsonFileName = "module_bp_java_deps.json"
)
@@ -47,13 +45,13 @@
// (b/204397180) Generate module_bp_java_deps.json by default.
moduleInfos := make(map[string]android.IdeInfo)
- ctx.VisitAllModules(func(module android.Module) {
- if !module.Enabled(ctx) {
+ ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
+ if !android.OtherModulePointerProviderOrDefault(ctx, module, android.CommonModuleInfoProvider).Enabled {
return
}
// Prevent including both prebuilts and matching source modules when one replaces the other.
- if !android.IsModulePreferred(module) {
+ if !android.IsModulePreferredProxy(ctx, module) {
return
}
@@ -62,9 +60,11 @@
return
}
name := ideInfoProvider.BaseModuleName
- ideModuleNameProvider, ok := module.(android.IDECustomizedModuleName)
- if ok {
- name = ideModuleNameProvider.IDECustomizedModuleName()
+ if info, ok := android.OtherModuleProvider(ctx, module, JavaLibraryInfoProvider); ok && info.Prebuilt {
+ // TODO(b/113562217): Extract the base module name from the Import name, often the Import name
+ // has a prefix "prebuilt_". Remove the prefix explicitly if needed until we find a better
+ // solution to get the Import name.
+ name = android.RemoveOptionalPrebuiltPrefix(module.Name())
}
dpInfo := moduleInfos[name]
@@ -72,13 +72,12 @@
dpInfo.Paths = []string{ctx.ModuleDir(module)}
moduleInfos[name] = dpInfo
- mkProvider, ok := module.(android.AndroidMkDataProvider)
+ mkProvider, ok := android.OtherModuleProvider(ctx, module, android.AndroidMkDataInfoProvider)
if !ok {
return
}
- data := mkProvider.AndroidMk()
- if data.Class != "" {
- dpInfo.Classes = append(dpInfo.Classes, data.Class)
+ if mkProvider.Class != "" {
+ dpInfo.Classes = append(dpInfo.Classes, mkProvider.Class)
}
if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
@@ -101,14 +100,7 @@
Rule: android.Touch,
Output: jfpath,
})
-}
-
-func (j *jdepsGeneratorSingleton) MakeVars(ctx android.MakeVarsContext) {
- if j.outputPath == nil {
- return
- }
-
- ctx.DistForGoal("general-tests", j.outputPath)
+ ctx.DistForGoals([]string{"general-tests", "dist_files"}, j.outputPath)
}
func createJsonFile(moduleInfos map[string]android.IdeInfo, jfpath android.WritablePath) error {
diff --git a/java/jdeps_test.go b/java/jdeps_test.go
index 1435000..00f3839 100644
--- a/java/jdeps_test.go
+++ b/java/jdeps_test.go
@@ -22,6 +22,7 @@
)
func TestCollectJavaLibraryPropertiesAddLibsDeps(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t,
`
java_library {name: "Foo"}
@@ -31,7 +32,7 @@
libs: ["Foo", "Bar"],
}
`)
- module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
+ module := ctx.ModuleForTests(t, "javalib", "android_common").Module().(*Library)
dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
for _, expected := range []string{"Foo", "Bar"} {
@@ -42,6 +43,7 @@
}
func TestCollectJavaLibraryPropertiesAddStaticLibsDeps(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t,
`
java_library {name: "Foo"}
@@ -51,7 +53,7 @@
static_libs: ["Foo", "Bar"],
}
`)
- module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
+ module := ctx.ModuleForTests(t, "javalib", "android_common").Module().(*Library)
dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
for _, expected := range []string{"Foo", "Bar"} {
@@ -62,6 +64,7 @@
}
func TestCollectJavaLibraryPropertiesAddScrs(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t,
`
java_library {
@@ -69,7 +72,7 @@
srcs: ["Foo.java", "Bar.java"],
}
`)
- module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
+ module := ctx.ModuleForTests(t, "javalib", "android_common").Module().(*Library)
dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
expected := []string{"Foo.java", "Bar.java"}
@@ -79,6 +82,7 @@
}
func TestCollectJavaLibraryPropertiesAddAidlIncludeDirs(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t,
`
java_library {
@@ -88,7 +92,7 @@
},
}
`)
- module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
+ module := ctx.ModuleForTests(t, "javalib", "android_common").Module().(*Library)
dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
expected := []string{"Foo", "Bar"}
@@ -98,6 +102,7 @@
}
func TestCollectJavaLibraryWithJarJarRules(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t,
`
java_library {
@@ -106,7 +111,7 @@
jarjar_rules: "jarjar_rules.txt",
}
`)
- module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
+ module := ctx.ModuleForTests(t, "javalib", "android_common").Module().(*Library)
dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
android.AssertStringEquals(t, "IdeInfo.Srcs of repackaged library should not be empty", "foo.java", dpInfo.Srcs[0])
@@ -117,6 +122,7 @@
}
func TestCollectJavaLibraryLinkingAgainstVersionedSdk(t *testing.T) {
+ t.Parallel()
ctx := android.GroupFixturePreparers(
prepareForJavaTest,
FixtureWithPrebuiltApis(map[string][]string{
@@ -129,7 +135,7 @@
sdk_version: "29",
}
`)
- module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
+ module := ctx.ModuleForTests(t, "javalib", "android_common").Module().(*Library)
dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
android.AssertStringListContains(t, "IdeInfo.Deps should contain versioned sdk module", dpInfo.Deps, "sdk_public_29_android")
@@ -165,11 +171,11 @@
api_surface: "public",
}
`)
- javalib := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
+ javalib := ctx.ModuleForTests(t, "javalib", "android_common").Module().(*Library)
dpInfo, _ := android.OtherModuleProvider(ctx, javalib, android.IdeInfoProviderKey)
android.AssertStringListDoesNotContain(t, "IdeInfo.Deps should contain not contain `none`", dpInfo.Deps, "none")
- javalib_stubs := ctx.ModuleForTests("javalib.stubs", "android_common").Module().(*ApiLibrary)
+ javalib_stubs := ctx.ModuleForTests(t, "javalib.stubs", "android_common").Module().(*ApiLibrary)
dpInfo, _ = android.OtherModuleProvider(ctx, javalib_stubs, android.IdeInfoProviderKey)
android.AssertStringListDoesNotContain(t, "IdeInfo.Deps should contain not contain `none`", dpInfo.Deps, "none")
}
diff --git a/java/kotlin.go b/java/kotlin.go
index f42d163..308bb03 100644
--- a/java/kotlin.go
+++ b/java/kotlin.go
@@ -181,6 +181,7 @@
Command: `rm -rf "$srcJarDir" "$kotlinBuildFile" "$kaptDir" && ` +
`mkdir -p "$srcJarDir" "$kaptDir/sources" "$kaptDir/classes" && ` +
`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
+ `${config.FindInputDeltaCmd} --template '' --target "$out" --inputs_file "$out.rsp" && ` +
`${config.GenKotlinBuildFileCmd} --classpath "$classpath" --name "$name"` +
` --srcs "$out.rsp" --srcs "$srcJarDir/list"` +
` $commonSrcFilesArg --out "$kotlinBuildFile" && ` +
@@ -197,8 +198,10 @@
`$kaptProcessor ` +
`-Xbuild-file=$kotlinBuildFile && ` +
`${config.SoongZipCmd} -jar -write_if_changed -o $out -C $kaptDir/stubs -D $kaptDir/stubs && ` +
+ `if [ -f "$out.pc_state.new" ]; then mv "$out.pc_state.new" "$out.pc_state"; fi && ` +
`rm -rf "$srcJarDir"`,
CommandDeps: []string{
+ "${config.FindInputDeltaCmd}",
"${config.KotlincCmd}",
"${config.KotlinCompilerJar}",
"${config.KotlinKaptJar}",
diff --git a/java/kotlin_test.go b/java/kotlin_test.go
index 45eac01..4b56cff 100644
--- a/java/kotlin_test.go
+++ b/java/kotlin_test.go
@@ -24,6 +24,7 @@
)
func TestKotlin(t *testing.T) {
+ t.Parallel()
bp := `
java_library {
name: "foo",
@@ -49,13 +50,6 @@
srcs: ["d.kt"],
}`
- kotlinStdlibTurbineCombinedJars := []string{
- "out/soong/.intermediates/default/java/kotlin-stdlib/android_common/turbine-combined/kotlin-stdlib.jar",
- "out/soong/.intermediates/default/java/kotlin-stdlib-jdk7/android_common/turbine-combined/kotlin-stdlib-jdk7.jar",
- "out/soong/.intermediates/default/java/kotlin-stdlib-jdk8/android_common/turbine-combined/kotlin-stdlib-jdk8.jar",
- "out/soong/.intermediates/default/java/kotlin-annotations/android_common/turbine-combined/kotlin-annotations.jar",
- }
-
kotlinStdlibTurbineJars := []string{
"out/soong/.intermediates/default/java/kotlin-stdlib/android_common/turbine/kotlin-stdlib.jar",
"out/soong/.intermediates/default/java/kotlin-stdlib-jdk7/android_common/turbine/kotlin-stdlib-jdk7.jar",
@@ -70,21 +64,11 @@
"out/soong/.intermediates/default/java/kotlin-annotations/android_common/javac/kotlin-annotations.jar",
}
- bootclasspathTurbineCombinedJars := []string{
- "out/soong/.intermediates/default/java/stable.core.platform.api.stubs/android_common/turbine-combined/stable.core.platform.api.stubs.jar",
- "out/soong/.intermediates/default/java/core-lambda-stubs/android_common/turbine-combined/core-lambda-stubs.jar",
- }
-
bootclasspathTurbineJars := []string{
"out/soong/.intermediates/default/java/stable.core.platform.api.stubs/android_common/turbine/stable.core.platform.api.stubs.jar",
"out/soong/.intermediates/default/java/core-lambda-stubs/android_common/turbine/core-lambda-stubs.jar",
}
- frameworkTurbineCombinedJars := []string{
- "out/soong/.intermediates/default/java/ext/android_common/turbine-combined/ext.jar",
- "out/soong/.intermediates/default/java/framework/android_common/turbine-combined/framework.jar",
- }
-
frameworkTurbineJars := []string{
"out/soong/.intermediates/default/java/ext/android_common/turbine/ext.jar",
"out/soong/.intermediates/default/java/framework/android_common/turbine/framework.jar",
@@ -108,68 +92,8 @@
barHeaderCombinedInputs []string
}{
{
- name: "normal",
- preparer: android.NullFixturePreparer,
- fooKotlincInputs: []string{"a.java", "b.kt"},
- fooJavacInputs: []string{"a.java"},
- fooKotlincClasspath: slices.Concat(
- bootclasspathTurbineCombinedJars,
- frameworkTurbineCombinedJars,
- []string{"out/soong/.intermediates/quz/android_common/turbine-combined/quz.jar"},
- kotlinStdlibTurbineCombinedJars,
- ),
- fooJavacClasspath: slices.Concat(
- []string{"out/soong/.intermediates/foo/android_common/kotlin_headers/foo.jar"},
- frameworkTurbineCombinedJars,
- []string{"out/soong/.intermediates/quz/android_common/turbine-combined/quz.jar"},
- kotlinStdlibTurbineCombinedJars,
- ),
- fooCombinedInputs: slices.Concat(
- []string{
- "out/soong/.intermediates/foo/android_common/kotlin/foo.jar",
- "out/soong/.intermediates/foo/android_common/javac/foo.jar",
- "out/soong/.intermediates/quz/android_common/combined/quz.jar",
- },
- kotlinStdlibJavacJars,
- ),
- fooHeaderCombinedInputs: slices.Concat(
- []string{
- "out/soong/.intermediates/foo/android_common/turbine/foo.jar",
- "out/soong/.intermediates/foo/android_common/kotlin_headers/foo.jar",
- "out/soong/.intermediates/quz/android_common/turbine-combined/quz.jar",
- },
- kotlinStdlibTurbineCombinedJars,
- ),
-
- barKotlincInputs: []string{"b.kt"},
- barKotlincClasspath: slices.Concat(
- bootclasspathTurbineCombinedJars,
- frameworkTurbineCombinedJars,
- []string{
- "out/soong/.intermediates/foo/android_common/turbine-combined/foo.jar",
- "out/soong/.intermediates/baz/android_common/turbine-combined/baz.jar",
- },
- kotlinStdlibTurbineCombinedJars,
- ),
- barCombinedInputs: slices.Concat(
- []string{
- "out/soong/.intermediates/bar/android_common/kotlin/bar.jar",
- "out/soong/.intermediates/baz/android_common/combined/baz.jar",
- },
- kotlinStdlibJavacJars,
- []string{},
- ),
- barHeaderCombinedInputs: slices.Concat(
- []string{
- "out/soong/.intermediates/bar/android_common/kotlin_headers/bar.jar",
- "out/soong/.intermediates/baz/android_common/turbine-combined/baz.jar",
- },
- kotlinStdlibTurbineCombinedJars,
- ),
- },
- {
name: "transitive classpath",
- preparer: PrepareForTestWithTransitiveClasspathEnabled,
+ preparer: android.NullFixturePreparer,
fooKotlincInputs: []string{"a.java", "b.kt"},
fooJavacInputs: []string{"a.java"},
fooKotlincClasspath: slices.Concat(
@@ -234,11 +158,12 @@
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
tt.preparer,
).RunTestWithBp(t, bp)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
fooKotlinc := foo.Rule("kotlinc")
android.AssertPathsRelativeToTopEquals(t, "foo kotlinc inputs", tt.fooKotlincInputs, fooKotlinc.Inputs)
@@ -258,7 +183,7 @@
fooCombinedHeaderJar := foo.Output("turbine-combined/foo.jar")
android.AssertPathsRelativeToTopEquals(t, "foo header combined inputs", tt.fooHeaderCombinedInputs, fooCombinedHeaderJar.Inputs)
- bar := result.ModuleForTests("bar", "android_common")
+ bar := result.ModuleForTests(t, "bar", "android_common")
barKotlinc := bar.Rule("kotlinc")
android.AssertPathsRelativeToTopEquals(t, "bar kotlinc inputs", tt.barKotlincInputs, barKotlinc.Inputs)
@@ -275,6 +200,7 @@
}
func TestKapt(t *testing.T) {
+ t.Parallel()
bp := `
java_library {
name: "foo",
@@ -303,18 +229,19 @@
}
`
t.Run("", func(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, bp)
buildOS := ctx.Config().BuildOS.String()
- foo := ctx.ModuleForTests("foo", "android_common")
+ foo := ctx.ModuleForTests(t, "foo", "android_common")
kaptStubs := foo.Rule("kapt")
turbineApt := foo.Description("turbine apt")
kotlinc := foo.Rule("kotlinc")
javac := foo.Rule("javac")
- bar := ctx.ModuleForTests("bar", buildOS+"_common").Rule("javac").Output.String()
- baz := ctx.ModuleForTests("baz", buildOS+"_common").Rule("javac").Output.String()
+ bar := ctx.ModuleForTests(t, "bar", buildOS+"_common").Rule("javac").Output.String()
+ baz := ctx.ModuleForTests(t, "baz", buildOS+"_common").Rule("javac").Output.String()
// Test that the kotlin and java sources are passed to kapt and kotlinc
if len(kaptStubs.Inputs) != 2 || kaptStubs.Inputs[0].String() != "a.java" || kaptStubs.Inputs[1].String() != "b.kt" {
@@ -384,6 +311,7 @@
})
t.Run("errorprone", func(t *testing.T) {
+ t.Parallel()
env := map[string]string{
"RUN_ERROR_PRONE": "true",
}
@@ -395,13 +323,13 @@
buildOS := result.Config.BuildOS.String()
- kapt := result.ModuleForTests("foo", "android_common").Rule("kapt")
- javac := result.ModuleForTests("foo", "android_common").Description("javac")
- errorprone := result.ModuleForTests("foo", "android_common").Description("errorprone")
+ kapt := result.ModuleForTests(t, "foo", "android_common").Rule("kapt")
+ javac := result.ModuleForTests(t, "foo", "android_common").Description("javac")
+ errorprone := result.ModuleForTests(t, "foo", "android_common").Description("errorprone")
- bar := result.ModuleForTests("bar", buildOS+"_common").Description("javac").Output.String()
- baz := result.ModuleForTests("baz", buildOS+"_common").Description("javac").Output.String()
- myCheck := result.ModuleForTests("my_check", buildOS+"_common").Description("javac").Output.String()
+ bar := result.ModuleForTests(t, "bar", buildOS+"_common").Description("javac").Output.String()
+ baz := result.ModuleForTests(t, "baz", buildOS+"_common").Description("javac").Output.String()
+ myCheck := result.ModuleForTests(t, "my_check", buildOS+"_common").Description("javac").Output.String()
// Test that the errorprone plugins are not passed to kapt
expectedProcessorPath := "-P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + bar +
@@ -434,6 +362,7 @@
}
func TestKaptEncodeFlags(t *testing.T) {
+ t.Parallel()
// Compares the kaptEncodeFlags against the results of the example implementation at
// https://kotlinlang.org/docs/reference/kapt.html#apjavac-options-encoding
tests := []struct {
@@ -484,6 +413,7 @@
for i, test := range tests {
t.Run(strconv.Itoa(i), func(t *testing.T) {
+ t.Parallel()
got := kaptEncodeFlags(test.in)
if got != test.out {
t.Errorf("\nwant %q\n got %q", test.out, got)
@@ -493,6 +423,7 @@
}
func TestKotlinCompose(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, `
@@ -501,7 +432,7 @@
}
kotlin_plugin {
- name: "androidx.compose.compiler_compiler-hosted-plugin",
+ name: "kotlin-compose-compiler-plugin",
}
java_library {
@@ -523,9 +454,9 @@
buildOS := result.Config.BuildOS.String()
- composeCompiler := result.ModuleForTests("androidx.compose.compiler_compiler-hosted-plugin", buildOS+"_common").Rule("combineJar").Output
- withCompose := result.ModuleForTests("withcompose", "android_common")
- noCompose := result.ModuleForTests("nocompose", "android_common")
+ composeCompiler := result.ModuleForTests(t, "kotlin-compose-compiler-plugin", buildOS+"_common").Rule("combineJar").Output
+ withCompose := result.ModuleForTests(t, "withcompose", "android_common")
+ noCompose := result.ModuleForTests(t, "nocompose", "android_common")
android.AssertStringListContains(t, "missing compose compiler dependency",
withCompose.Rule("kotlinc").Implicits.Strings(), composeCompiler.String())
@@ -544,6 +475,7 @@
}
func TestKotlinPlugin(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, `
@@ -570,9 +502,9 @@
buildOS := result.Config.BuildOS.String()
- kotlinPlugin := result.ModuleForTests("kotlin_plugin", buildOS+"_common").Rule("combineJar").Output
- withKotlinPlugin := result.ModuleForTests("with_kotlin_plugin", "android_common")
- noKotlinPlugin := result.ModuleForTests("no_kotlin_plugin", "android_common")
+ kotlinPlugin := result.ModuleForTests(t, "kotlin_plugin", buildOS+"_common").Rule("combineJar").Output
+ withKotlinPlugin := result.ModuleForTests(t, "with_kotlin_plugin", "android_common")
+ noKotlinPlugin := result.ModuleForTests(t, "no_kotlin_plugin", "android_common")
android.AssertStringListContains(t, "missing plugin compiler dependency",
withKotlinPlugin.Rule("kotlinc").Implicits.Strings(), kotlinPlugin.String())
diff --git a/java/legacy_core_platform_api_usage.go b/java/legacy_core_platform_api_usage.go
index 4be7d04..21895d4 100644
--- a/java/legacy_core_platform_api_usage.go
+++ b/java/legacy_core_platform_api_usage.go
@@ -47,8 +47,8 @@
"sam",
"saminterfacelibrary",
"sammanagerlibrary",
- "services",
"services.core.unboosted",
+ "services.impl",
"Settings-core",
"SettingsGoogle",
"SettingsGoogleOverlayCoral",
diff --git a/java/lint.go b/java/lint.go
index ac90e19..dc1e51f 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -69,6 +69,11 @@
// If soong gets support for testonly, this flag should be replaced with that.
Test *bool
+ // Same as the regular Test property, but set by internal soong code based on if the module
+ // type is a test module type. This will act as the default value for the test property,
+ // but can be overridden by the user.
+ Test_module_type *bool `blueprint:"mutated"`
+
// Whether to ignore the exit code of Android lint. This is the --exit_code
// option. Defaults to false.
Suppress_exit_code *bool
@@ -257,7 +262,12 @@
if l.library {
cmd.Flag("--library")
}
- if proptools.BoolDefault(l.properties.Lint.Test, false) {
+
+ test := proptools.BoolDefault(l.properties.Lint.Test_module_type, false)
+ if l.properties.Lint.Test != nil {
+ test = *l.properties.Lint.Test
+ }
+ if test {
cmd.Flag("--test")
}
if l.manifest != nil {
@@ -388,7 +398,7 @@
}
}
- extraLintCheckModules := ctx.GetDirectDepsWithTag(extraLintCheckTag)
+ extraLintCheckModules := ctx.GetDirectDepsProxyWithTag(extraLintCheckTag)
for _, extraLintCheckModule := range extraLintCheckModules {
if dep, ok := android.OtherModuleProvider(ctx, extraLintCheckModule, JavaInfoProvider); ok {
l.extraLintCheckJars = append(l.extraLintCheckJars, dep.ImplementationAndResourcesJars...)
@@ -413,7 +423,7 @@
depSetsBuilder := NewLintDepSetBuilder().Direct(html, text, xml, baseline)
- ctx.VisitDirectDepsWithTag(staticLibTag, func(dep android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(staticLibTag, func(dep android.ModuleProxy) {
if info, ok := android.OtherModuleProvider(ctx, dep, LintProvider); ok {
depSetsBuilder.Transitive(info)
}
@@ -470,7 +480,7 @@
cmd := rule.Command()
- cmd.Flag(`JAVA_OPTS="-Xmx3072m --add-opens java.base/java.util=ALL-UNNAMED"`).
+ cmd.Flag(`JAVA_OPTS="-Xmx4096m --add-opens java.base/java.util=ALL-UNNAMED"`).
FlagWithArg("ANDROID_SDK_HOME=", lintPaths.homeDir.String()).
FlagWithInput("SDK_ANNOTATIONS=", annotationsZipPath).
FlagWithInput("LINT_OPTS=-DLINT_API_DATABASE=", apiVersionsXMLPath)
@@ -585,12 +595,12 @@
l.copyLintDependencies(ctx)
}
-func findModuleOrErr(ctx android.SingletonContext, moduleName string) android.Module {
- var res android.Module
- ctx.VisitAllModules(func(m android.Module) {
+func findModuleOrErr(ctx android.SingletonContext, moduleName string) *android.ModuleProxy {
+ var res *android.ModuleProxy
+ ctx.VisitAllModuleProxies(func(m android.ModuleProxy) {
if ctx.ModuleName(m) == moduleName {
if res == nil {
- res = m
+ res = &m
} else {
ctx.Errorf("lint: multiple %s modules found: %s and %s", moduleName,
ctx.ModuleSubDir(m), ctx.ModuleSubDir(res))
@@ -625,13 +635,13 @@
ctx.Build(pctx, android.BuildParams{
Rule: android.CpIfChanged,
- Input: android.OutputFileForModule(ctx, sdkAnnotations, ""),
+ Input: android.OutputFileForModule(ctx, *sdkAnnotations, ""),
Output: copiedLintDatabaseFilesPath(ctx, files.annotationCopiedName),
})
ctx.Build(pctx, android.BuildParams{
Rule: android.CpIfChanged,
- Input: android.OutputFileForModule(ctx, apiVersionsDb, ".api_versions.xml"),
+ Input: android.OutputFileForModule(ctx, *apiVersionsDb, ".api_versions.xml"),
Output: copiedLintDatabaseFilesPath(ctx, files.apiVersionsCopiedName),
})
}
@@ -648,12 +658,13 @@
var outputs []*LintInfo
var dirs []string
- ctx.VisitAllModules(func(m android.Module) {
- if ctx.Config().KatiEnabled() && !m.ExportedToMake() {
+ ctx.VisitAllModuleProxies(func(m android.ModuleProxy) {
+ commonInfo := android.OtherModulePointerProviderOrDefault(ctx, m, android.CommonModuleInfoProvider)
+ if ctx.Config().KatiEnabled() && !commonInfo.ExportedToMake {
return
}
- if apex, ok := m.(android.ApexModule); ok && apex.NotAvailableForPlatform() {
+ if commonInfo.IsApexModule && commonInfo.NotAvailableForPlatform {
apexInfo, _ := android.OtherModuleProvider(ctx, m, android.ApexInfoProvider)
if apexInfo.IsForPlatform() {
// There are stray platform variants of modules in apexes that are not available for
@@ -694,16 +705,12 @@
zip(l.referenceBaselineZip, func(l *LintInfo) android.Path { return l.ReferenceBaseline })
ctx.Phony("lint-check", l.htmlZip, l.textZip, l.xmlZip, l.referenceBaselineZip)
-}
-func (l *lintSingleton) MakeVars(ctx android.MakeVarsContext) {
if !ctx.Config().UnbundledBuild() {
ctx.DistForGoal("lint-check", l.htmlZip, l.textZip, l.xmlZip, l.referenceBaselineZip)
}
}
-var _ android.SingletonMakeVarsProvider = (*lintSingleton)(nil)
-
func init() {
android.RegisterParallelSingletonType("lint",
func() android.Singleton { return &lintSingleton{} })
diff --git a/java/lint_test.go b/java/lint_test.go
index afe3914..236fa63 100644
--- a/java/lint_test.go
+++ b/java/lint_test.go
@@ -22,6 +22,7 @@
)
func TestJavaLintDoesntUseBaselineImplicitly(t *testing.T) {
+ t.Parallel()
ctx, _ := testJavaWithFS(t, `
java_library {
name: "foo",
@@ -37,7 +38,7 @@
"lint-baseline.xml": nil,
})
- foo := ctx.ModuleForTests("foo", "android_common")
+ foo := ctx.ModuleForTests(t, "foo", "android_common")
sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx, foo.Output("lint.sbox.textproto"))
if strings.Contains(*sboxProto.Commands[0].Command, "--baseline lint-baseline.xml") {
@@ -46,6 +47,7 @@
}
func TestJavaLintRequiresCustomLintFileToExist(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.PrepareForTestDisallowNonExistentPaths,
@@ -65,6 +67,7 @@
}
func TestJavaLintUsesCorrectBpConfig(t *testing.T) {
+ t.Parallel()
ctx, _ := testJavaWithFS(t, `
java_library {
name: "foo",
@@ -84,7 +87,7 @@
"mybaseline.xml": nil,
})
- foo := ctx.ModuleForTests("foo", "android_common")
+ foo := ctx.ModuleForTests(t, "foo", "android_common")
sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx, foo.Output("lint.sbox.textproto"))
if !strings.Contains(*sboxProto.Commands[0].Command, "--baseline mybaseline.xml") {
@@ -101,6 +104,7 @@
}
func TestJavaLintBypassUpdatableChecks(t *testing.T) {
+ t.Parallel()
testCases := []struct {
name string
bp string
@@ -144,6 +148,7 @@
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
errorHandler := android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.error)
android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules).
ExtendWithErrorHandler(errorHandler).
@@ -153,6 +158,7 @@
}
func TestJavaLintStrictUpdatabilityLinting(t *testing.T) {
+ t.Parallel()
bp := `
java_library {
name: "foo",
@@ -187,7 +193,7 @@
result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules, fs.AddToFixture()).
RunTestWithBp(t, bp)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
strictUpdatabilityCheck := foo.Output("lint_strict_updatability_check.stamp")
if !strings.Contains(strictUpdatabilityCheck.RuleParams.Command,
"--disallowed_issues NewApi") {
@@ -250,7 +256,7 @@
})).
RunTestWithBp(t, thisBp)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
sboxProto := android.RuleBuilderSboxProtoForTests(t, result.TestContext, foo.Output("lint.sbox.textproto"))
if !strings.Contains(*sboxProto.Commands[0].Command, "/"+testCase.expected_file) {
t.Error("did not use full api database for case", testCase)
@@ -276,3 +282,50 @@
ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("Don't use --disable, --enable, or --check in the flags field, instead use the dedicated disabled_checks, warning_checks, error_checks, or fatal_checks fields")).
RunTestWithBp(t, bp)
}
+
+// b/358643466
+func TestNotTestViaDefault(t *testing.T) {
+ bp := `
+ java_defaults {
+ name: "mydefaults",
+ lint: {
+ test: false,
+ },
+ }
+ android_test {
+ name: "foo",
+ srcs: [
+ "a.java",
+ ],
+ min_sdk_version: "29",
+ sdk_version: "current",
+ defaults: ["mydefaults"],
+ }
+ android_test {
+ name: "foo2",
+ srcs: [
+ "a.java",
+ ],
+ min_sdk_version: "29",
+ sdk_version: "current",
+ }
+ `
+ result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, bp)
+ ctx := result.TestContext
+
+ foo := ctx.ModuleForTests(t, "foo", "android_common")
+ sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx, foo.Output("lint.sbox.textproto"))
+ command := *sboxProto.Commands[0].Command
+
+ if strings.Contains(command, "--test") {
+ t.Fatalf("Expected command to not contain --test")
+ }
+
+ foo2 := ctx.ModuleForTests(t, "foo2", "android_common")
+ sboxProto2 := android.RuleBuilderSboxProtoForTests(t, ctx, foo2.Output("lint.sbox.textproto"))
+ command2 := *sboxProto2.Commands[0].Command
+
+ if !strings.Contains(command2, "--test") {
+ t.Fatalf("Expected command to contain --test")
+ }
+}
diff --git a/java/metalava/main-config.xml b/java/metalava/main-config.xml
index c61196f..c2881ac 100644
--- a/java/metalava/main-config.xml
+++ b/java/metalava/main-config.xml
@@ -16,4 +16,20 @@
<config xmlns="http://www.google.com/tools/metalava/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.google.com/tools/metalava/config ../../../../tools/metalava/metalava/src/main/resources/schemas/config.xsd"/>
+ xsi:schemaLocation="http://www.google.com/tools/metalava/config ../../../../tools/metalava/metalava/src/main/resources/schemas/config.xsd">
+ <api-surfaces>
+ <!-- These are hard coded into java_sdk_library. -->
+ <api-surface name="public"/>
+ <api-surface name="system" extends="public"/>
+ <api-surface name="module-lib" extends="system"/>
+ <api-surface name="test" extends="system"/>
+ <api-surface name="system-server" extends="public"/>
+ <!-- This is used in java/core-libraries/Android.bp. -->
+ <api-surface name="core"/>
+ <!-- These are used in libcore, external/conscrypt and external/icu. -->
+ <api-surface name="core-platform" extends="public"/>
+ <api-surface name="core-platform-legacy" extends="public"/>
+ <api-surface name="core-platform-plus-public"/>
+ <api-surface name="intra-core" extends="public"/>
+ </api-surfaces>
+</config>
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index d09a02e..155afc6 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -15,6 +15,11 @@
package java
import (
+ "maps"
+ "slices"
+
+ "github.com/google/blueprint"
+
"android/soong/android"
"android/soong/dexpreopt"
)
@@ -29,12 +34,15 @@
// The tags used for the dependencies between the platform bootclasspath and any configured boot
// jars.
-var (
- platformBootclasspathArtBootJarDepTag = bootclasspathDependencyTag{name: "art-boot-jar"}
- platformBootclasspathBootJarDepTag = bootclasspathDependencyTag{name: "platform-boot-jar"}
- platformBootclasspathApexBootJarDepTag = bootclasspathDependencyTag{name: "apex-boot-jar"}
- platformBootclasspathImplLibDepTag = dependencyTag{name: "impl-lib-tag"}
-)
+type platformBootclasspathImplLibDepTagType struct {
+ blueprint.BaseDependencyTag
+}
+
+func (p platformBootclasspathImplLibDepTagType) ExcludeFromVisibilityEnforcement() {}
+
+var platformBootclasspathImplLibDepTag platformBootclasspathImplLibDepTagType
+
+var _ android.ExcludeFromVisibilityEnforcementTag = platformBootclasspathImplLibDepTag
type platformBootclasspathModule struct {
android.ModuleBase
@@ -48,6 +56,12 @@
// The apex:module pairs obtained from the fragments.
fragments []android.Module
+ // The map of apex to the fragments they contain.
+ apexNameToFragment map[string]android.Module
+
+ // The map of library modules in the bootclasspath to the fragments that contain them.
+ libraryToApex map[android.Module]string
+
// Path to the monolithic hiddenapi-flags.csv file.
hiddenAPIFlagsCSV android.OutputPath
@@ -89,26 +103,12 @@
b.hiddenAPIDepsMutator(ctx)
- if !dexpreopt.IsDex2oatNeeded(ctx) {
- return
+ if dexpreopt.IsDex2oatNeeded(ctx) {
+ // Add a dependency onto the dex2oat tool which is needed for creating the boot image. The
+ // path is retrieved from the dependency by GetGlobalSoongConfig(ctx).
+ dexpreopt.RegisterToolDeps(ctx)
}
- // Add a dependency onto the dex2oat tool which is needed for creating the boot image. The
- // path is retrieved from the dependency by GetGlobalSoongConfig(ctx).
- dexpreopt.RegisterToolDeps(ctx)
-}
-
-func (b *platformBootclasspathModule) hiddenAPIDepsMutator(ctx android.BottomUpMutatorContext) {
- if ctx.Config().DisableHiddenApiChecks() {
- return
- }
-
- // Add dependencies onto the stub lib modules.
- apiLevelToStubLibModules := hiddenAPIComputeMonolithicStubLibModules(ctx.Config())
- hiddenAPIAddStubLibDependencies(ctx, apiLevelToStubLibModules)
-}
-
-func (b *platformBootclasspathModule) BootclasspathDepsMutator(ctx android.BottomUpMutatorContext) {
// Add dependencies on all the ART jars.
global := dexpreopt.GetGlobalConfig(ctx)
addDependenciesOntoSelectedBootImageApexes(ctx, "com.android.art")
@@ -116,13 +116,13 @@
var bootImageModuleNames []string
// TODO: b/308174306 - Remove the mechanism of depending on the java_sdk_library(_import) directly
- addDependenciesOntoBootImageModules(ctx, global.ArtApexJars, platformBootclasspathArtBootJarDepTag)
+ addDependenciesOntoBootImageModules(ctx, global.ArtApexJars, artBootJar)
bootImageModuleNames = append(bootImageModuleNames, global.ArtApexJars.CopyOfJars()...)
// Add dependencies on all the non-updatable jars, which are on the platform or in non-updatable
// APEXes.
platformJars := b.platformJars(ctx)
- addDependenciesOntoBootImageModules(ctx, platformJars, platformBootclasspathBootJarDepTag)
+ addDependenciesOntoBootImageModules(ctx, platformJars, platformBootJar)
bootImageModuleNames = append(bootImageModuleNames, platformJars.CopyOfJars()...)
// Add dependencies on all the updatable jars, except the ART jars.
@@ -133,7 +133,7 @@
}
addDependenciesOntoSelectedBootImageApexes(ctx, android.FirstUniqueStrings(apexes)...)
// TODO: b/308174306 - Remove the mechanism of depending on the java_sdk_library(_import) directly
- addDependenciesOntoBootImageModules(ctx, apexJars, platformBootclasspathApexBootJarDepTag)
+ addDependenciesOntoBootImageModules(ctx, apexJars, apexBootJar)
bootImageModuleNames = append(bootImageModuleNames, apexJars.CopyOfJars()...)
// Add dependencies on all the fragments.
@@ -147,32 +147,42 @@
}
}
-func addDependenciesOntoBootImageModules(ctx android.BottomUpMutatorContext, modules android.ConfiguredJarList, tag bootclasspathDependencyTag) {
+func (b *platformBootclasspathModule) hiddenAPIDepsMutator(ctx android.BottomUpMutatorContext) {
+ if ctx.Config().DisableHiddenApiChecks() {
+ return
+ }
+
+ // Add dependencies onto the stub lib modules.
+ apiLevelToStubLibModules := hiddenAPIComputeMonolithicStubLibModules(ctx.Config())
+ hiddenAPIAddStubLibDependencies(ctx, apiLevelToStubLibModules)
+}
+
+func addDependenciesOntoBootImageModules(ctx android.BottomUpMutatorContext, modules android.ConfiguredJarList, tagType bootclasspathDependencyTagType) {
for i := 0; i < modules.Len(); i++ {
apex := modules.Apex(i)
name := modules.Jar(i)
- addDependencyOntoApexModulePair(ctx, apex, name, tag)
+ addDependencyOntoApexModulePair(ctx, apex, name, tagType)
}
}
func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// Gather all the dependencies from the art, platform, and apex boot jars.
- artModules := gatherApexModulePairDepsWithTag(ctx, platformBootclasspathArtBootJarDepTag)
- platformModules := gatherApexModulePairDepsWithTag(ctx, platformBootclasspathBootJarDepTag)
- apexModules := gatherApexModulePairDepsWithTag(ctx, platformBootclasspathApexBootJarDepTag)
+ artModules, artModulesToApex := gatherApexModulePairDepsWithTag(ctx, artBootJar)
+ platformModules, platformModulesToApex := gatherApexModulePairDepsWithTag(ctx, platformBootJar)
+ apexModules, apexModulesToApex := gatherApexModulePairDepsWithTag(ctx, apexBootJar)
// Concatenate them all, in order as they would appear on the bootclasspath.
- var allModules []android.Module
- allModules = append(allModules, artModules...)
- allModules = append(allModules, platformModules...)
- allModules = append(allModules, apexModules...)
+ allModules := slices.Concat(artModules, platformModules, apexModules)
b.configuredModules = allModules
+ b.libraryToApex = maps.Clone(artModulesToApex)
+ maps.Copy(b.libraryToApex, platformModulesToApex)
+ maps.Copy(b.libraryToApex, apexModulesToApex)
// Do not add implLibModule to allModules as the impl lib is only used to collect the
// transitive source files
var implLibModule []android.Module
- ctx.VisitDirectDepsWithTag(implLibraryTag, func(m android.Module) {
+ ctx.VisitDirectDepsWithTag(platformBootclasspathImplLibDepTag, func(m android.Module) {
implLibModule = append(implLibModule, m)
})
@@ -188,7 +198,7 @@
TransformResourcesToJar(ctx, srcjar, jarArgs, transitiveSrcFiles)
// Gather all the fragments dependencies.
- b.fragments = gatherApexModulePairDepsWithTag(ctx, bootclasspathFragmentDepTag)
+ b.fragments, b.apexNameToFragment = gatherFragments(ctx)
// Check the configuration of the boot modules.
// ART modules are checked by the art-bootclasspath-fragment.
@@ -197,7 +207,7 @@
b.generateClasspathProtoBuildActions(ctx)
- bootDexJarByModule := b.generateHiddenAPIBuildActions(ctx, b.configuredModules, b.fragments)
+ bootDexJarByModule := b.generateHiddenAPIBuildActions(ctx, b.configuredModules, b.fragments, b.libraryToApex, b.apexNameToFragment)
buildRuleForBootJarsPackageCheck(ctx, bootDexJarByModule)
ctx.SetOutputFiles(android.Paths{b.hiddenAPIFlagsCSV}, "hiddenapi-flags.csv")
@@ -248,7 +258,7 @@
fromUpdatableApex := apexInfo.Updatable
if fromUpdatableApex {
// error: this jar is part of an updatable apex
- ctx.ModuleErrorf("module %q from updatable apexes %q is not allowed in the platform bootclasspath", ctx.OtherModuleName(m), apexInfo.InApexVariants)
+ ctx.ModuleErrorf("module %q from updatable apex %q is not allowed in the platform bootclasspath", ctx.OtherModuleName(m), apexInfo.BaseApexName)
} else {
// ok: this jar is part of the platform or a non-updatable apex
}
@@ -272,7 +282,11 @@
// modules is complete.
if !ctx.Config().AlwaysUsePrebuiltSdks() {
// error: this jar is part of the platform
- ctx.ModuleErrorf("module %q from platform is not allowed in the apex boot jars list", name)
+ if ctx.Config().AllowMissingDependencies() {
+ ctx.AddMissingDependencies([]string{"module_" + name + "_from_platform_is_not_allowed_in_the_apex_boot_jars_list"})
+ } else {
+ ctx.ModuleErrorf("module %q from platform is not allowed in the apex boot jars list", name)
+ }
}
} else {
// TODO(b/177892522): Treat this as an error.
@@ -284,7 +298,8 @@
}
// generateHiddenAPIBuildActions generates all the hidden API related build rules.
-func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, modules []android.Module, fragments []android.Module) bootDexJarByModule {
+func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, modules []android.Module,
+ fragments []android.Module, libraryToApex map[android.Module]string, apexNameToFragment map[string]android.Module) bootDexJarByModule {
createEmptyHiddenApiFiles := func() {
paths := android.OutputPaths{b.hiddenAPIFlagsCSV, b.hiddenAPIIndexCSV, b.hiddenAPIMetadataCSV}
for _, path := range paths {
@@ -311,7 +326,7 @@
}
// Construct a list of ClasspathElement objects from the modules and fragments.
- classpathElements := CreateClasspathElements(ctx, modules, fragments)
+ classpathElements := CreateClasspathElements(ctx, modules, fragments, libraryToApex, apexNameToFragment)
monolithicInfo := b.createAndProvideMonolithicHiddenAPIInfo(ctx, classpathElements)
diff --git a/java/platform_bootclasspath_test.go b/java/platform_bootclasspath_test.go
index 7fa6ddb..727e306 100644
--- a/java/platform_bootclasspath_test.go
+++ b/java/platform_bootclasspath_test.go
@@ -27,21 +27,27 @@
)
func TestPlatformBootclasspath(t *testing.T) {
+ t.Parallel()
preparer := android.GroupFixturePreparers(
prepareForTestWithPlatformBootclasspath,
FixtureConfigureBootJars("platform:foo", "system_ext:bar"),
+ android.FixtureMergeMockFs(android.MockFS{
+ "api/current.txt": nil,
+ "api/removed.txt": nil,
+ }),
android.FixtureWithRootAndroidBp(`
platform_bootclasspath {
name: "platform-bootclasspath",
}
- java_library {
+ java_sdk_library {
name: "bar",
srcs: ["a.java"],
system_modules: "none",
sdk_version: "none",
compile_dex: true,
system_ext_specific: true,
+ unsafe_ignore_missing_latest_api: true,
}
`),
)
@@ -76,6 +82,7 @@
`)
t.Run("missing", func(t *testing.T) {
+ t.Parallel()
preparer.
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`"platform-bootclasspath" depends on undefined module "foo"`)).
RunTest(t)
@@ -86,11 +93,12 @@
checkSrcJarInputs := func(t *testing.T, result *android.TestResult, name string, expected []string) {
t.Helper()
- srcjar := result.ModuleForTests(name, "android_common").Output(name + "-transitive.srcjar")
+ srcjar := result.ModuleForTests(t, name, "android_common").Output(name + "-transitive.srcjar")
android.AssertStringDoesContain(t, "srcjar arg", srcjar.Args["jarArgs"], "-srcjar")
android.AssertArrayString(t, "srcjar inputs", expected, srcjar.Implicits.Strings())
}
t.Run("source", func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
preparer,
addSourceBootclassPathModule,
@@ -107,6 +115,7 @@
})
t.Run("prebuilt", func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
preparer,
addPrebuiltBootclassPathModule,
@@ -123,6 +132,7 @@
})
t.Run("source+prebuilt - source preferred", func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
preparer,
addSourceBootclassPathModule,
@@ -140,6 +150,7 @@
})
t.Run("source+prebuilt - prebuilt preferred", func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
preparer,
addSourceBootclassPathModule,
@@ -157,6 +168,7 @@
})
t.Run("dex import", func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
preparer,
android.FixtureAddTextFile("deximport/Android.bp", `
@@ -179,6 +191,7 @@
}
func TestPlatformBootclasspathVariant(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForTestWithPlatformBootclasspath,
android.FixtureWithRootAndroidBp(`
@@ -193,6 +206,7 @@
}
func TestPlatformBootclasspath_ClasspathFragmentPaths(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForTestWithPlatformBootclasspath,
android.FixtureWithRootAndroidBp(`
@@ -204,10 +218,11 @@
p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule)
android.AssertStringEquals(t, "output filepath", "bootclasspath.pb", p.ClasspathFragmentBase.outputFilepath.Base())
- android.AssertPathRelativeToTopEquals(t, "install filepath", "out/soong/target/product/test_device/system/etc/classpaths", p.ClasspathFragmentBase.installDirPath)
+ android.AssertPathRelativeToTopEquals(t, "install filepath", "out/target/product/test_device/system/etc/classpaths", p.ClasspathFragmentBase.installDirPath)
}
func TestPlatformBootclasspathModule_AndroidMkEntries(t *testing.T) {
+ t.Parallel()
preparer := android.GroupFixturePreparers(
prepareForTestWithPlatformBootclasspath,
android.FixtureWithRootAndroidBp(`
@@ -218,6 +233,7 @@
)
t.Run("AndroidMkEntries", func(t *testing.T) {
+ t.Parallel()
result := preparer.RunTest(t)
p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule)
@@ -227,6 +243,7 @@
})
t.Run("hiddenapi-flags-entry", func(t *testing.T) {
+ t.Parallel()
result := preparer.RunTest(t)
p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule)
@@ -238,6 +255,7 @@
})
t.Run("classpath-fragment-entry", func(t *testing.T) {
+ t.Parallel()
result := preparer.RunTest(t)
want := map[string][]string{
@@ -262,6 +280,7 @@
}
func TestPlatformBootclasspath_Dist(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForTestWithPlatformBootclasspath,
FixtureConfigureBootJars("platform:foo", "platform:bar"),
@@ -305,6 +324,7 @@
}
func TestPlatformBootclasspath_HiddenAPIMonolithicFiles(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
hiddenApiFixtureFactory,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -347,7 +367,7 @@
// Make sure that the foo-hiddenapi-annotations.jar is included in the inputs to the rules that
// creates the index.csv file.
- platformBootclasspath := result.ModuleForTests("myplatform-bootclasspath", "android_common")
+ platformBootclasspath := result.ModuleForTests(t, "myplatform-bootclasspath", "android_common")
var rule android.TestingBuildParams
diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go
index 5b145c6..d2ec8bd 100644
--- a/java/platform_compat_config.go
+++ b/java/platform_compat_config.go
@@ -43,6 +43,13 @@
ctx.RegisterModuleType("global_compat_config", globalCompatConfigFactory)
}
+type PlatformCompatConfigInfo struct {
+ CompatConfig android.OutputPath
+ SubDir string
+}
+
+var PlatformCompatConfigInfoProvider = blueprint.NewProvider[PlatformCompatConfigInfo]()
+
var PrepareForTestWithPlatformCompatConfig = android.FixtureRegisterWithContext(registerPlatformCompatConfigBuildComponents)
func platformCompatConfigPath(ctx android.PathContext) android.OutputPath {
@@ -51,6 +58,10 @@
type platformCompatConfigProperties struct {
Src *string `android:"path"`
+
+ // If true, we include it in the "merged" XML (merged_compat_config.xml).
+ // Default is true.
+ Include_in_merged_xml *bool
}
type platformCompatConfig struct {
@@ -60,6 +71,7 @@
installDirPath android.InstallPath
configFile android.OutputPath
metadataFile android.OutputPath
+ doMerge bool
installConfigFile android.InstallPath
}
@@ -68,6 +80,10 @@
return p.metadataFile
}
+func (p *platformCompatConfig) includeInMergedXml() bool {
+ return p.doMerge
+}
+
func (p *platformCompatConfig) CompatConfig() android.OutputPath {
return p.configFile
}
@@ -78,8 +94,19 @@
type platformCompatConfigMetadataProvider interface {
compatConfigMetadata() android.Path
+
+ // Whether to include it in the "merged" XML (merged_compat_config.xml) or not.
+ includeInMergedXml() bool
}
+type PlatformCompatConfigMetadataInfo struct {
+ CompatConfigMetadata android.Path
+ // Whether to include it in the "merged" XML (merged_compat_config.xml) or not.
+ IncludeInMergedXml bool
+}
+
+var PlatformCompatConfigMetadataInfoProvider = blueprint.NewProvider[PlatformCompatConfigMetadataInfo]()
+
type PlatformCompatConfigIntf interface {
android.Module
@@ -98,6 +125,7 @@
metadataFileName := p.Name() + "_meta.xml"
p.configFile = android.PathForModuleOut(ctx, configFileName).OutputPath
p.metadataFile = android.PathForModuleOut(ctx, metadataFileName).OutputPath
+ p.doMerge = proptools.BoolDefault(p.properties.Include_in_merged_xml, true)
path := android.PathForModuleSrc(ctx, String(p.properties.Src))
rule.Command().
@@ -111,6 +139,16 @@
rule.Build(configFileName, "Extract compat/compat_config.xml and install it")
ctx.InstallFile(p.installDirPath, p.configFile.Base(), p.configFile)
ctx.SetOutputFiles(android.Paths{p.configFile}, "")
+
+ android.SetProvider(ctx, PlatformCompatConfigInfoProvider, PlatformCompatConfigInfo{
+ CompatConfig: p.CompatConfig(),
+ SubDir: p.SubDir(),
+ })
+
+ android.SetProvider(ctx, PlatformCompatConfigMetadataInfoProvider, PlatformCompatConfigMetadataInfo{
+ CompatConfigMetadata: p.compatConfigMetadata(),
+ IncludeInMergedXml: p.includeInMergedXml(),
+ })
}
func (p *platformCompatConfig) AndroidMkEntries() []android.AndroidMkEntries {
@@ -201,6 +239,10 @@
return module.metadataFile
}
+func (module *prebuiltCompatConfigModule) includeInMergedXml() bool {
+ return true // Always include in merged.xml
+}
+
func (module *prebuiltCompatConfigModule) BaseModuleName() string {
return proptools.StringDefault(module.properties.Source_module_name, module.ModuleBase.Name())
}
@@ -209,6 +251,11 @@
func (module *prebuiltCompatConfigModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
module.metadataFile = module.prebuilt.SingleSourcePath(ctx)
+
+ android.SetProvider(ctx, PlatformCompatConfigMetadataInfoProvider, PlatformCompatConfigMetadataInfo{
+ CompatConfigMetadata: module.compatConfigMetadata(),
+ IncludeInMergedXml: module.includeInMergedXml(),
+ })
}
// A prebuilt version of platform_compat_config that provides the metadata.
@@ -229,15 +276,18 @@
var compatConfigMetadata android.Paths
- ctx.VisitAllModules(func(module android.Module) {
- if !module.Enabled(ctx) {
+ ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
+ if !android.OtherModulePointerProviderOrDefault(ctx, module, android.CommonModuleInfoProvider).Enabled {
return
}
- if c, ok := module.(platformCompatConfigMetadataProvider); ok {
- if !android.IsModulePreferred(module) {
+ if c, ok := android.OtherModuleProvider(ctx, module, PlatformCompatConfigMetadataInfoProvider); ok {
+ if !android.IsModulePreferredProxy(ctx, module) {
return
}
- metadata := c.compatConfigMetadata()
+ if !c.IncludeInMergedXml {
+ return
+ }
+ metadata := c.CompatConfigMetadata
compatConfigMetadata = append(compatConfigMetadata, metadata)
}
})
@@ -258,12 +308,7 @@
rule.Build("merged-compat-config", "Merge compat config")
p.metadata = outputPath
-}
-
-func (p *platformCompatConfigSingleton) MakeVars(ctx android.MakeVarsContext) {
- if p.metadata != nil {
- ctx.DistForGoal("droidcore", p.metadata)
- }
+ ctx.DistForGoal("droidcore", p.metadata)
}
func platformCompatConfigSingletonFactory() android.Singleton {
diff --git a/java/platform_compat_config_test.go b/java/platform_compat_config_test.go
index 80d991c..72f81e0 100644
--- a/java/platform_compat_config_test.go
+++ b/java/platform_compat_config_test.go
@@ -21,11 +21,13 @@
)
func TestPlatformCompatConfig(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithPlatformCompatConfig,
android.FixtureWithRootAndroidBp(`
platform_compat_config {
name: "myconfig2",
+ include_in_merged_xml: false,
}
platform_compat_config {
name: "myconfig1",
@@ -38,7 +40,6 @@
CheckMergedCompatConfigInputs(t, result, "myconfig",
"out/soong/.intermediates/myconfig1/myconfig1_meta.xml",
- "out/soong/.intermediates/myconfig2/myconfig2_meta.xml",
"out/soong/.intermediates/myconfig3/myconfig3_meta.xml",
)
}
diff --git a/java/plugin.go b/java/plugin.go
index 610c9fd..3534c7b 100644
--- a/java/plugin.go
+++ b/java/plugin.go
@@ -16,8 +16,21 @@
import (
"android/soong/android"
+ "github.com/google/blueprint"
)
+type JavaPluginInfo struct {
+ ProcessorClass *string
+ GeneratesApi bool
+}
+
+var JavaPluginInfoProvider = blueprint.NewProvider[JavaPluginInfo]()
+
+type KotlinPluginInfo struct {
+}
+
+var KotlinPluginInfoProvider = blueprint.NewProvider[KotlinPluginInfo]()
+
func init() {
registerJavaPluginBuildComponents(android.InitRegistrationContext)
}
@@ -65,7 +78,22 @@
Generates_api *bool
}
+func (p *Plugin) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ p.Library.GenerateAndroidBuildActions(ctx)
+
+ android.SetProvider(ctx, JavaPluginInfoProvider, JavaPluginInfo{
+ ProcessorClass: p.pluginProperties.Processor_class,
+ GeneratesApi: Bool(p.pluginProperties.Generates_api),
+ })
+}
+
// Plugin describes a kotlin_plugin module, a host java/kotlin library that will be used by kotlinc as a compiler plugin.
type KotlinPlugin struct {
Library
}
+
+func (p *KotlinPlugin) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ p.Library.GenerateAndroidBuildActions(ctx)
+
+ android.SetProvider(ctx, KotlinPluginInfoProvider, KotlinPluginInfo{})
+}
diff --git a/java/plugin_test.go b/java/plugin_test.go
index dc29b1c..007b74a 100644
--- a/java/plugin_test.go
+++ b/java/plugin_test.go
@@ -19,6 +19,7 @@
)
func TestNoPlugin(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -26,8 +27,8 @@
}
`)
- javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
- turbine := ctx.ModuleForTests("foo", "android_common").MaybeRule("turbine")
+ javac := ctx.ModuleForTests(t, "foo", "android_common").Rule("javac")
+ turbine := ctx.ModuleForTests(t, "foo", "android_common").MaybeRule("turbine")
if turbine.Rule == nil {
t.Errorf("expected turbine to be enabled")
@@ -43,6 +44,7 @@
}
func TestPlugin(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -59,14 +61,14 @@
buildOS := ctx.Config().BuildOS.String()
- javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
- turbine := ctx.ModuleForTests("foo", "android_common").MaybeRule("turbine")
+ javac := ctx.ModuleForTests(t, "foo", "android_common").Rule("javac")
+ turbine := ctx.ModuleForTests(t, "foo", "android_common").MaybeRule("turbine")
if turbine.Rule == nil {
t.Errorf("expected turbine to be enabled")
}
- bar := ctx.ModuleForTests("bar", buildOS+"_common").Rule("javac").Output.String()
+ bar := ctx.ModuleForTests(t, "bar", buildOS+"_common").Rule("javac").Output.String()
if !inList(bar, javac.Implicits.Strings()) {
t.Errorf("foo implicits %v does not contain %q", javac.Implicits.Strings(), bar)
@@ -82,6 +84,7 @@
}
func TestPluginGeneratesApi(t *testing.T) {
+ t.Parallel()
ctx, _ := testJava(t, `
java_library {
name: "foo",
@@ -99,14 +102,14 @@
buildOS := ctx.Config().BuildOS.String()
- javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
- turbine := ctx.ModuleForTests("foo", "android_common").MaybeRule("turbine")
+ javac := ctx.ModuleForTests(t, "foo", "android_common").Rule("javac")
+ turbine := ctx.ModuleForTests(t, "foo", "android_common").MaybeRule("turbine")
if turbine.Rule != nil {
t.Errorf("expected turbine to be disabled")
}
- bar := ctx.ModuleForTests("bar", buildOS+"_common").Rule("javac").Output.String()
+ bar := ctx.ModuleForTests(t, "bar", buildOS+"_common").Rule("javac").Output.String()
if !inList(bar, javac.Implicits.Strings()) {
t.Errorf("foo implicits %v does not contain %q", javac.Implicits.Strings(), bar)
diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go
index 527e479..31f149e 100644
--- a/java/prebuilt_apis.go
+++ b/java/prebuilt_apis.go
@@ -55,11 +55,6 @@
// If set to true, compile dex for java_import modules. Defaults to false.
Imports_compile_dex *bool
-
- // If set to true, allow incremental platform API of the form MM.m where MM is the major release
- // version corresponding to the API level/SDK_INT and m is an incremental release version
- // (e.g. API changes associated with QPR). Defaults to false.
- Allow_incremental_platform_api *bool
}
type prebuiltApis struct {
@@ -97,28 +92,28 @@
}
// parseFinalizedPrebuiltPath is like parsePrebuiltPath, but verifies the version is numeric (a finalized version).
-func parseFinalizedPrebuiltPath(ctx android.LoadHookContext, p string, allowIncremental bool) (module string, version int, release int, scope string) {
+func parseFinalizedPrebuiltPath(ctx android.LoadHookContext, p string) (module string, version int, release int, scope string) {
module, v, scope := parsePrebuiltPath(ctx, p)
- if allowIncremental {
- parts := strings.Split(v, ".")
- if len(parts) != 2 {
- ctx.ModuleErrorf("Found unexpected version '%v' for incremental prebuilts - expect MM.m format for incremental API with both major (MM) an minor (m) revision.", v)
- return
- }
+
+ // assume a major.minor version code
+ parts := strings.Split(v, ".")
+ if len(parts) == 2 {
sdk, sdk_err := strconv.Atoi(parts[0])
qpr, qpr_err := strconv.Atoi(parts[1])
if sdk_err != nil || qpr_err != nil {
- ctx.ModuleErrorf("Unable to read version number for incremental prebuilt api '%v'", v)
+ ctx.ModuleErrorf("Unable to read major.minor version for prebuilt api '%v'", v)
return
}
version = sdk
release = qpr
return
}
+
+ // assume a legacy integer only api level
release = 0
version, err := strconv.Atoi(v)
if err != nil {
- ctx.ModuleErrorf("Found finalized API files in non-numeric dir '%v'", v)
+ ctx.ModuleErrorf("Unable to read API level for prebuilt api '%v'", v)
return
}
return
@@ -279,12 +274,11 @@
}
// Create modules for all (<module>, <scope, <version>) triplets,
- allowIncremental := proptools.BoolDefault(p.properties.Allow_incremental_platform_api, false)
for _, f := range apiLevelFiles {
- module, version, release, scope := parseFinalizedPrebuiltPath(mctx, f, allowIncremental)
- if allowIncremental {
- incrementalVersion := strconv.Itoa(version) + "." + strconv.Itoa(release)
- createApiModule(mctx, PrebuiltApiModuleName(module, scope, incrementalVersion), f)
+ module, version, release, scope := parseFinalizedPrebuiltPath(mctx, f)
+ if release != 0 {
+ majorDotMinorVersion := strconv.Itoa(version) + "." + strconv.Itoa(release)
+ createApiModule(mctx, PrebuiltApiModuleName(module, scope, majorDotMinorVersion), f)
} else {
createApiModule(mctx, PrebuiltApiModuleName(module, scope, strconv.Itoa(version)), f)
}
@@ -300,7 +294,7 @@
getLatest := func(files []string, isExtensionApiFile bool) map[string]latestApiInfo {
m := make(map[string]latestApiInfo)
for _, f := range files {
- module, version, release, scope := parseFinalizedPrebuiltPath(mctx, f, allowIncremental)
+ module, version, release, scope := parseFinalizedPrebuiltPath(mctx, f)
if strings.HasSuffix(module, "incompatibilities") {
continue
}
diff --git a/java/prebuilt_apis_test.go b/java/prebuilt_apis_test.go
index b6fb2c6..17fdae9 100644
--- a/java/prebuilt_apis_test.go
+++ b/java/prebuilt_apis_test.go
@@ -29,6 +29,7 @@
}
func TestPrebuiltApis_SystemModulesCreation(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
FixtureWithPrebuiltApis(map[string][]string{
@@ -61,6 +62,7 @@
}
func TestPrebuiltApis_WithExtensions(t *testing.T) {
+ t.Parallel()
runTestWithBaseExtensionLevel := func(v int) (foo_input, bar_input, baz_input string) {
result := android.GroupFixturePreparers(
prepareForJavaTest,
@@ -76,9 +78,9 @@
"2": {"foo", "bar"},
}),
).RunTest(t)
- foo_input = result.ModuleForTests("foo.api.public.latest", "").Rule("generator").Implicits[0].String()
- bar_input = result.ModuleForTests("bar.api.public.latest", "").Rule("generator").Implicits[0].String()
- baz_input = result.ModuleForTests("baz.api.public.latest", "").Rule("generator").Implicits[0].String()
+ foo_input = result.ModuleForTests(t, "foo.api.public.latest", "").Rule("generator").Implicits[0].String()
+ bar_input = result.ModuleForTests(t, "bar.api.public.latest", "").Rule("generator").Implicits[0].String()
+ baz_input = result.ModuleForTests(t, "baz.api.public.latest", "").Rule("generator").Implicits[0].String()
return
}
// Extension 2 is the latest for both foo and bar, finalized after the base extension version.
@@ -100,25 +102,26 @@
android.AssertStringEquals(t, "Expected latest baz = api level 32", "prebuilts/sdk/32/public/api/baz.txt", baz_input)
}
-func TestPrebuiltApis_WithIncrementalApi(t *testing.T) {
+func TestPrebuiltApis_WithMixedVersionCodes(t *testing.T) {
+ t.Parallel()
runTestWithIncrementalApi := func() (foo_input, bar_input, baz_input string) {
result := android.GroupFixturePreparers(
prepareForJavaTest,
- FixtureWithPrebuiltIncrementalApis(map[string][]string{
+ FixtureWithPrebuiltApis(map[string][]string{
"33.0": {"foo"},
- "33.1": {"foo", "bar", "baz"},
- "33.2": {"foo", "bar"},
+ "34": {"foo", "bar", "baz"},
+ "34.1": {"foo", "bar"},
"current": {"foo", "bar"},
}),
).RunTest(t)
- foo_input = result.ModuleForTests("foo.api.public.latest", "").Rule("generator").Implicits[0].String()
- bar_input = result.ModuleForTests("bar.api.public.latest", "").Rule("generator").Implicits[0].String()
- baz_input = result.ModuleForTests("baz.api.public.latest", "").Rule("generator").Implicits[0].String()
+ foo_input = result.ModuleForTests(t, "foo.api.public.latest", "").Rule("generator").Implicits[0].String()
+ bar_input = result.ModuleForTests(t, "bar.api.public.latest", "").Rule("generator").Implicits[0].String()
+ baz_input = result.ModuleForTests(t, "baz.api.public.latest", "").Rule("generator").Implicits[0].String()
return
}
- // 33.1 is the latest for baz, 33.2 is the latest for both foo & bar
+ // 34 is the latest for baz, 34.1 is the latest for both foo & bar
foo_input, bar_input, baz_input := runTestWithIncrementalApi()
- android.AssertStringEquals(t, "Expected latest foo = api level 33.2", "prebuilts/sdk/33.2/public/api/foo.txt", foo_input)
- android.AssertStringEquals(t, "Expected latest bar = api level 33.2", "prebuilts/sdk/33.2/public/api/bar.txt", bar_input)
- android.AssertStringEquals(t, "Expected latest baz = api level 33.1", "prebuilts/sdk/33.1/public/api/baz.txt", baz_input)
+ android.AssertStringEquals(t, "Expected latest foo = api level 34.1", "prebuilts/sdk/34.1/public/api/foo.txt", foo_input)
+ android.AssertStringEquals(t, "Expected latest bar = api level 34.1", "prebuilts/sdk/34.1/public/api/bar.txt", bar_input)
+ android.AssertStringEquals(t, "Expected latest baz = api level 34", "prebuilts/sdk/34/public/api/baz.txt", baz_input)
}
diff --git a/java/proto_test.go b/java/proto_test.go
index d1cb714..3fbe3e6 100644
--- a/java/proto_test.go
+++ b/java/proto_test.go
@@ -28,6 +28,7 @@
`
func TestProtoStream(t *testing.T) {
+ t.Parallel()
bp := `
java_library {
name: "java-stream-protos",
@@ -45,7 +46,7 @@
PrepareForIntegrationTestWithJava,
).RunTestWithBp(t, protoModules+bp)
- proto0 := ctx.ModuleForTests("java-stream-protos", "android_common").Output("proto/proto0.srcjar")
+ proto0 := ctx.ModuleForTests(t, "java-stream-protos", "android_common").Output("proto/proto0.srcjar")
if cmd := proto0.RuleParams.Command; !strings.Contains(cmd, "--javastream_out=") {
t.Errorf("expected '--javastream_out' in %q", cmd)
diff --git a/java/ravenwood.go b/java/ravenwood.go
index 4c43a9f..a942dc6 100644
--- a/java/ravenwood.go
+++ b/java/ravenwood.go
@@ -110,13 +110,15 @@
module.AddProperties(&module.testProperties, &module.ravenwoodTestProperties)
module.Module.dexpreopter.isTest = true
- module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
+ module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
module.testProperties.Test_suites = []string{
"general-tests",
"ravenwood-tests",
}
module.testProperties.Test_options.Unit_test = proptools.BoolPtr(false)
+ module.Module.sourceProperties.Test_only = proptools.BoolPtr(true)
+ module.Module.sourceProperties.Top_level_test_target = true
InitJavaModule(module, android.DeviceSupported)
android.InitDefaultableModule(module)
@@ -185,26 +187,24 @@
// All JNI libraries included in the runtime
var runtimeJniModuleNames map[string]bool
- if utils := ctx.GetDirectDepsWithTag(ravenwoodUtilsTag)[0]; utils != nil {
- for _, installFile := range android.OtherModuleProviderOrDefault(
- ctx, utils, android.InstallFilesProvider).InstallFiles {
- installDeps = append(installDeps, installFile)
- }
- jniDeps, ok := android.OtherModuleProvider(ctx, utils, ravenwoodLibgroupJniDepProvider)
- if ok {
- runtimeJniModuleNames = jniDeps.names
- }
+ utils := ctx.GetDirectDepsProxyWithTag(ravenwoodUtilsTag)[0]
+ for _, installFile := range android.OtherModuleProviderOrDefault(
+ ctx, utils, android.InstallFilesProvider).InstallFiles {
+ installDeps = append(installDeps, installFile)
+ }
+ jniDeps, ok := android.OtherModuleProvider(ctx, utils, ravenwoodLibgroupJniDepProvider)
+ if ok {
+ runtimeJniModuleNames = jniDeps.names
}
- if runtime := ctx.GetDirectDepsWithTag(ravenwoodRuntimeTag)[0]; runtime != nil {
- for _, installFile := range android.OtherModuleProviderOrDefault(
- ctx, runtime, android.InstallFilesProvider).InstallFiles {
- installDeps = append(installDeps, installFile)
- }
- jniDeps, ok := android.OtherModuleProvider(ctx, runtime, ravenwoodLibgroupJniDepProvider)
- if ok {
- runtimeJniModuleNames = jniDeps.names
- }
+ runtime := ctx.GetDirectDepsProxyWithTag(ravenwoodRuntimeTag)[0]
+ for _, installFile := range android.OtherModuleProviderOrDefault(
+ ctx, runtime, android.InstallFilesProvider).InstallFiles {
+ installDeps = append(installDeps, installFile)
+ }
+ jniDeps, ok = android.OtherModuleProvider(ctx, runtime, ravenwoodLibgroupJniDepProvider)
+ if ok {
+ runtimeJniModuleNames = jniDeps.names
}
// Also remember what JNI libs are in the runtime.
@@ -228,7 +228,7 @@
resApkInstallPath := installPath.Join(ctx, "ravenwood-res-apks")
copyResApk := func(tag blueprint.DependencyTag, toFileName string) {
- if resApk := ctx.GetDirectDepsWithTag(tag); len(resApk) > 0 {
+ if resApk := ctx.GetDirectDepsProxyWithTag(tag); len(resApk) > 0 {
installFile := android.OutputFileForModule(ctx, resApk[0], "")
installResApk := ctx.InstallFile(resApkInstallPath, toFileName, installFile)
installDeps = append(installDeps, installResApk)
@@ -260,6 +260,19 @@
// Install our JAR with all dependencies
ctx.InstallFile(installPath, ctx.ModuleName()+".jar", r.outputFile, installDeps...)
+
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ if _, ok := r.testConfig.(android.WritablePath); ok {
+ moduleInfoJSON.AutoTestConfig = []string{"true"}
+ }
+ if r.testConfig != nil {
+ moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, r.testConfig.String())
+ }
+ moduleInfoJSON.CompatibilitySuites = []string{"general-tests", "ravenwood-tests"}
+
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: r.TestSuites(),
+ })
}
func (r *ravenwoodTest) AndroidMkEntries() []android.AndroidMkEntries {
@@ -345,7 +358,7 @@
// Install our runtime into expected location for packaging
installPath := android.PathForModuleInstall(ctx, r.BaseModuleName())
for _, lib := range r.ravenwoodLibgroupProperties.Libs {
- libModule := ctx.GetDirectDepWithTag(lib, ravenwoodLibContentTag)
+ libModule := ctx.GetDirectDepProxyWithTag(lib, ravenwoodLibContentTag)
if libModule == nil {
if ctx.Config().AllowMissingDependencies() {
ctx.AddMissingDependencies([]string{lib})
@@ -377,6 +390,10 @@
// Normal build should perform install steps
ctx.Phony(r.BaseModuleName(), android.PathForPhony(ctx, r.BaseModuleName()+"-install"))
+
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: r.TestSuites(),
+ })
}
// collectTransitiveJniDeps returns all JNI dependencies, including transitive
diff --git a/java/ravenwood_test.go b/java/ravenwood_test.go
index 6394a9a..d6493bc 100644
--- a/java/ravenwood_test.go
+++ b/java/ravenwood_test.go
@@ -100,9 +100,10 @@
`),
)
-var installPathPrefix = "out/soong/host/linux-x86/testcases"
+var installPathPrefix = "out/host/linux-x86/testcases"
func TestRavenwoodRuntime(t *testing.T) {
+ t.Parallel()
if runtime.GOOS != "linux" {
t.Skip("requires linux")
}
@@ -120,7 +121,7 @@
CheckModuleHasDependency(t, ctx.TestContext, "ravenwood-utils", "android_common", "framework-rules.ravenwood")
// Verify that we've emitted artifacts in expected location
- runtime := ctx.ModuleForTests("ravenwood-runtime", "android_common")
+ runtime := ctx.ModuleForTests(t, "ravenwood-runtime", "android_common")
runtime.Output(installPathPrefix + "/ravenwood-runtime/framework-minus-apex.ravenwood.jar")
runtime.Output(installPathPrefix + "/ravenwood-runtime/framework-services.ravenwood.jar")
runtime.Output(installPathPrefix + "/ravenwood-runtime/lib64/ravenwood-runtime-jni1.so")
@@ -128,11 +129,12 @@
runtime.Output(installPathPrefix + "/ravenwood-runtime/lib64/ravenwood-runtime-jni3.so")
runtime.Output(installPathPrefix + "/ravenwood-runtime/ravenwood-data/app1.apk")
runtime.Output(installPathPrefix + "/ravenwood-runtime/fonts/Font.ttf")
- utils := ctx.ModuleForTests("ravenwood-utils", "android_common")
+ utils := ctx.ModuleForTests(t, "ravenwood-utils", "android_common")
utils.Output(installPathPrefix + "/ravenwood-utils/framework-rules.ravenwood.jar")
}
func TestRavenwoodTest(t *testing.T) {
+ t.Parallel()
if runtime.GOOS != "linux" {
t.Skip("requires linux")
}
@@ -191,7 +193,7 @@
CheckModuleHasDependency(t, ctx.TestContext, "ravenwood-test", "android_common", "ravenwood-utils")
CheckModuleHasDependency(t, ctx.TestContext, "ravenwood-test", "android_common", "jni-lib")
- module := ctx.ModuleForTests("ravenwood-test", "android_common")
+ module := ctx.ModuleForTests(t, "ravenwood-test", "android_common")
classpath := module.Rule("javac").Args["classpath"]
// Verify that we're linking against test_current
@@ -212,7 +214,7 @@
module.Output(installPathPrefix + "/ravenwood-test/ravenwood-res-apks/ravenwood-res.apk")
module.Output(installPathPrefix + "/ravenwood-test/ravenwood-res-apks/ravenwood-inst-res.apk")
- module = ctx.ModuleForTests("ravenwood-test-empty", "android_common")
+ module = ctx.ModuleForTests(t, "ravenwood-test-empty", "android_common")
module.Output(installPathPrefix + "/ravenwood-test-empty/ravenwood.properties")
// ravenwood-runtime*.so are included in the runtime, so it shouldn't be emitted.
@@ -228,4 +230,15 @@
android.AssertStringListContains(t, "orderOnly", orderOnly, installPathPrefix+"/ravenwood-runtime/lib64/libred.so")
android.AssertStringListContains(t, "orderOnly", orderOnly, installPathPrefix+"/ravenwood-runtime/lib64/ravenwood-runtime-jni3.so")
android.AssertStringListContains(t, "orderOnly", orderOnly, installPathPrefix+"/ravenwood-utils/framework-rules.ravenwood.jar")
+
+ // Ensure they are listed as "test" modules for code coverage
+ expectedTestOnlyModules := []string{
+ "ravenwood-test",
+ "ravenwood-test-empty",
+ }
+ expectedTopLevelTests := []string{
+ "ravenwood-test",
+ "ravenwood-test-empty",
+ }
+ assertTestOnlyAndTopLevel(t, ctx, expectedTestOnlyModules, expectedTopLevelTests)
}
diff --git a/java/robolectric.go b/java/robolectric.go
index 5f46267..1d204a4 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -21,6 +21,7 @@
"android/soong/java/config"
"android/soong/tradefed"
+ "github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -28,6 +29,23 @@
RegisterRobolectricBuildComponents(android.InitRegistrationContext)
}
+type RobolectricRuntimesInfo struct {
+ Runtimes []android.InstallPath
+}
+
+var RobolectricRuntimesInfoProvider = blueprint.NewProvider[RobolectricRuntimesInfo]()
+
+type roboRuntimeOnlyDependencyTag struct {
+ blueprint.BaseDependencyTag
+}
+
+var roboRuntimeOnlyDepTag roboRuntimeOnlyDependencyTag
+
+// Mark this tag so dependencies that use it are excluded from visibility enforcement.
+func (t roboRuntimeOnlyDependencyTag) ExcludeFromVisibilityEnforcement() {}
+
+var _ android.ExcludeFromVisibilityEnforcementTag = roboRuntimeOnlyDepTag
+
func RegisterRobolectricBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("android_robolectric_test", RobolectricTestFactory)
ctx.RegisterModuleType("android_robolectric_runtimes", robolectricRuntimesFactory)
@@ -41,12 +59,12 @@
}
const robolectricCurrentLib = "Robolectric_all-target"
+const clearcutJunitLib = "ClearcutJunitListenerAar"
const robolectricPrebuiltLibPattern = "platform-robolectric-%s-prebuilt"
var (
roboCoverageLibsTag = dependencyTag{name: "roboCoverageLibs"}
roboRuntimesTag = dependencyTag{name: "roboRuntimes"}
- roboRuntimeOnlyTag = dependencyTag{name: "roboRuntimeOnlyTag"}
)
type robolectricProperties struct {
@@ -64,10 +82,6 @@
Shards *int64
}
- // The version number of a robolectric prebuilt to use from prebuilts/misc/common/robolectric
- // instead of the one built from source in external/robolectric-shadows.
- Robolectric_prebuilt_version *string
-
// Use /external/robolectric rather than /external/robolectric-shadows as the version of robolectric
// to use. /external/robolectric closely tracks github's master, and will fully replace /external/robolectric-shadows
Upstream *bool
@@ -106,21 +120,12 @@
ctx.PropertyErrorf("instrumentation_for", "missing required instrumented module")
}
- if v := String(r.robolectricProperties.Robolectric_prebuilt_version); v != "" {
- ctx.AddVariationDependencies(nil, staticLibTag, fmt.Sprintf(robolectricPrebuiltLibPattern, v))
- } else if !proptools.BoolDefault(r.robolectricProperties.Strict_mode, true) {
- if proptools.Bool(r.robolectricProperties.Upstream) {
- ctx.AddVariationDependencies(nil, staticLibTag, robolectricCurrentLib+"_upstream")
- } else {
- ctx.AddVariationDependencies(nil, staticLibTag, robolectricCurrentLib)
- }
- }
+ ctx.AddVariationDependencies(nil, roboRuntimeOnlyDepTag, clearcutJunitLib)
if proptools.BoolDefault(r.robolectricProperties.Strict_mode, true) {
- ctx.AddVariationDependencies(nil, roboRuntimeOnlyTag, robolectricCurrentLib+"_upstream")
+ ctx.AddVariationDependencies(nil, roboRuntimeOnlyDepTag, robolectricCurrentLib)
} else {
- // opting out from strict mode, robolectric_non_strict_mode_permission lib should be added
- ctx.AddVariationDependencies(nil, staticLibTag, "robolectric_non_strict_mode_permission")
+ ctx.AddVariationDependencies(nil, staticLibTag, robolectricCurrentLib)
}
ctx.AddVariationDependencies(nil, staticLibTag, robolectricDefaultLibs...)
@@ -139,39 +144,54 @@
r.forceOSType = ctx.Config().BuildOS
r.forceArchType = ctx.Config().BuildArch
+ var extraTestRunnerOptions []tradefed.Option
+ extraTestRunnerOptions = append(extraTestRunnerOptions, tradefed.Option{Name: "java-flags", Value: "-Drobolectric=true"})
+ if proptools.BoolDefault(r.robolectricProperties.Strict_mode, true) {
+ extraTestRunnerOptions = append(extraTestRunnerOptions, tradefed.Option{Name: "java-flags", Value: "-Drobolectric.strict.mode=true"})
+ }
+
+ var extraOptions []tradefed.Option
+ var javaHome = ctx.Config().Getenv("ANDROID_JAVA_HOME")
+ extraOptions = append(extraOptions, tradefed.Option{Name: "java-folder", Value: javaHome})
+
r.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
- TestConfigProp: r.testProperties.Test_config,
- TestConfigTemplateProp: r.testProperties.Test_config_template,
- TestSuites: r.testProperties.Test_suites,
- AutoGenConfig: r.testProperties.Auto_gen_config,
- DeviceTemplate: "${RobolectricTestConfigTemplate}",
- HostTemplate: "${RobolectricTestConfigTemplate}",
+ TestConfigProp: r.testProperties.Test_config,
+ TestConfigTemplateProp: r.testProperties.Test_config_template,
+ TestSuites: r.testProperties.Test_suites,
+ OptionsForAutogenerated: extraOptions,
+ TestRunnerOptions: extraTestRunnerOptions,
+ AutoGenConfig: r.testProperties.Auto_gen_config,
+ DeviceTemplate: "${RobolectricTestConfigTemplate}",
+ HostTemplate: "${RobolectricTestConfigTemplate}",
})
r.data = android.PathsForModuleSrc(ctx, r.testProperties.Data)
r.data = append(r.data, android.PathsForModuleSrc(ctx, r.testProperties.Device_common_data)...)
r.data = append(r.data, android.PathsForModuleSrc(ctx, r.testProperties.Device_first_data)...)
r.data = append(r.data, android.PathsForModuleSrc(ctx, r.testProperties.Device_first_prefer32_data)...)
+ r.data = append(r.data, android.PathsForModuleSrc(ctx, r.testProperties.Host_common_data)...)
var ok bool
- var instrumentedApp *AndroidApp
+ var instrumentedApp *JavaInfo
+ var appInfo *AppInfo
// TODO: this inserts paths to built files into the test, it should really be inserting the contents.
- instrumented := ctx.GetDirectDepsWithTag(instrumentationForTag)
+ instrumented := ctx.GetDirectDepsProxyWithTag(instrumentationForTag)
if len(instrumented) == 1 {
- instrumentedApp, ok = instrumented[0].(*AndroidApp)
+ appInfo, ok = android.OtherModuleProvider(ctx, instrumented[0], AppInfoProvider)
if !ok {
ctx.PropertyErrorf("instrumentation_for", "dependency must be an android_app")
}
+ instrumentedApp = android.OtherModuleProviderOrDefault(ctx, instrumented[0], JavaInfoProvider)
} else if !ctx.Config().AllowMissingDependencies() {
panic(fmt.Errorf("expected exactly 1 instrumented dependency, got %d", len(instrumented)))
}
var resourceApk android.Path
var manifest android.Path
- if instrumentedApp != nil {
- manifest = instrumentedApp.mergedManifestFile
- resourceApk = instrumentedApp.outputFile
+ if appInfo != nil {
+ manifest = appInfo.MergedManifestFile
+ resourceApk = instrumentedApp.OutputFile
}
roboTestConfigJar := android.PathForModuleOut(ctx, "robolectric_samedir", "samedir_config.jar")
@@ -179,7 +199,7 @@
extraCombinedJars := android.Paths{roboTestConfigJar}
- handleLibDeps := func(dep android.Module) {
+ handleLibDeps := func(dep android.ModuleProxy) {
if !android.InList(ctx.OtherModuleName(dep), config.FrameworkLibraries) {
if m, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok {
extraCombinedJars = append(extraCombinedJars, m.ImplementationAndResourcesJars...)
@@ -187,25 +207,25 @@
}
}
- for _, dep := range ctx.GetDirectDepsWithTag(libTag) {
+ for _, dep := range ctx.GetDirectDepsProxyWithTag(libTag) {
handleLibDeps(dep)
}
- for _, dep := range ctx.GetDirectDepsWithTag(sdkLibTag) {
+ for _, dep := range ctx.GetDirectDepsProxyWithTag(sdkLibTag) {
handleLibDeps(dep)
}
// handle the runtimeOnly tag for strict_mode
- for _, dep := range ctx.GetDirectDepsWithTag(roboRuntimeOnlyTag) {
+ for _, dep := range ctx.GetDirectDepsProxyWithTag(roboRuntimeOnlyDepTag) {
handleLibDeps(dep)
}
- if instrumentedApp != nil {
- extraCombinedJars = append(extraCombinedJars, instrumentedApp.implementationAndResourcesJar)
+ if appInfo != nil {
+ extraCombinedJars = append(extraCombinedJars, instrumentedApp.ImplementationAndResourcesJars...)
}
r.stem = proptools.StringDefault(r.overridableProperties.Stem, ctx.ModuleName())
r.classLoaderContexts = r.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
r.dexpreopter.disableDexpreopt()
- r.compile(ctx, nil, nil, nil, extraCombinedJars)
+ javaInfo := r.compile(ctx, nil, nil, nil, extraCombinedJars)
installPath := android.PathForModuleInstall(ctx, r.BaseModuleName())
var installDeps android.InstallPaths
@@ -227,8 +247,8 @@
installDeps = append(installDeps, installedResourceApk)
}
- runtimes := ctx.GetDirectDepWithTag("robolectric-android-all-prebuilts", roboRuntimesTag)
- for _, runtime := range runtimes.(*robolectricRuntimes).runtimes {
+ runtimes := ctx.GetDirectDepProxyWithTag("robolectric-android-all-prebuilts", roboRuntimesTag)
+ for _, runtime := range android.OtherModuleProviderOrDefault(ctx, runtimes, RobolectricRuntimesInfoProvider).Runtimes {
installDeps = append(installDeps, runtime)
}
@@ -242,6 +262,33 @@
}
r.installFile = ctx.InstallFile(installPath, ctx.ModuleName()+".jar", r.outputFile, installDeps...)
+
+ if javaInfo != nil {
+ setExtraJavaInfo(ctx, r, javaInfo)
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+ }
+
+ moduleInfoJSON := r.javaLibraryModuleInfoJSON(ctx)
+ if _, ok := r.testConfig.(android.WritablePath); ok {
+ moduleInfoJSON.AutoTestConfig = []string{"true"}
+ }
+ if r.testConfig != nil {
+ moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, r.testConfig.String())
+ }
+ if len(r.testProperties.Test_suites) > 0 {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, r.testProperties.Test_suites...)
+ } else {
+ moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
+ }
+
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: r.TestSuites(),
+ })
+
+ android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
+ TestOnly: Bool(r.sourceProperties.Test_only),
+ TopLevelTarget: r.sourceProperties.Top_level_test_target,
+ })
}
func generateSameDirRoboTestConfigJar(ctx android.ModuleContext, outputFile android.ModuleOutPath) {
@@ -292,8 +339,9 @@
&module.testProperties)
module.Module.dexpreopter.isTest = true
- module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
-
+ module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
+ module.Module.sourceProperties.Test_only = proptools.BoolPtr(true)
+ module.Module.sourceProperties.Top_level_test_target = true
module.testProperties.Test_suites = []string{"robolectric-tests"}
InitJavaModule(module, android.DeviceSupported)
@@ -357,7 +405,7 @@
}
if !ctx.Config().AlwaysUsePrebuiltSdks() && r.props.Lib != nil {
- runtimeFromSourceModule := ctx.GetDirectDepWithTag(String(r.props.Lib), libTag)
+ runtimeFromSourceModule := ctx.GetDirectDepProxyWithTag(String(r.props.Lib), libTag)
if runtimeFromSourceModule == nil {
if ctx.Config().AllowMissingDependencies() {
ctx.AddMissingDependencies([]string{String(r.props.Lib)})
@@ -375,6 +423,14 @@
installedRuntime := ctx.InstallFile(androidAllDir, runtimeName, runtimeFromSourceJar)
r.runtimes = append(r.runtimes, installedRuntime)
}
+
+ android.SetProvider(ctx, RobolectricRuntimesInfoProvider, RobolectricRuntimesInfo{
+ Runtimes: r.runtimes,
+ })
+
+ android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+ TestSuites: r.TestSuites(),
+ })
}
func (r *robolectricRuntimes) InstallInTestcases() bool { return true }
diff --git a/java/robolectric_test.go b/java/robolectric_test.go
index 4775bac..cc16c6a 100644
--- a/java/robolectric_test.go
+++ b/java/robolectric_test.go
@@ -32,6 +32,11 @@
}
java_library {
+ name: "Robolectric_all-target",
+ srcs: ["Robo.java"]
+ }
+
+ java_library {
name: "mockito-robolectric-prebuilt",
srcs: ["Mockito.java"]
}
@@ -44,6 +49,12 @@
java_library {
name: "junitxml",
srcs: ["JUnitXml.java"]
+
+ }
+
+ java_library {
+ name: "ClearcutJunitListenerAar",
+ srcs: ["Runtime.java"]
}
java_library_host {
@@ -60,6 +71,7 @@
)
func TestRobolectricJniTest(t *testing.T) {
+ t.Parallel()
if runtime.GOOS != "linux" {
t.Skip("requires linux")
}
@@ -93,6 +105,17 @@
CheckModuleHasDependency(t, ctx.TestContext, "robo-test", "android_common", "jni-lib1")
// Check that the .so files make it into the output.
- module := ctx.ModuleForTests("robo-test", "android_common")
+ module := ctx.ModuleForTests(t, "robo-test", "android_common")
module.Output(installPathPrefix + "/robo-test/lib64/jni-lib1.so")
+
+ // Ensure they are listed as "test" modules for code coverage
+ expectedTestOnlyModules := []string{
+ "robo-test",
+ }
+
+ expectedTopLevelTests := []string{
+ "robo-test",
+ }
+ assertTestOnlyAndTopLevel(t, ctx, expectedTestOnlyModules, expectedTopLevelTests)
+
}
diff --git a/java/rro.go b/java/rro.go
index ab4fafa..4ae8d7f 100644
--- a/java/rro.go
+++ b/java/rro.go
@@ -34,6 +34,15 @@
ctx.RegisterModuleType("override_runtime_resource_overlay", OverrideRuntimeResourceOverlayModuleFactory)
}
+type RuntimeResourceOverlayInfo struct {
+ OutputFile android.Path
+ Certificate Certificate
+ Theme string
+ OverriddenManifestPackageName string
+}
+
+var RuntimeResourceOverlayInfoProvider = blueprint.NewProvider[RuntimeResourceOverlayInfo]()
+
type RuntimeResourceOverlay struct {
android.ModuleBase
android.DefaultableModuleBase
@@ -90,15 +99,6 @@
Overrides []string
}
-// RuntimeResourceOverlayModule interface is used by the apex package to gather information from
-// a RuntimeResourceOverlay module.
-type RuntimeResourceOverlayModule interface {
- android.Module
- OutputFile() android.Path
- Certificate() Certificate
- Theme() string
-}
-
// RRO's partition logic is different from the partition logic of other modules defined in soong/android/paths.go
// The default partition for RRO is "/product" and not "/system"
func rroPartition(ctx android.ModuleContext) string {
@@ -139,6 +139,25 @@
r.aapt.hasNoCode = true
// Do not remove resources without default values nor dedupe resource configurations with the same value
aaptLinkFlags := []string{"--no-resource-deduping", "--no-resource-removal"}
+
+ // Add TARGET_AAPT_CHARACTERISTICS values to AAPT link flags if they exist and --product flags were not provided.
+ hasProduct := android.PrefixInList(r.aaptProperties.Aaptflags, "--product")
+ if !hasProduct && len(ctx.Config().ProductAAPTCharacteristics()) > 0 {
+ aaptLinkFlags = append(aaptLinkFlags, "--product", ctx.Config().ProductAAPTCharacteristics())
+ }
+
+ if !Bool(r.aaptProperties.Aapt_include_all_resources) {
+ // Product AAPT config
+ for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
+ aaptLinkFlags = append(aaptLinkFlags, "-c", aaptConfig)
+ }
+
+ // Product AAPT preferred config
+ if len(ctx.Config().ProductAAPTPreferredConfig()) > 0 {
+ aaptLinkFlags = append(aaptLinkFlags, "--preferred-density", ctx.Config().ProductAAPTPreferredConfig())
+ }
+ }
+
// Allow the override of "package name" and "overlay target package name"
manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName())
if overridden || r.overridableProperties.Package_name != nil {
@@ -187,6 +206,16 @@
android.SetProvider(ctx, FlagsPackagesProvider, FlagsPackages{
AconfigTextFiles: aconfigTextFilePaths,
})
+
+ android.SetProvider(ctx, RuntimeResourceOverlayInfoProvider, RuntimeResourceOverlayInfo{
+ OutputFile: r.outputFile,
+ Certificate: r.Certificate(),
+ Theme: r.Theme(),
+ })
+
+ ctx.SetOutputFiles([]android.Path{r.outputFile}, "")
+
+ buildComplianceMetadata(ctx)
}
func (r *RuntimeResourceOverlay) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
@@ -216,10 +245,6 @@
return r.certificate
}
-func (r *RuntimeResourceOverlay) OutputFile() android.Path {
- return r.outputFile
-}
-
func (r *RuntimeResourceOverlay) Theme() string {
return String(r.properties.Theme)
}
@@ -370,10 +395,11 @@
a.aapt.buildActions(ctx,
aaptBuildActionOptions{
- sdkContext: a,
- extraLinkFlags: aaptLinkFlags,
- rroDirs: &rroDirs,
- manifestForAapt: genManifest,
+ sdkContext: a,
+ extraLinkFlags: aaptLinkFlags,
+ rroDirs: &rroDirs,
+ manifestForAapt: genManifest,
+ aconfigTextFiles: getAconfigFilePaths(ctx),
},
)
@@ -390,6 +416,11 @@
// Install the signed apk
installDir := android.PathForModuleInstall(ctx, "overlay")
ctx.InstallFile(installDir, signed.Base(), signed)
+
+ android.SetProvider(ctx, RuntimeResourceOverlayInfoProvider, RuntimeResourceOverlayInfo{
+ OutputFile: signed,
+ Certificate: a.certificate,
+ })
}
func (a *AutogenRuntimeResourceOverlay) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
diff --git a/java/rro_test.go b/java/rro_test.go
index 4d58bb4..3e4fed5 100644
--- a/java/rro_test.go
+++ b/java/rro_test.go
@@ -24,6 +24,7 @@
)
func TestRuntimeResourceOverlay(t *testing.T) {
+ t.Parallel()
fs := android.MockFS{
"baz/res/res/values/strings.xml": nil,
"bar/res/res/values/strings.xml": nil,
@@ -66,7 +67,7 @@
fs.AddToFixture(),
).RunTestWithBp(t, bp)
- m := result.ModuleForTests("foo", "android_common")
+ m := result.ModuleForTests(t, "foo", "android_common")
// Check AAPT2 link flags.
aapt2Flags := m.Output("package-res.apk").Args["flags"]
@@ -115,7 +116,7 @@
android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", result.Config, expectedPath, path)
// A themed module has a different device location
- m = result.ModuleForTests("foo_themed", "android_common")
+ m = result.ModuleForTests(t, "foo_themed", "android_common")
androidMkEntries = android.AndroidMkEntriesForTest(t, result.TestContext, m.Module())[0]
path = androidMkEntries.EntryMap["LOCAL_MODULE_PATH"]
expectedPath = []string{shared.JoinPath("out/target/product/test_device/product/overlay/faza")}
@@ -129,6 +130,7 @@
}
func TestRuntimeResourceOverlay_JavaDefaults(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.FixtureModifyConfig(android.SetKatiEnabledForTests),
@@ -153,7 +155,7 @@
//
// RRO module with defaults
//
- m := result.ModuleForTests("foo_with_defaults", "android_common")
+ m := result.ModuleForTests(t, "foo_with_defaults", "android_common")
// Check AAPT2 link flags.
aapt2Flags := strings.Split(m.Output("package-res.apk").Args["flags"], " ")
@@ -171,7 +173,7 @@
//
// RRO module without defaults
//
- m = result.ModuleForTests("foo_barebones", "android_common")
+ m = result.ModuleForTests(t, "foo_barebones", "android_common")
// Check AAPT2 link flags.
aapt2Flags = strings.Split(m.Output("package-res.apk").Args["flags"], " ")
@@ -216,7 +218,7 @@
}{
{
variantName: "android_common",
- apkPath: "out/soong/target/product/test_device/product/overlay/foo_overlay.apk",
+ apkPath: "out/target/product/test_device/product/overlay/foo_overlay.apk",
overrides: nil,
targetVariant: "android_common",
packageFlag: "",
@@ -224,7 +226,7 @@
},
{
variantName: "android_common_bar_overlay",
- apkPath: "out/soong/target/product/test_device/product/overlay/bar_overlay.apk",
+ apkPath: "out/target/product/test_device/product/overlay/bar_overlay.apk",
overrides: []string{"foo_overlay"},
targetVariant: "android_common_bar",
packageFlag: "com.android.bar.overlay",
@@ -233,7 +235,7 @@
},
}
for _, expected := range expectedVariants {
- variant := ctx.ModuleForTests("foo_overlay", expected.variantName)
+ variant := ctx.ModuleForTests(t, "foo_overlay", expected.variantName)
// Check the final apk name
variant.Output(expected.apkPath)
@@ -283,28 +285,28 @@
}{
{
name: "device_specific",
- expectedPath: "out/soong/target/product/test_device/odm/overlay",
+ expectedPath: "out/target/product/test_device/odm/overlay",
},
{
name: "soc_specific",
- expectedPath: "out/soong/target/product/test_device/vendor/overlay",
+ expectedPath: "out/target/product/test_device/vendor/overlay",
},
{
name: "system_ext_specific",
- expectedPath: "out/soong/target/product/test_device/system_ext/overlay",
+ expectedPath: "out/target/product/test_device/system_ext/overlay",
},
{
name: "product_specific",
- expectedPath: "out/soong/target/product/test_device/product/overlay",
+ expectedPath: "out/target/product/test_device/product/overlay",
},
{
name: "default",
- expectedPath: "out/soong/target/product/test_device/product/overlay",
+ expectedPath: "out/target/product/test_device/product/overlay",
},
}
for _, testCase := range testCases {
ctx, _ := testJava(t, bp)
- mod := ctx.ModuleForTests(testCase.name, "android_common").Module().(*RuntimeResourceOverlay)
+ mod := ctx.ModuleForTests(t, testCase.name, "android_common").Module().(*RuntimeResourceOverlay)
android.AssertPathRelativeToTopEquals(t, "Install dir is not correct for "+testCase.name, testCase.expectedPath, mod.installDir)
}
}
@@ -339,7 +341,7 @@
}
`)
- foo := result.ModuleForTests("foo", "android_common")
+ foo := result.ModuleForTests(t, "foo", "android_common")
// runtime_resource_overlay module depends on aconfig_declarations listed in flags_packages
android.AssertBoolEquals(t, "foo expected to depend on bar", true,
@@ -356,3 +358,21 @@
"--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt",
)
}
+
+func TestCanBeDataOfTest(t *testing.T) {
+ android.GroupFixturePreparers(
+ prepareForJavaTest,
+ ).RunTestWithBp(t, `
+ runtime_resource_overlay {
+ name: "foo",
+ sdk_version: "current",
+ }
+ android_test {
+ name: "bar",
+ data: [
+ ":foo",
+ ],
+ }
+ `)
+ // Just test that this doesn't get errors
+}
diff --git a/java/sdk.go b/java/sdk.go
index 407fdcf..1dbea3b 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -276,7 +276,7 @@
func createFrameworkAidl(stubsModules []string, path android.WritablePath, ctx android.SingletonContext) *android.RuleBuilder {
stubsJars := make([]android.Paths, len(stubsModules))
- ctx.VisitAllModules(func(module android.Module) {
+ ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
// Collect dex jar paths for the modules listed above.
if j, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
name := ctx.ModuleName(module)
@@ -360,7 +360,7 @@
"api_fingerprint",
}
count := 0
- ctx.VisitAllModules(func(module android.Module) {
+ ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
name := ctx.ModuleName(module)
if android.InList(name, apiTxtFileModules) {
cmd.Inputs(android.OutputFilesForModule(ctx, module, ""))
@@ -383,6 +383,10 @@
}
rule.Build("api_fingerprint", "generate api_fingerprint.txt")
+
+ if ctx.Config().BuildOS.Linux() {
+ ctx.DistForGoals([]string{"sdk", "droidcore"}, out)
+ }
}
func sdkMakeVars(ctx android.MakeVarsContext) {
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 7891776..00ba8b2 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -316,6 +316,15 @@
return name
}
+func (scopes apiScopes) matchingScopeFromSdkKind(kind android.SdkKind) *apiScope {
+ for _, scope := range scopes {
+ if scope.kind == kind {
+ return scope
+ }
+ }
+ return nil
+}
+
var (
scopeByName = make(map[string]*apiScope)
allScopeNames []string
@@ -480,6 +489,9 @@
// Extra libs used when compiling stubs for this scope.
Libs []string
+
+ // Name to override the api_surface that is passed down to droidstubs.
+ Api_surface *string
}
type sdkLibraryProperties struct {
@@ -690,9 +702,9 @@
paths.stubsHeaderPath = lib.HeaderJars
paths.stubsImplPath = lib.ImplementationJars
- libDep := dep.(UsesLibraryDependency)
- paths.stubsDexJarPath = libDep.DexJarBuildPath(ctx)
- paths.exportableStubsDexJarPath = libDep.DexJarBuildPath(ctx)
+ libDep := android.OtherModuleProviderOrDefault(ctx, dep, JavaInfoProvider)
+ paths.stubsDexJarPath = libDep.DexJarBuildPath
+ paths.exportableStubsDexJarPath = libDep.DexJarBuildPath
return nil
} else {
return fmt.Errorf("expected module that has JavaInfoProvider, e.g. java_library")
@@ -706,8 +718,8 @@
paths.stubsImplPath = lib.ImplementationJars
}
- libDep := dep.(UsesLibraryDependency)
- paths.stubsDexJarPath = libDep.DexJarBuildPath(ctx)
+ libDep := android.OtherModuleProviderOrDefault(ctx, dep, JavaInfoProvider)
+ paths.stubsDexJarPath = libDep.DexJarBuildPath
return nil
} else {
return fmt.Errorf("expected module that has JavaInfoProvider, e.g. java_library")
@@ -720,58 +732,67 @@
paths.stubsImplPath = lib.ImplementationJars
}
- libDep := dep.(UsesLibraryDependency)
- paths.exportableStubsDexJarPath = libDep.DexJarBuildPath(ctx)
+ libDep := android.OtherModuleProviderOrDefault(ctx, dep, JavaInfoProvider)
+ paths.exportableStubsDexJarPath = libDep.DexJarBuildPath
return nil
} else {
return fmt.Errorf("expected module that has JavaInfoProvider, e.g. java_library")
}
}
-func (paths *scopePaths) treatDepAsApiStubsProvider(dep android.Module, action func(provider ApiStubsProvider) error) error {
- if apiStubsProvider, ok := dep.(ApiStubsProvider); ok {
- err := action(apiStubsProvider)
+func (paths *scopePaths) treatDepAsApiStubsProvider(ctx android.ModuleContext, dep android.Module,
+ action func(*DroidStubsInfo, *StubsSrcInfo) error) error {
+ apiStubsProvider, ok := android.OtherModuleProvider(ctx, dep, DroidStubsInfoProvider)
+ if !ok {
+ return fmt.Errorf("expected module that provides DroidStubsInfo, e.g. droidstubs")
+ }
+
+ apiStubsSrcProvider, ok := android.OtherModuleProvider(ctx, dep, StubsSrcInfoProvider)
+ if !ok {
+ return fmt.Errorf("expected module that provides StubsSrcInfo, e.g. droidstubs")
+ }
+ return action(&apiStubsProvider, &apiStubsSrcProvider)
+}
+
+func (paths *scopePaths) treatDepAsApiStubsSrcProvider(
+ ctx android.ModuleContext, dep android.Module, action func(provider *StubsSrcInfo) error) error {
+ if apiStubsProvider, ok := android.OtherModuleProvider(ctx, dep, StubsSrcInfoProvider); ok {
+ err := action(&apiStubsProvider)
if err != nil {
return err
}
return nil
} else {
- return fmt.Errorf("expected module that implements ExportableApiStubsSrcProvider, e.g. droidstubs")
+ return fmt.Errorf("expected module that provides DroidStubsInfo, e.g. droidstubs")
}
}
-func (paths *scopePaths) treatDepAsApiStubsSrcProvider(dep android.Module, action func(provider ApiStubsSrcProvider) error) error {
- if apiStubsProvider, ok := dep.(ApiStubsSrcProvider); ok {
- err := action(apiStubsProvider)
- if err != nil {
- return err
- }
- return nil
- } else {
- return fmt.Errorf("expected module that implements ApiStubsSrcProvider, e.g. droidstubs")
+func (paths *scopePaths) extractApiInfoFromApiStubsProvider(provider *DroidStubsInfo, stubsType StubsType) error {
+ var currentApiFilePathErr, removedApiFilePathErr error
+ info, err := getStubsInfoForType(provider, stubsType)
+ if err != nil {
+ return err
}
-}
-
-func (paths *scopePaths) extractApiInfoFromApiStubsProvider(provider ApiStubsProvider, stubsType StubsType) error {
- var annotationsZip, currentApiFilePath, removedApiFilePath android.Path
- annotationsZip, annotationsZipErr := provider.AnnotationsZip(stubsType)
- currentApiFilePath, currentApiFilePathErr := provider.ApiFilePath(stubsType)
- removedApiFilePath, removedApiFilePathErr := provider.RemovedApiFilePath(stubsType)
-
- combinedError := errors.Join(annotationsZipErr, currentApiFilePathErr, removedApiFilePathErr)
+ if info.ApiFile == nil {
+ currentApiFilePathErr = fmt.Errorf("expected module that provides ApiFile")
+ }
+ if info.RemovedApiFile == nil {
+ removedApiFilePathErr = fmt.Errorf("expected module that provides RemovedApiFile")
+ }
+ combinedError := errors.Join(currentApiFilePathErr, removedApiFilePathErr)
if combinedError == nil {
- paths.annotationsZip = android.OptionalPathForPath(annotationsZip)
- paths.currentApiFilePath = android.OptionalPathForPath(currentApiFilePath)
- paths.removedApiFilePath = android.OptionalPathForPath(removedApiFilePath)
+ paths.annotationsZip = android.OptionalPathForPath(info.AnnotationsZip)
+ paths.currentApiFilePath = android.OptionalPathForPath(info.ApiFile)
+ paths.removedApiFilePath = android.OptionalPathForPath(info.RemovedApiFile)
}
return combinedError
}
-func (paths *scopePaths) extractStubsSourceInfoFromApiStubsProviders(provider ApiStubsSrcProvider, stubsType StubsType) error {
- stubsSrcJar, err := provider.StubsSrcJar(stubsType)
+func (paths *scopePaths) extractStubsSourceInfoFromApiStubsProviders(provider *StubsSrcInfo, stubsType StubsType) error {
+ path, err := getStubsSrcInfoForType(provider, stubsType)
if err == nil {
- paths.stubsSrcJar = android.OptionalPathForPath(stubsSrcJar)
+ paths.stubsSrcJar = android.OptionalPathForPath(path)
}
return err
}
@@ -781,7 +802,7 @@
if ctx.Config().ReleaseHiddenApiExportableStubs() {
stubsType = Exportable
}
- return paths.treatDepAsApiStubsSrcProvider(dep, func(provider ApiStubsSrcProvider) error {
+ return paths.treatDepAsApiStubsSrcProvider(ctx, dep, func(provider *StubsSrcInfo) error {
return paths.extractStubsSourceInfoFromApiStubsProviders(provider, stubsType)
})
}
@@ -791,17 +812,17 @@
if ctx.Config().ReleaseHiddenApiExportableStubs() {
stubsType = Exportable
}
- return paths.treatDepAsApiStubsProvider(dep, func(provider ApiStubsProvider) error {
- extractApiInfoErr := paths.extractApiInfoFromApiStubsProvider(provider, stubsType)
- extractStubsSourceInfoErr := paths.extractStubsSourceInfoFromApiStubsProviders(provider, stubsType)
+ return paths.treatDepAsApiStubsProvider(ctx, dep, func(apiStubsProvider *DroidStubsInfo, apiStubsSrcProvider *StubsSrcInfo) error {
+ extractApiInfoErr := paths.extractApiInfoFromApiStubsProvider(apiStubsProvider, stubsType)
+ extractStubsSourceInfoErr := paths.extractStubsSourceInfoFromApiStubsProviders(apiStubsSrcProvider, stubsType)
return errors.Join(extractApiInfoErr, extractStubsSourceInfoErr)
})
}
-func extractOutputPaths(dep android.Module) (android.Paths, error) {
+func extractOutputPaths(ctx android.ModuleContext, dep android.Module) (android.Paths, error) {
var paths android.Paths
- if sourceFileProducer, ok := dep.(android.SourceFileProducer); ok {
- paths = sourceFileProducer.Srcs()
+ if sourceFileProducer, ok := android.OtherModuleProvider(ctx, dep, android.SourceFilesInfoProvider); ok {
+ paths = sourceFileProducer.Srcs
return paths, nil
} else {
return nil, fmt.Errorf("module %q does not produce source files", dep)
@@ -809,17 +830,47 @@
}
func (paths *scopePaths) extractLatestApiPath(ctx android.ModuleContext, dep android.Module) error {
- outputPaths, err := extractOutputPaths(dep)
+ outputPaths, err := extractOutputPaths(ctx, dep)
paths.latestApiPaths = outputPaths
return err
}
func (paths *scopePaths) extractLatestRemovedApiPath(ctx android.ModuleContext, dep android.Module) error {
- outputPaths, err := extractOutputPaths(dep)
+ outputPaths, err := extractOutputPaths(ctx, dep)
paths.latestRemovedApiPaths = outputPaths
return err
}
+func getStubsInfoForType(info *DroidStubsInfo, stubsType StubsType) (ret *StubsInfo, err error) {
+ switch stubsType {
+ case Everything:
+ ret, err = &info.EverythingStubsInfo, nil
+ case Exportable:
+ ret, err = &info.ExportableStubsInfo, nil
+ default:
+ ret, err = nil, fmt.Errorf("stubs info not supported for the stub type %s", stubsType.String())
+ }
+ if ret == nil && err == nil {
+ err = fmt.Errorf("stubs info is null for the stub type %s", stubsType.String())
+ }
+ return ret, err
+}
+
+func getStubsSrcInfoForType(info *StubsSrcInfo, stubsType StubsType) (ret android.Path, err error) {
+ switch stubsType {
+ case Everything:
+ ret, err = info.EverythingStubsSrcJar, nil
+ case Exportable:
+ ret, err = info.ExportableStubsSrcJar, nil
+ default:
+ ret, err = nil, fmt.Errorf("stubs src info not supported for the stub type %s", stubsType.String())
+ }
+ if ret == nil && err == nil {
+ err = fmt.Errorf("stubs src info is null for the stub type %s", stubsType.String())
+ }
+ return ret, err
+}
+
type commonToSdkLibraryAndImportProperties struct {
// Specifies whether this module can be used as an Android shared library; defaults
// to true.
@@ -880,6 +931,8 @@
RootLibraryName() string
}
+var _ android.ApexModule = (*SdkLibrary)(nil)
+
func (m *SdkLibrary) RootLibraryName() string {
return m.BaseModuleName()
}
@@ -908,9 +961,9 @@
// This is non-empty only when api_only is false.
implLibraryHeaderJars android.Paths
- // The reference to the implementation library created by the source module.
- // Is nil if the source module does not exist.
- implLibraryModule *Library
+ // The reference to the JavaInfo provided by implementation library created by
+ // the source module. Is nil if the source module does not exist.
+ implLibraryInfo *JavaInfo
}
func (c *commonToSdkLibraryAndImport) initCommon(module commonSdkLibraryAndImportModule) {
@@ -1170,6 +1223,8 @@
// Whether if this can be used as a shared library.
SharedLibrary bool
+
+ Prebuilt bool
}
var SdkLibraryInfoProvider = blueprint.NewProvider[SdkLibraryInfo]()
@@ -1200,7 +1255,8 @@
commonToSdkLibraryAndImport
- builtInstalledForApex []dexpreopterInstall
+ apexSystemServerDexpreoptInstalls []DexpreopterInstall
+ apexSystemServerDexJars android.Paths
}
func (module *SdkLibrary) generateTestAndSystemScopesByDefault() bool {
@@ -1211,16 +1267,16 @@
// To satisfy the UsesLibraryDependency interface
func (module *SdkLibrary) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
- if module.implLibraryModule != nil {
- return module.implLibraryModule.DexJarBuildPath(ctx)
+ if module.implLibraryInfo != nil {
+ return module.implLibraryInfo.DexJarFile
}
return makeUnsetDexJarPath()
}
// To satisfy the UsesLibraryDependency interface
func (module *SdkLibrary) DexJarInstallPath() android.Path {
- if module.implLibraryModule != nil {
- return module.implLibraryModule.DexJarInstallPath()
+ if module.implLibraryInfo != nil {
+ return module.implLibraryInfo.InstallFile
}
return nil
}
@@ -1281,10 +1337,10 @@
func CheckMinSdkVersion(ctx android.ModuleContext, module *Library) {
android.CheckMinSdkVersion(ctx, module.MinSdkVersion(ctx), func(c android.BaseModuleContext, do android.PayloadDepsCallback) {
- ctx.WalkDeps(func(child android.Module, parent android.Module) bool {
- isExternal := !module.depIsInSameApex(ctx, child)
- if am, ok := child.(android.ApexModule); ok {
- if !do(ctx, parent, am, isExternal) {
+ ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool {
+ isExternal := !android.IsDepInSameApex(ctx, module, child)
+ if am, ok := android.OtherModuleProvider(ctx, child, android.CommonModuleInfoProvider); ok && am.IsApexModule {
+ if !do(ctx, parent, child, isExternal) {
return false
}
}
@@ -1407,11 +1463,11 @@
// Collate the components exported by this module. All scope specific modules are exported but
// the impl and xml component modules are not.
exportedComponents := map[string]struct{}{}
-
+ var implLib android.ModuleProxy
// Record the paths to the header jars of the library (stubs and impl).
// When this java_sdk_library is depended upon from others via "libs" property,
// the recorded paths will be returned depending on the link type of the caller.
- ctx.VisitDirectDeps(func(to android.Module) {
+ ctx.VisitDirectDepsProxy(func(to android.ModuleProxy) {
tag := ctx.OtherModuleDependencyTag(to)
// Extract information from any of the scope specific dependencies.
@@ -1431,7 +1487,8 @@
if tag == implLibraryTag {
if dep, ok := android.OtherModuleProvider(ctx, to, JavaInfoProvider); ok {
module.implLibraryHeaderJars = append(module.implLibraryHeaderJars, dep.HeaderJars...)
- module.implLibraryModule = to.(*Library)
+ module.implLibraryInfo = dep
+ implLib = to
}
}
})
@@ -1442,44 +1499,44 @@
module.hideApexVariantFromMake = true
}
- if module.implLibraryModule != nil {
+ if module.implLibraryInfo != nil {
if ctx.Device() {
- module.classesJarPaths = android.Paths{module.implLibraryModule.implementationJarFile}
- module.bootDexJarPath = module.implLibraryModule.bootDexJarPath
- module.uncompressDexState = module.implLibraryModule.uncompressDexState
- module.active = module.implLibraryModule.active
+ module.classesJarPaths = module.implLibraryInfo.ImplementationJars
+ module.bootDexJarPath = module.implLibraryInfo.BootDexJarPath
+ module.uncompressDexState = module.implLibraryInfo.UncompressDexState
+ module.active = module.implLibraryInfo.Active
}
- module.outputFile = module.implLibraryModule.outputFile
- module.dexJarFile = makeDexJarPathFromPath(module.implLibraryModule.dexJarFile.Path())
- module.headerJarFile = module.implLibraryModule.headerJarFile
- module.implementationAndResourcesJar = module.implLibraryModule.implementationAndResourcesJar
- module.builtInstalledForApex = module.implLibraryModule.builtInstalledForApex
- module.dexpreopter.configPath = module.implLibraryModule.dexpreopter.configPath
- module.dexpreopter.outputProfilePathOnHost = module.implLibraryModule.dexpreopter.outputProfilePathOnHost
+ module.outputFile = module.implLibraryInfo.OutputFile
+ module.dexJarFile = makeDexJarPathFromPath(module.implLibraryInfo.DexJarFile.Path())
+ module.headerJarFile = module.implLibraryInfo.HeaderJars[0]
+ module.implementationAndResourcesJar = module.implLibraryInfo.ImplementationAndResourcesJars[0]
+ module.apexSystemServerDexpreoptInstalls = module.implLibraryInfo.DexpreopterInfo.ApexSystemServerDexpreoptInstalls
+ module.apexSystemServerDexJars = module.implLibraryInfo.DexpreopterInfo.ApexSystemServerDexJars
+ module.dexpreopter.configPath = module.implLibraryInfo.ConfigPath
+ module.dexpreopter.outputProfilePathOnHost = module.implLibraryInfo.DexpreopterInfo.OutputProfilePathOnHost
// Properties required for Library.AndroidMkEntries
- module.logtagsSrcs = module.implLibraryModule.logtagsSrcs
- module.dexpreopter.builtInstalled = module.implLibraryModule.dexpreopter.builtInstalled
- module.jacocoReportClassesFile = module.implLibraryModule.jacocoReportClassesFile
- module.dexer.proguardDictionary = module.implLibraryModule.dexer.proguardDictionary
- module.dexer.proguardUsageZip = module.implLibraryModule.dexer.proguardUsageZip
- module.linter.reports = module.implLibraryModule.linter.reports
+ module.logtagsSrcs = module.implLibraryInfo.LogtagsSrcs
+ module.dexpreopter.builtInstalled = module.implLibraryInfo.BuiltInstalled
+ module.jacocoReportClassesFile = module.implLibraryInfo.JacocoReportClassesFile
+ module.dexer.proguardDictionary = module.implLibraryInfo.ProguardDictionary
+ module.dexer.proguardUsageZip = module.implLibraryInfo.ProguardUsageZip
+ module.linter.reports = module.implLibraryInfo.LinterReports
- if lintInfo, ok := android.OtherModuleProvider(ctx, module.implLibraryModule, LintProvider); ok {
+ if lintInfo, ok := android.OtherModuleProvider(ctx, implLib, LintProvider); ok {
android.SetProvider(ctx, LintProvider, lintInfo)
}
if !module.Host() {
- module.hostdexInstallFile = module.implLibraryModule.hostdexInstallFile
+ module.hostdexInstallFile = module.implLibraryInfo.HostdexInstallFile
}
- if installFilesInfo, ok := android.OtherModuleProvider(ctx, module.implLibraryModule, android.InstallFilesProvider); ok {
+ if installFilesInfo, ok := android.OtherModuleProvider(ctx, implLib, android.InstallFilesProvider); ok {
if installFilesInfo.CheckbuildTarget != nil {
ctx.CheckbuildFile(installFilesInfo.CheckbuildTarget)
}
}
- android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: module.implLibraryModule.uniqueSrcFiles.Strings()})
}
// Make the set of components exported by this module available for use elsewhere.
@@ -1518,17 +1575,39 @@
}
}
- if module.requiresRuntimeImplementationLibrary() && module.implLibraryModule != nil {
+ if module.requiresRuntimeImplementationLibrary() && module.implLibraryInfo != nil {
generatingLibs = append(generatingLibs, module.implLibraryModuleName())
- setOutputFiles(ctx, module.implLibraryModule.Module)
+ setOutputFilesFromJavaInfo(ctx, module.implLibraryInfo)
}
+ javaInfo := &JavaInfo{
+ JacocoReportClassesFile: module.jacocoReportClassesFile,
+ }
+ setExtraJavaInfo(ctx, ctx.Module(), javaInfo)
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+
sdkLibInfo.GeneratingLibs = generatingLibs
+ sdkLibInfo.Prebuilt = false
android.SetProvider(ctx, SdkLibraryInfoProvider, sdkLibInfo)
}
-func (module *SdkLibrary) BuiltInstalledForApex() []dexpreopterInstall {
- return module.builtInstalledForApex
+func setOutputFilesFromJavaInfo(ctx android.ModuleContext, info *JavaInfo) {
+ ctx.SetOutputFiles(append(android.PathsIfNonNil(info.OutputFile), info.ExtraOutputFiles...), "")
+ ctx.SetOutputFiles(android.PathsIfNonNil(info.OutputFile), android.DefaultDistTag)
+ ctx.SetOutputFiles(info.ImplementationAndResourcesJars, ".jar")
+ ctx.SetOutputFiles(info.HeaderJars, ".hjar")
+ if info.ProguardDictionary.Valid() {
+ ctx.SetOutputFiles(android.Paths{info.ProguardDictionary.Path()}, ".proguard_map")
+ }
+ ctx.SetOutputFiles(info.GeneratedSrcjars, ".generated_srcjars")
+}
+
+func (module *SdkLibrary) ApexSystemServerDexpreoptInstalls() []DexpreopterInstall {
+ return module.apexSystemServerDexpreoptInstalls
+}
+
+func (module *SdkLibrary) ApexSystemServerDexJars() android.Paths {
+ return module.apexSystemServerDexJars
}
func (module *SdkLibrary) AndroidMkEntries() []android.AndroidMkEntries {
@@ -1636,15 +1715,22 @@
}
// Implements android.ApexModule
-func (module *SdkLibrary) DepIsInSameApex(mctx android.BaseModuleContext, dep android.Module) bool {
- depTag := mctx.OtherModuleDependencyTag(dep)
- if depTag == xmlPermissionsFileTag {
+func (m *SdkLibrary) GetDepInSameApexChecker() android.DepInSameApexChecker {
+ return SdkLibraryDepInSameApexChecker{}
+}
+
+type SdkLibraryDepInSameApexChecker struct {
+ android.BaseDepInSameApexChecker
+}
+
+func (m SdkLibraryDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
+ if tag == xmlPermissionsFileTag {
return true
}
- if dep.Name() == module.implLibraryModuleName() {
+ if tag == implLibraryTag {
return true
}
- return module.Library.DepIsInSameApex(mctx, dep)
+ return depIsInSameApex(tag)
}
// Implements android.ApexModule
@@ -1901,10 +1987,6 @@
commonToSdkLibraryAndImport
- // The reference to the xml permissions module created by the source module.
- // Is nil if the source module does not exist.
- xmlPermissionsFileModule *sdkLibraryXml
-
// Build path to the dex implementation jar obtained from the prebuilt_apex, if any.
dexJarFile OptionalDexJarPath
dexJarFileErr error
@@ -2059,9 +2141,16 @@
var _ android.ApexModule = (*SdkLibraryImport)(nil)
// Implements android.ApexModule
-func (module *SdkLibraryImport) DepIsInSameApex(mctx android.BaseModuleContext, dep android.Module) bool {
- depTag := mctx.OtherModuleDependencyTag(dep)
- if depTag == xmlPermissionsFileTag {
+func (m *SdkLibraryImport) GetDepInSameApexChecker() android.DepInSameApexChecker {
+ return SdkLibraryImportDepIsInSameApexChecker{}
+}
+
+type SdkLibraryImportDepIsInSameApexChecker struct {
+ android.BaseDepInSameApexChecker
+}
+
+func (m SdkLibraryImportDepIsInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
+ if tag == xmlPermissionsFileTag {
return true
}
@@ -2071,13 +2160,10 @@
}
// Implements android.ApexModule
-func (module *SdkLibraryImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
- sdkVersion android.ApiLevel) error {
- // we don't check prebuilt modules for sdk_version
- return nil
+func (m *SdkLibraryImport) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
+ return android.MinApiLevel
}
-// Implements android.ApexModule
func (module *SdkLibraryImport) UniqueApexVariations() bool {
return module.uniqueApexVariations()
}
@@ -2094,7 +2180,7 @@
module.installFile = android.PathForModuleInstall(ctx, "framework", module.Stem()+".jar")
// Record the paths to the prebuilt stubs library and stubs source.
- ctx.VisitDirectDeps(func(to android.Module) {
+ ctx.VisitDirectDepsProxy(func(to android.ModuleProxy) {
tag := ctx.OtherModuleDependencyTag(to)
// Extract information from any of the scope specific dependencies.
@@ -2106,17 +2192,11 @@
// is determined by the nature of the dependency which is determined by the tag.
scopeTag.extractDepInfo(ctx, to, scopePaths)
} else if tag == implLibraryTag {
- if implLibrary, ok := to.(*Library); ok {
- module.implLibraryModule = implLibrary
+ if implInfo, ok := android.OtherModuleProvider(ctx, to, JavaInfoProvider); ok {
+ module.implLibraryInfo = implInfo
} else {
ctx.ModuleErrorf("implementation library must be of type *java.Library but was %T", to)
}
- } else if tag == xmlPermissionsFileTag {
- if xmlPermissionsFileModule, ok := to.(*sdkLibraryXml); ok {
- module.xmlPermissionsFileModule = xmlPermissionsFileModule
- } else {
- ctx.ModuleErrorf("xml permissions file module must be of type *sdkLibraryXml but was %T", to)
- }
}
})
sdkLibInfo := module.generateCommonBuildActions(ctx)
@@ -2156,12 +2236,21 @@
}
module.setOutputFiles(ctx)
- if module.implLibraryModule != nil {
+ if module.implLibraryInfo != nil {
generatingLibs = append(generatingLibs, module.implLibraryModuleName())
- setOutputFiles(ctx, module.implLibraryModule.Module)
+ setOutputFilesFromJavaInfo(ctx, module.implLibraryInfo)
}
+ javaInfo := &JavaInfo{}
+ if module.implLibraryInfo != nil {
+ javaInfo.JacocoReportClassesFile = module.implLibraryInfo.JacocoReportClassesFile
+ }
+
+ setExtraJavaInfo(ctx, ctx.Module(), javaInfo)
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+
sdkLibInfo.GeneratingLibs = generatingLibs
+ sdkLibInfo.Prebuilt = true
android.SetProvider(ctx, SdkLibraryInfoProvider, sdkLibInfo)
}
@@ -2177,10 +2266,10 @@
if module.dexJarFile.IsSet() {
return module.dexJarFile
}
- if module.implLibraryModule == nil {
+ if module.implLibraryInfo == nil {
return makeUnsetDexJarPath()
} else {
- return module.implLibraryModule.DexJarBuildPath(ctx)
+ return module.implLibraryInfo.DexJarFile
}
}
@@ -2196,10 +2285,10 @@
// to satisfy apex.javaDependency interface
func (module *SdkLibraryImport) JacocoReportClassesFile() android.Path {
- if module.implLibraryModule == nil {
+ if module.implLibraryInfo == nil {
return nil
} else {
- return module.implLibraryModule.JacocoReportClassesFile()
+ return module.implLibraryInfo.JacocoReportClassesFile
}
}
@@ -2212,19 +2301,19 @@
// to satisfy java.ApexDependency interface
func (module *SdkLibraryImport) HeaderJars() android.Paths {
- if module.implLibraryModule == nil {
+ if module.implLibraryInfo == nil {
return nil
} else {
- return module.implLibraryModule.HeaderJars()
+ return module.implLibraryInfo.HeaderJars
}
}
// to satisfy java.ApexDependency interface
func (module *SdkLibraryImport) ImplementationAndResourcesJars() android.Paths {
- if module.implLibraryModule == nil {
+ if module.implLibraryInfo == nil {
return nil
} else {
- return module.implLibraryModule.ImplementationAndResourcesJars()
+ return module.implLibraryInfo.ImplementationAndResourcesJars
}
}
@@ -2389,8 +2478,7 @@
s.Min_device_sdk = sdk.commonSdkLibraryProperties.Min_device_sdk
s.Max_device_sdk = sdk.commonSdkLibraryProperties.Max_device_sdk
- implLibrary := sdk.implLibraryModule
- if implLibrary != nil && implLibrary.dexpreopter.dexpreoptProperties.Dex_preopt_result.Profile_guided {
+ if sdk.implLibraryInfo != nil && sdk.implLibraryInfo.ProfileGuided {
s.DexPreoptProfileGuided = proptools.BoolPtr(true)
}
}
diff --git a/java/sdk_library_internal.go b/java/sdk_library_internal.go
index 768e57a..f5feabe 100644
--- a/java/sdk_library_internal.go
+++ b/java/sdk_library_internal.go
@@ -15,12 +15,13 @@
package java
import (
- "android/soong/android"
- "android/soong/etc"
"fmt"
"path"
"strings"
+ "android/soong/android"
+ "android/soong/etc"
+
"github.com/google/blueprint/proptools"
)
@@ -173,6 +174,20 @@
mctx.CreateModule(LibraryFactory, properties...)
}
+// getApiSurfaceForScope returns the api surface name to use for the apiScope. If one is specified
+// in the corresponding ApiScopeProperties.Api_surface property that is used, otherwise the name of
+// the apiScope is used.
+func (module *SdkLibrary) getApiSurfaceForScope(apiScope *apiScope) *string {
+ scopeProperties := module.scopeToProperties[apiScope]
+
+ apiSurface := scopeProperties.Api_surface
+ if apiSurface == nil {
+ apiSurface = &apiScope.name
+ }
+
+ return apiSurface
+}
+
// Creates the [Droidstubs] module with ".stubs.source.<[apiScope.name]>" that creates stubs
// source files from the given full source files and also updates and checks the API
// specification files (i.e. "*-current.txt", "*-removed.txt" files).
@@ -226,7 +241,7 @@
props.Srcs = append(props.Srcs, module.properties.Srcs...)
props.Srcs = append(props.Srcs, module.sdkLibraryProperties.Api_srcs...)
props.Sdk_version = module.deviceProperties.Sdk_version
- props.Api_surface = &apiScope.name
+ props.Api_surface = module.getApiSurfaceForScope(apiScope)
props.System_modules = module.deviceProperties.System_modules
props.Installable = proptools.BoolPtr(false)
// A droiddoc module has only one Libs property and doesn't distinguish between
@@ -778,7 +793,11 @@
// from android.ApexModule
func (module *sdkLibraryXml) AvailableFor(what string) bool {
- return true
+ return android.CheckAvailableForApex(what, module.ApexAvailableFor())
+}
+
+func (module *sdkLibraryXml) ApexAvailableFor() []string {
+ return []string{android.AvailableToPlatform, android.AvailableToAnyApex}
}
func (module *sdkLibraryXml) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -788,10 +807,8 @@
var _ android.ApexModule = (*sdkLibraryXml)(nil)
// Implements android.ApexModule
-func (module *sdkLibraryXml) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
- sdkVersion android.ApiLevel) error {
- // sdkLibraryXml doesn't need to be checked separately because java_sdk_library is checked
- return nil
+func (m *sdkLibraryXml) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
+ return android.MinApiLevel
}
// File path to the runtime implementation library
@@ -919,6 +936,8 @@
ctx.PackageFile(module.installDirPath, libName+".xml", module.outputFilePath)
ctx.SetOutputFiles(android.OutputPaths{module.outputFilePath}.Paths(), "")
+
+ etc.SetCommonPrebuiltEtcInfo(ctx, module)
}
func (module *sdkLibraryXml) AndroidMkEntries() []android.AndroidMkEntries {
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index 6031d72..6d27e54 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -25,6 +25,7 @@
)
func TestJavaSdkLibrary(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -114,19 +115,19 @@
`)
// check the existence of the internal modules
- foo := result.ModuleForTests("foo", "android_common")
- result.ModuleForTests(apiScopePublic.stubsLibraryModuleName("foo"), "android_common")
- result.ModuleForTests(apiScopeSystem.stubsLibraryModuleName("foo"), "android_common")
- result.ModuleForTests(apiScopeTest.stubsLibraryModuleName("foo"), "android_common")
- result.ModuleForTests(apiScopePublic.stubsSourceModuleName("foo"), "android_common")
- result.ModuleForTests(apiScopeSystem.stubsSourceModuleName("foo"), "android_common")
- result.ModuleForTests(apiScopeTest.stubsSourceModuleName("foo"), "android_common")
- result.ModuleForTests(apiScopePublic.stubsSourceModuleName("foo")+".api.contribution", "")
- result.ModuleForTests(apiScopePublic.apiLibraryModuleName("foo"), "android_common")
- result.ModuleForTests("foo"+sdkXmlFileSuffix, "android_common")
- result.ModuleForTests("foo.api.public.28", "")
- result.ModuleForTests("foo.api.system.28", "")
- result.ModuleForTests("foo.api.test.28", "")
+ foo := result.ModuleForTests(t, "foo", "android_common")
+ result.ModuleForTests(t, apiScopePublic.stubsLibraryModuleName("foo"), "android_common")
+ result.ModuleForTests(t, apiScopeSystem.stubsLibraryModuleName("foo"), "android_common")
+ result.ModuleForTests(t, apiScopeTest.stubsLibraryModuleName("foo"), "android_common")
+ result.ModuleForTests(t, apiScopePublic.stubsSourceModuleName("foo"), "android_common")
+ result.ModuleForTests(t, apiScopeSystem.stubsSourceModuleName("foo"), "android_common")
+ result.ModuleForTests(t, apiScopeTest.stubsSourceModuleName("foo"), "android_common")
+ result.ModuleForTests(t, apiScopePublic.stubsSourceModuleName("foo")+".api.contribution", "")
+ result.ModuleForTests(t, apiScopePublic.apiLibraryModuleName("foo"), "android_common")
+ result.ModuleForTests(t, "foo"+sdkXmlFileSuffix, "android_common")
+ result.ModuleForTests(t, "foo.api.public.28", "")
+ result.ModuleForTests(t, "foo.api.system.28", "")
+ result.ModuleForTests(t, "foo.api.test.28", "")
exportedComponentsInfo, _ := android.OtherModuleProvider(result, foo.Module(), android.ExportedComponentsInfoProvider)
expectedFooExportedComponents := []string{
@@ -146,28 +147,28 @@
}
android.AssertArrayString(t, "foo exported components", expectedFooExportedComponents, exportedComponentsInfo.Components)
- bazJavac := result.ModuleForTests("baz", "android_common").Rule("javac")
+ bazJavac := result.ModuleForTests(t, "baz", "android_common").Rule("javac")
// tests if baz is actually linked to the stubs lib
- android.AssertStringDoesContain(t, "baz javac classpath", bazJavac.Args["classpath"], "foo.stubs.system.jar")
+ android.AssertStringDoesContain(t, "baz javac classpath", bazJavac.Args["classpath"], "foo.stubs.system.from-text.jar")
// ... and not to the impl lib
android.AssertStringDoesNotContain(t, "baz javac classpath", bazJavac.Args["classpath"], "foo.jar")
// test if baz is not linked to the system variant of foo
android.AssertStringDoesNotContain(t, "baz javac classpath", bazJavac.Args["classpath"], "foo.stubs.jar")
- bazTestJavac := result.ModuleForTests("baz-test", "android_common").Rule("javac")
+ bazTestJavac := result.ModuleForTests(t, "baz-test", "android_common").Rule("javac")
// tests if baz-test is actually linked to the test stubs lib
- android.AssertStringDoesContain(t, "baz-test javac classpath", bazTestJavac.Args["classpath"], "foo.stubs.test.jar")
+ android.AssertStringDoesContain(t, "baz-test javac classpath", bazTestJavac.Args["classpath"], "foo.stubs.test.from-text.jar")
- baz29Javac := result.ModuleForTests("baz-29", "android_common").Rule("javac")
+ baz29Javac := result.ModuleForTests(t, "baz-29", "android_common").Rule("javac")
// tests if baz-29 is actually linked to the system 29 stubs lib
- android.AssertStringDoesContain(t, "baz-29 javac classpath", baz29Javac.Args["classpath"], "prebuilts/sdk/sdk_system_29_foo/android_common/combined/sdk_system_29_foo.jar")
+ android.AssertStringDoesContain(t, "baz-29 javac classpath", baz29Javac.Args["classpath"], "prebuilts/sdk/sdk_system_29_foo/android_common/local-combined/sdk_system_29_foo.jar")
- bazModule30Javac := result.ModuleForTests("baz-module-30", "android_common").Rule("javac")
+ bazModule30Javac := result.ModuleForTests(t, "baz-module-30", "android_common").Rule("javac")
// tests if "baz-module-30" is actually linked to the module 30 stubs lib
- android.AssertStringDoesContain(t, "baz-module-30 javac classpath", bazModule30Javac.Args["classpath"], "prebuilts/sdk/sdk_module-lib_30_foo/android_common/combined/sdk_module-lib_30_foo.jar")
+ android.AssertStringDoesContain(t, "baz-module-30 javac classpath", bazModule30Javac.Args["classpath"], "prebuilts/sdk/sdk_module-lib_30_foo/android_common/local-combined/sdk_module-lib_30_foo.jar")
// test if baz has exported SDK lib names foo and bar to qux
- qux := result.ModuleForTests("qux", "android_common")
+ qux := result.ModuleForTests(t, "qux", "android_common")
if quxLib, ok := qux.Module().(*Library); ok {
requiredSdkLibs, optionalSdkLibs := quxLib.ClassLoaderContexts().UsesLibs()
android.AssertDeepEquals(t, "qux exports (required)", []string{"fred", "quuz", "foo", "bar"}, requiredSdkLibs)
@@ -175,18 +176,19 @@
}
// test if quuz have created the api_contribution module
- result.ModuleForTests(apiScopePublic.stubsSourceModuleName("quuz")+".api.contribution", "")
+ result.ModuleForTests(t, apiScopePublic.stubsSourceModuleName("quuz")+".api.contribution", "")
- fooImplDexJar := result.ModuleForTests("foo.impl", "android_common").Rule("d8")
+ fooImplDexJar := result.ModuleForTests(t, "foo.impl", "android_common").Rule("d8")
// tests if kotlinc generated files are NOT excluded from output of foo.impl.
android.AssertStringDoesNotContain(t, "foo.impl dex", fooImplDexJar.BuildParams.Args["mergeZipsFlags"], "-stripFile META-INF/*.kotlin_module")
- barImplDexJar := result.ModuleForTests("bar.impl", "android_common").Rule("d8")
+ barImplDexJar := result.ModuleForTests(t, "bar.impl", "android_common").Rule("d8")
// tests if kotlinc generated files are excluded from output of bar.impl.
android.AssertStringDoesContain(t, "bar.impl dex", barImplDexJar.BuildParams.Args["mergeZipsFlags"], "-stripFile META-INF/*.kotlin_module")
}
func TestJavaSdkLibrary_UpdatableLibrary(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -218,7 +220,7 @@
`)
// test that updatability attributes are passed on correctly
- fooUpdatable := result.ModuleForTests("fooUpdatable.xml", "android_common").Output("fooUpdatable.xml")
+ fooUpdatable := result.ModuleForTests(t, "fooUpdatable.xml", "android_common").Output("fooUpdatable.xml")
fooUpdatableContents := android.ContentFromFileRuleForTests(t, result.TestContext, fooUpdatable)
android.AssertStringDoesContain(t, "fooUpdatable.xml contents", fooUpdatableContents, `on-bootclasspath-since="U"`)
android.AssertStringDoesContain(t, "fooUpdatable.xml contents", fooUpdatableContents, `on-bootclasspath-before="V"`)
@@ -227,7 +229,7 @@
// double check that updatability attributes are not written if they don't exist in the bp file
// the permissions file for the foo library defined above
- fooPermissions := result.ModuleForTests("foo.xml", "android_common").Output("foo.xml")
+ fooPermissions := result.ModuleForTests(t, "foo.xml", "android_common").Output("foo.xml")
fooPermissionsContents := android.ContentFromFileRuleForTests(t, result.TestContext, fooPermissions)
android.AssertStringDoesNotContain(t, "foo.xml contents", fooPermissionsContents, `on-bootclasspath-since`)
android.AssertStringDoesNotContain(t, "foo.xml contents", fooPermissionsContents, `on-bootclasspath-before`)
@@ -236,6 +238,7 @@
}
func TestJavaSdkLibrary_UpdatableLibrary_Validation_ValidVersion(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -263,6 +266,7 @@
}
func TestJavaSdkLibrary_UpdatableLibrary_Validation_AtLeastTAttributes(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -292,6 +296,7 @@
}
func TestJavaSdkLibrary_UpdatableLibrary_Validation_MinAndMaxDeviceSdk(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -319,6 +324,7 @@
}
func TestJavaSdkLibrary_UpdatableLibrary_Validation_MinAndMaxDeviceSdkAndModuleMinSdk(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -347,6 +353,7 @@
}
func TestJavaSdkLibrary_UpdatableLibrary_usesNewTag(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -363,13 +370,14 @@
}
`)
// test that updatability attributes are passed on correctly
- fooUpdatable := result.ModuleForTests("foo.xml", "android_common").Output("foo.xml")
+ fooUpdatable := result.ModuleForTests(t, "foo.xml", "android_common").Output("foo.xml")
fooUpdatableContents := android.ContentFromFileRuleForTests(t, result.TestContext, fooUpdatable)
android.AssertStringDoesContain(t, "foo.xml contents", fooUpdatableContents, `<apex-library`)
android.AssertStringDoesNotContain(t, "foo.xml contents", fooUpdatableContents, `<library`)
}
func TestJavaSdkLibrary_StubOrImplOnlyLibs(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -409,12 +417,12 @@
{lib: "stub-only-static-lib", in_stub_combined: true},
}
verify := func(sdklib, dep string, cp, combined bool) {
- sdklibCp := result.ModuleForTests(sdklib, "android_common").Rule("javac").Args["classpath"]
+ sdklibCp := result.ModuleForTests(t, sdklib, "android_common").Rule("javac").Args["classpath"]
expected := cp || combined // Every combined jar is also on the classpath.
android.AssertStringContainsEquals(t, "bad classpath for "+sdklib, sdklibCp, "/"+dep+".jar", expected)
- combineJarInputs := result.ModuleForTests(sdklib, "android_common").Rule("combineJar").Inputs.Strings()
- depPath := filepath.Join("out", "soong", ".intermediates", dep, "android_common", "turbine-combined", dep+".jar")
+ combineJarInputs := result.ModuleForTests(t, sdklib, "android_common").Rule("combineJar").Inputs.Strings()
+ depPath := filepath.Join("out", "soong", ".intermediates", dep, "android_common", "turbine", dep+".jar")
android.AssertStringListContainsEquals(t, "bad combined inputs for "+sdklib, combineJarInputs, depPath, combined)
}
for _, expectation := range expectations {
@@ -426,6 +434,7 @@
}
func TestJavaSdkLibrary_DoNotAccessImplWhenItIsNotBuilt(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -448,13 +457,14 @@
`)
// The bar library should depend on the stubs jar.
- barLibrary := result.ModuleForTests("bar", "android_common").Rule("javac")
- if expected, actual := `^-classpath .*:out/soong/[^:]*/turbine-combined/foo\.stubs\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
+ barLibrary := result.ModuleForTests(t, "bar", "android_common").Rule("javac")
+ if expected, actual := `^-classpath .*:out/soong/[^:]*/foo\.stubs\.from-text/foo\.stubs\.from-text\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
t.Errorf("expected %q, found %#q", expected, actual)
}
}
func TestJavaSdkLibrary_AccessOutputFiles(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -478,12 +488,13 @@
}
func TestJavaSdkLibrary_AccessOutputFiles_NoAnnotations(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
FixtureWithLastReleaseApis("foo"),
).
- ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "bar" variant "android_common": unsupported module reference tag ".public.annotations.zip"`)).
+ ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "bar" variant "android_common": unsupported output tag ".public.annotations.zip"`)).
RunTestWithBp(t, `
java_sdk_library {
name: "foo",
@@ -503,12 +514,13 @@
}
func TestJavaSdkLibrary_AccessOutputFiles_MissingScope(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
FixtureWithLastReleaseApis("foo"),
).
- ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "bar" variant "android_common": unsupported module reference tag ".system.stubs.source"`)).
+ ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "bar" variant "android_common": unsupported output tag ".system.stubs.source"`)).
RunTestWithBp(t, `
java_sdk_library {
name: "foo",
@@ -527,6 +539,7 @@
}
func TestJavaSdkLibrary_Deps(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -557,6 +570,7 @@
}
func TestJavaSdkLibraryImport_AccessOutputFiles(t *testing.T) {
+ t.Parallel()
prepareForJavaTest.RunTestWithBp(t, `
java_sdk_library_import {
name: "foo",
@@ -582,6 +596,7 @@
}
func TestJavaSdkLibraryImport_AccessOutputFiles_Invalid(t *testing.T) {
+ t.Parallel()
bp := `
java_sdk_library_import {
name: "foo",
@@ -592,6 +607,7 @@
`
t.Run("stubs.source", func(t *testing.T) {
+ t.Parallel()
prepareForJavaTest.
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo" is not a SourceFileProducer or having valid output file for tag ".public.stubs.source"`)).
RunTestWithBp(t, bp+`
@@ -607,6 +623,7 @@
})
t.Run("api.txt", func(t *testing.T) {
+ t.Parallel()
prepareForJavaTest.
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo" is not a SourceFileProducer or having valid output file for tag ".public.api.txt"`)).
RunTestWithBp(t, bp+`
@@ -621,6 +638,7 @@
})
t.Run("removed-api.txt", func(t *testing.T) {
+ t.Parallel()
prepareForJavaTest.
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo" is not a SourceFileProducer or having valid output file for tag ".public.removed-api.txt"`)).
RunTestWithBp(t, bp+`
@@ -636,6 +654,7 @@
}
func TestJavaSdkLibrary_InvalidScopes(t *testing.T) {
+ t.Parallel()
prepareForJavaTest.
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo": enabled api scope "system" depends on disabled scope "public"`)).
RunTestWithBp(t, `
@@ -656,6 +675,7 @@
}
func TestJavaSdkLibrary_SdkVersion_ForScope(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -674,6 +694,7 @@
}
func TestJavaSdkLibrary_ModuleLib(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -694,6 +715,7 @@
}
func TestJavaSdkLibrary_SystemServer(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -714,6 +736,7 @@
}
func TestJavaSdkLibrary_SystemServer_AccessToStubScopeLibs(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -768,13 +791,13 @@
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)
+ return fmt.Sprintf("out/soong/.intermediates/%[1]s.from-text/android_common/%[1]s.from-text/%[1]s.from-text.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")
+ barLibrary := result.ModuleForTests(t, "bar", "android_common").Rule("javac")
stubLibraries := []string{
stubsPath("foo-public", apiScopePublic),
stubsPath("foo-system", apiScopeSystem),
@@ -788,6 +811,7 @@
}
func TestJavaSdkLibraryImport(t *testing.T) {
+ t.Parallel()
result := prepareForJavaTest.RunTestWithBp(t, `
java_library {
name: "foo",
@@ -826,10 +850,10 @@
`)
for _, scope := range []string{"", ".system", ".test"} {
- fooModule := result.ModuleForTests("foo"+scope, "android_common")
+ fooModule := result.ModuleForTests(t, "foo"+scope, "android_common")
javac := fooModule.Rule("javac")
- sdklibStubsJar := result.ModuleForTests("sdklib.stubs"+scope, "android_common").Output("combined/sdklib.stubs" + scope + ".jar").Output
+ sdklibStubsJar := result.ModuleForTests(t, "sdklib.stubs"+scope, "android_common").Output("local-combined/sdklib.stubs" + scope + ".jar").Output
android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], sdklibStubsJar.String())
}
@@ -844,6 +868,7 @@
}
func TestJavaSdkLibraryImport_WithSource(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -968,25 +993,25 @@
CheckModuleDependencies(t, result.TestContext, "combined", "android_common", []string{
// Each use of :sdklib{...} adds a dependency onto prebuilt_sdklib.
`prebuilt_sdklib`,
- `prebuilt_sdklib`,
- `prebuilt_sdklib`,
`prebuilt_sdklib.stubs`,
`prebuilt_sdklib.stubs.source`,
})
// Make sure that dependencies on sdklib that resolve to one of the child libraries use the
// prebuilt library.
- public := result.ModuleForTests("public", "android_common")
+ public := result.ModuleForTests(t, "public", "android_common")
rule := public.Output("javac/public.jar")
inputs := rule.Implicits.Strings()
- expected := "out/soong/.intermediates/prebuilt_sdklib.stubs/android_common/combined/sdklib.stubs.jar"
+ expected := "out/soong/.intermediates/prebuilt_sdklib.stubs/android_common/local-combined/sdklib.stubs.jar"
if !android.InList(expected, inputs) {
t.Errorf("expected %q to contain %q", inputs, expected)
}
}
func TestJavaSdkLibraryImport_Preferred(t *testing.T) {
+ t.Parallel()
t.Run("prefer", func(t *testing.T) {
+ t.Parallel()
testJavaSdkLibraryImport_Preferred(t, "prefer: true,", android.NullFixturePreparer)
})
}
@@ -994,6 +1019,7 @@
// If a module is listed in `mainline_module_contributions, it should be used
// It will supersede any other source vs prebuilt selection mechanism like `prefer` attribute
func TestSdkLibraryImport_MetadataModuleSupersedesPreferred(t *testing.T) {
+ t.Parallel()
bp := `
apex_contributions {
name: "my_mainline_module_contributions",
@@ -1093,17 +1119,17 @@
).RunTestWithBp(t, bp)
// Make sure that rdeps get the correct source vs prebuilt based on mainline_module_contributions
- public := result.ModuleForTests("public", "android_common")
+ public := result.ModuleForTests(t, "public", "android_common")
rule := public.Output("javac/public.jar")
inputs := rule.Implicits.Strings()
expectedInputs := []string{
// source
- "out/soong/.intermediates/sdklib.prebuilt_preferred_using_legacy_flags.stubs/android_common/turbine-combined/sdklib.prebuilt_preferred_using_legacy_flags.stubs.jar",
- "out/soong/.intermediates/sdklib.prebuilt_preferred_using_legacy_flags.stubs.system/android_common/turbine-combined/sdklib.prebuilt_preferred_using_legacy_flags.stubs.system.jar",
+ "out/soong/.intermediates/sdklib.prebuilt_preferred_using_legacy_flags.stubs.from-text/android_common/sdklib.prebuilt_preferred_using_legacy_flags.stubs.from-text/sdklib.prebuilt_preferred_using_legacy_flags.stubs.from-text.jar",
+ "out/soong/.intermediates/sdklib.prebuilt_preferred_using_legacy_flags.stubs.system.from-text/android_common/sdklib.prebuilt_preferred_using_legacy_flags.stubs.system.from-text/sdklib.prebuilt_preferred_using_legacy_flags.stubs.system.from-text.jar",
// prebuilt
- "out/soong/.intermediates/prebuilt_sdklib.source_preferred_using_legacy_flags.stubs/android_common/combined/sdklib.source_preferred_using_legacy_flags.stubs.jar",
- "out/soong/.intermediates/prebuilt_sdklib.source_preferred_using_legacy_flags.stubs.system/android_common/combined/sdklib.source_preferred_using_legacy_flags.stubs.system.jar",
+ "out/soong/.intermediates/prebuilt_sdklib.source_preferred_using_legacy_flags.stubs/android_common/local-combined/sdklib.source_preferred_using_legacy_flags.stubs.jar",
+ "out/soong/.intermediates/prebuilt_sdklib.source_preferred_using_legacy_flags.stubs.system/android_common/local-combined/sdklib.source_preferred_using_legacy_flags.stubs.system.jar",
}
for _, expected := range expectedInputs {
if !android.InList(expected, inputs) {
@@ -1113,6 +1139,7 @@
}
func TestJavaSdkLibraryDist(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
PrepareForTestWithJavaBuildComponents,
PrepareForTestWithJavaDefaultModules,
@@ -1179,7 +1206,8 @@
for _, tt := range testCases {
t.Run(tt.module, func(t *testing.T) {
- m := result.ModuleForTests(apiScopePublic.exportableStubsLibraryModuleName(tt.module), "android_common").Module().(*Library)
+ t.Parallel()
+ m := result.ModuleForTests(t, apiScopePublic.exportableStubsLibraryModuleName(tt.module), "android_common").Module().(*Library)
dists := m.Dists()
if len(dists) != 1 {
t.Fatalf("expected exactly 1 dist entry, got %d", len(dists))
@@ -1195,6 +1223,7 @@
}
func TestSdkLibrary_CheckMinSdkVersion(t *testing.T) {
+ t.Parallel()
preparer := android.GroupFixturePreparers(
PrepareForTestWithJavaBuildComponents,
PrepareForTestWithJavaDefaultModules,
@@ -1279,6 +1308,7 @@
}
func TestJavaSdkLibrary_StubOnlyLibs_PassedToDroidstubs(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -1300,12 +1330,13 @@
`)
// The foo.stubs.source should depend on bar-lib
- fooStubsSources := result.ModuleForTests("foo.stubs.source", "android_common").Module().(*Droidstubs)
+ fooStubsSources := result.ModuleForTests(t, "foo.stubs.source", "android_common").Module().(*Droidstubs)
eval := fooStubsSources.ConfigurableEvaluator(android.PanickingConfigAndErrorContext(result.TestContext))
android.AssertStringListContains(t, "foo stubs should depend on bar-lib", fooStubsSources.Javadoc.properties.Libs.GetOrDefault(eval, nil), "bar-lib")
}
func TestJavaSdkLibrary_Scope_Libs_PassedToDroidstubs(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -1327,12 +1358,13 @@
`)
// The foo.stubs.source should depend on bar-lib
- fooStubsSources := result.ModuleForTests("foo.stubs.source", "android_common").Module().(*Droidstubs)
+ fooStubsSources := result.ModuleForTests(t, "foo.stubs.source", "android_common").Module().(*Droidstubs)
eval := fooStubsSources.ConfigurableEvaluator(android.PanickingConfigAndErrorContext(result.TestContext))
android.AssertStringListContains(t, "foo stubs should depend on bar-lib", fooStubsSources.Javadoc.properties.Libs.GetOrDefault(eval, nil), "bar-lib")
}
func TestJavaSdkLibrary_ApiLibrary(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -1377,12 +1409,13 @@
}
for _, c := range testCases {
- m := result.ModuleForTests(c.scope.apiLibraryModuleName("foo"), "android_common").Module().(*ApiLibrary)
+ m := result.ModuleForTests(t, c.scope.apiLibraryModuleName("foo"), "android_common").Module().(*ApiLibrary)
android.AssertArrayString(t, "Module expected to contain api contributions", c.apiContributions, m.properties.Api_contributions)
}
}
func TestStaticDepStubLibrariesVisibility(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -1412,6 +1445,7 @@
}
func TestSdkLibraryDependency(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -1438,12 +1472,13 @@
}
`)
- barPermissions := result.ModuleForTests("bar.xml", "android_common").Output("bar.xml")
+ barPermissions := result.ModuleForTests(t, "bar.xml", "android_common").Output("bar.xml")
barContents := android.ContentFromFileRuleForTests(t, result.TestContext, barPermissions)
android.AssertStringDoesContain(t, "bar.xml java_sdk_xml command", barContents, `dependency="foo"`)
}
func TestSdkLibraryExportableStubsLibrary(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -1480,8 +1515,8 @@
exportableSourceStubsLibraryModuleName := apiScopePublic.exportableSourceStubsLibraryModuleName("foo")
// Check modules generation
- result.ModuleForTests(exportableStubsLibraryModuleName, "android_common")
- result.ModuleForTests(exportableSourceStubsLibraryModuleName, "android_common")
+ result.ModuleForTests(t, exportableStubsLibraryModuleName, "android_common")
+ result.ModuleForTests(t, exportableSourceStubsLibraryModuleName, "android_common")
// Check static lib dependency
android.AssertBoolEquals(t, "exportable top level stubs library module depends on the"+
@@ -1494,6 +1529,7 @@
// For java libraries depending on java_sdk_library(_import) via libs, assert that
// rdep gets stubs of source if source is listed in apex_contributions and prebuilt has prefer (legacy mechanism)
func TestStubResolutionOfJavaSdkLibraryInLibs(t *testing.T) {
+ t.Parallel()
bp := `
apex_contributions {
name: "my_mainline_module_contributions",
@@ -1539,14 +1575,16 @@
result := fixture.RunTestWithBp(t, bp)
// Make sure that rdeps get the correct source vs prebuilt based on mainline_module_contributions
- public := result.ModuleForTests("mymodule", "android_common")
+ public := result.ModuleForTests(t, "mymodule", "android_common")
rule := public.Output("javac/mymodule.jar")
inputs := rule.Implicits.Strings()
- android.AssertStringListContains(t, "Could not find the expected stub on classpath", inputs, "out/soong/.intermediates/sdklib.stubs/android_common/turbine-combined/sdklib.stubs.jar")
+ android.AssertStringListContains(t, "Could not find the expected stub on classpath", inputs,
+ "out/soong/.intermediates/sdklib.stubs.from-text/android_common/sdklib.stubs.from-text/sdklib.stubs.from-text.jar")
}
// test that rdep gets resolved to the correct version of a java_sdk_library (source or a specific prebuilt)
func TestMultipleSdkLibraryPrebuilts(t *testing.T) {
+ t.Parallel()
bp := `
apex_contributions {
name: "my_mainline_module_contributions",
@@ -1599,17 +1637,17 @@
{
desc: "Source library is selected using apex_contributions",
selectedDependencyName: "sdklib",
- expectedStubPath: "out/soong/.intermediates/sdklib.stubs/android_common/turbine-combined/sdklib.stubs.jar",
+ expectedStubPath: "out/soong/.intermediates/sdklib.stubs.from-text/android_common/sdklib.stubs.from-text/sdklib.stubs.from-text.jar",
},
{
desc: "Prebuilt library v1 is selected using apex_contributions",
selectedDependencyName: "prebuilt_sdklib.v1",
- expectedStubPath: "out/soong/.intermediates/prebuilt_sdklib.v1.stubs/android_common/combined/sdklib.stubs.jar",
+ expectedStubPath: "out/soong/.intermediates/prebuilt_sdklib.v1.stubs/android_common/local-combined/sdklib.stubs.jar",
},
{
desc: "Prebuilt library v2 is selected using apex_contributions",
selectedDependencyName: "prebuilt_sdklib.v2",
- expectedStubPath: "out/soong/.intermediates/prebuilt_sdklib.v2.stubs/android_common/combined/sdklib.stubs.jar",
+ expectedStubPath: "out/soong/.intermediates/prebuilt_sdklib.v2.stubs/android_common/local-combined/sdklib.stubs.jar",
},
}
@@ -1624,7 +1662,7 @@
result := fixture.RunTestWithBp(t, fmt.Sprintf(bp, tc.selectedDependencyName))
// Make sure that rdeps get the correct source vs prebuilt based on mainline_module_contributions
- public := result.ModuleForTests("mymodule", "android_common")
+ public := result.ModuleForTests(t, "mymodule", "android_common")
rule := public.Output("javac/mymodule.jar")
inputs := rule.Implicits.Strings()
android.AssertStringListContains(t, "Could not find the expected stub on classpath", inputs, tc.expectedStubPath)
@@ -1632,6 +1670,7 @@
}
func TestStubLinkType(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -1668,6 +1707,7 @@
}
func TestSdkLibDirectDependency(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
@@ -1732,6 +1772,7 @@
}
func TestSdkLibDirectDependencyWithPrebuiltSdk(t *testing.T) {
+ t.Parallel()
android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
diff --git a/java/sdk_test.go b/java/sdk_test.go
index 9bfe6a2..6386a00 100644
--- a/java/sdk_test.go
+++ b/java/sdk_test.go
@@ -53,6 +53,7 @@
}
func TestClasspath(t *testing.T) {
+ t.Parallel()
const frameworkAidl = "-I" + defaultJavaDir + "/framework/aidl"
var classpathTestcases = []classpathTestCase{
{
@@ -388,22 +389,18 @@
},
}
- t.Parallel()
t.Run("basic", func(t *testing.T) {
t.Parallel()
- testClasspathTestCases(t, classpathTestcases, false, false)
+ testClasspathTestCases(t, classpathTestcases, false)
})
t.Run("Always_use_prebuilt_sdks=true", func(t *testing.T) {
- testClasspathTestCases(t, classpathTestcases, true, false)
- })
-
- t.Run("UseTransitiveJarsInClasspath", func(t *testing.T) {
- testClasspathTestCases(t, classpathTestcases, false, true)
+ t.Parallel()
+ testClasspathTestCases(t, classpathTestcases, true)
})
}
-func testClasspathTestCases(t *testing.T, classpathTestcases []classpathTestCase, alwaysUsePrebuiltSdks, useTransitiveJarsInClasspath bool) {
+func testClasspathTestCases(t *testing.T, classpathTestcases []classpathTestCase, alwaysUsePrebuiltSdks bool) {
for _, testcase := range classpathTestcases {
if testcase.forAlwaysUsePrebuiltSdks != nil && *testcase.forAlwaysUsePrebuiltSdks != alwaysUsePrebuiltSdks {
continue
@@ -444,10 +441,8 @@
switch {
case e == `""`, strings.HasSuffix(e, ".jar"):
ret[i] = e
- case useTransitiveJarsInClasspath:
- ret[i] = filepath.Join("out", "soong", ".intermediates", defaultJavaDir, e, "android_common", "turbine", e+".jar")
default:
- ret[i] = filepath.Join("out", "soong", ".intermediates", defaultJavaDir, e, "android_common", "turbine-combined", e+".jar")
+ ret[i] = filepath.Join("out", "soong", ".intermediates", defaultJavaDir, e, "android_common", "turbine", e+".jar")
}
}
return ret
@@ -499,7 +494,7 @@
}
checkClasspath := func(t *testing.T, result *android.TestResult, isJava8 bool) {
- foo := result.ModuleForTests("foo", variant(result))
+ foo := result.ModuleForTests(t, "foo", variant(result))
javac := foo.Rule("javac")
var deps []string
@@ -542,9 +537,6 @@
variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
})
}
- if useTransitiveJarsInClasspath {
- preparer = PrepareForTestWithTransitiveClasspathEnabled
- }
fixtureFactory := android.GroupFixturePreparers(
prepareForJavaTest,
@@ -571,12 +563,13 @@
// Test with legacy javac -source 1.8 -target 1.8
t.Run("Java language level 8", func(t *testing.T) {
+ t.Parallel()
result := fixtureFactory.RunTestWithBp(t, bpJava8)
checkClasspath(t, result, true /* isJava8 */)
if testcase.host != android.Host {
- aidl := result.ModuleForTests("foo", variant(result)).Rule("aidl")
+ aidl := result.ModuleForTests(t, "foo", variant(result)).Rule("aidl")
android.AssertStringDoesContain(t, "aidl command", aidl.RuleParams.Command, testcase.aidl+" -I.")
}
@@ -584,12 +577,13 @@
// Test with default javac -source 9 -target 9
t.Run("Java language level 9", func(t *testing.T) {
+ t.Parallel()
result := fixtureFactory.RunTestWithBp(t, bp)
checkClasspath(t, result, false /* isJava8 */)
if testcase.host != android.Host {
- aidl := result.ModuleForTests("foo", variant(result)).Rule("aidl")
+ aidl := result.ModuleForTests(t, "foo", variant(result)).Rule("aidl")
android.AssertStringDoesContain(t, "aidl command", aidl.RuleParams.Command, testcase.aidl+" -I.")
}
@@ -602,6 +596,7 @@
// Test again with PLATFORM_VERSION_CODENAME=REL, javac -source 8 -target 8
t.Run("REL + Java language level 8", func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
fixtureFactory, prepareWithPlatformVersionRel).RunTestWithBp(t, bpJava8)
@@ -610,6 +605,7 @@
// Test again with PLATFORM_VERSION_CODENAME=REL, javac -source 9 -target 9
t.Run("REL + Java language level 9", func(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
fixtureFactory, prepareWithPlatformVersionRel).RunTestWithBp(t, bp)
diff --git a/java/sdk_version_test.go b/java/sdk_version_test.go
index 88351d2..03d55f7 100644
--- a/java/sdk_version_test.go
+++ b/java/sdk_version_test.go
@@ -25,6 +25,7 @@
}
func TestSystemSdkFromVendor(t *testing.T) {
+ t.Parallel()
fixtures := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
@@ -57,7 +58,7 @@
vendor: true,
sdk_version: "system_current",
}`)
- fooModule := result.ModuleForTests("foo", "android_common")
+ fooModule := result.ModuleForTests(t, "foo", "android_common")
fooClasspath := fooModule.Rule("javac").Args["classpath"]
android.AssertStringDoesContain(t, "foo classpath", fooClasspath, "prebuilts/sdk/34/system/android.jar")
diff --git a/java/support_libraries.go b/java/support_libraries.go
index c483fc1..f76eb11 100644
--- a/java/support_libraries.go
+++ b/java/support_libraries.go
@@ -28,7 +28,7 @@
func supportLibrariesMakeVarsProvider(ctx android.MakeVarsContext) {
var supportAars, supportJars []string
- ctx.VisitAllModules(func(module android.Module) {
+ ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
dir := ctx.ModuleDir(module)
switch {
case strings.HasPrefix(dir, "prebuilts/sdk/current/extras"),
@@ -47,11 +47,16 @@
return
}
- switch module.(type) {
- case *AndroidLibrary, *AARImport:
+ _, isAndroidLibrary := android.OtherModuleProvider(ctx, module, AndroidLibraryInfoProvider)
+ _, isAARImport := android.OtherModuleProvider(ctx, module, AARImportInfoProvider)
+ if isAndroidLibrary || isAARImport {
supportAars = append(supportAars, name)
- case *Library, *Import:
- supportJars = append(supportJars, name)
+ } else {
+ _, isJavaLibrary := android.OtherModuleProvider(ctx, module, JavaLibraryInfoProvider)
+ _, isJavaPlugin := android.OtherModuleProvider(ctx, module, JavaPluginInfoProvider)
+ if isJavaLibrary && !isJavaPlugin {
+ supportJars = append(supportJars, name)
+ }
}
})
diff --git a/java/system_modules_test.go b/java/system_modules_test.go
index b05b0e4..99301bc 100644
--- a/java/system_modules_test.go
+++ b/java/system_modules_test.go
@@ -51,10 +51,11 @@
`)
func TestJavaSystemModules(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(prepareForJavaTest, addSourceSystemModules).RunTest(t)
// check the existence of the source module
- sourceSystemModules := result.ModuleForTests("system-modules", "android_common")
+ sourceSystemModules := result.ModuleForTests(t, "system-modules", "android_common")
sourceInputs := sourceSystemModules.Rule("jarsTosystemModules").Inputs
// The expected paths are the header jars from the source input modules.
@@ -78,10 +79,11 @@
`)
func TestJavaSystemModulesImport(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(prepareForJavaTest, addPrebuiltSystemModules).RunTest(t)
// check the existence of the renamed prebuilt module
- prebuiltSystemModules := result.ModuleForTests("system-modules", "android_common")
+ prebuiltSystemModules := result.ModuleForTests(t, "system-modules", "android_common")
prebuiltInputs := prebuiltSystemModules.Rule("jarsTosystemModules").Inputs
// The expected paths are the header jars from the renamed prebuilt input modules.
@@ -90,6 +92,7 @@
}
func TestJavaSystemModulesMixSourceAndPrebuilt(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForJavaTest,
addSourceSystemModules,
@@ -97,7 +100,7 @@
).RunTest(t)
// check the existence of the source module
- sourceSystemModules := result.ModuleForTests("system-modules", "android_common")
+ sourceSystemModules := result.ModuleForTests(t, "system-modules", "android_common")
sourceInputs := sourceSystemModules.Rule("jarsTosystemModules").Inputs
// The expected paths are the header jars from the source input modules.
@@ -105,7 +108,7 @@
android.AssertArrayString(t, "source system modules inputs", expectedSourcePaths, sourceInputs.RelativeToTop().Strings())
// check the existence of the renamed prebuilt module
- prebuiltSystemModules := result.ModuleForTests("prebuilt_system-modules", "android_common")
+ prebuiltSystemModules := result.ModuleForTests(t, "prebuilt_system-modules", "android_common")
prebuiltInputs := prebuiltSystemModules.Rule("jarsTosystemModules").Inputs
// The expected paths are the header jars from the renamed prebuilt input modules.
@@ -114,6 +117,7 @@
}
func TestMultipleSystemModulesPrebuilts(t *testing.T) {
+ t.Parallel()
bp := `
// an rdep
java_library {
diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go
index 3176ad9..a60f6b8 100644
--- a/java/systemserver_classpath_fragment.go
+++ b/java/systemserver_classpath_fragment.go
@@ -58,6 +58,10 @@
return m
}
+func (m *platformSystemServerClasspathModule) UniqueApexVariations() bool {
+ return true
+}
+
func (p *platformSystemServerClasspathModule) AndroidMkEntries() (entries []android.AndroidMkEntries) {
return p.classpathFragmentBase().androidMkEntries()
}
@@ -91,8 +95,10 @@
properties systemServerClasspathFragmentProperties
}
-func (s *SystemServerClasspathModule) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
- return nil
+var _ android.ApexModule = (*SystemServerClasspathModule)(nil)
+
+func (m *SystemServerClasspathModule) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
+ return android.MinApiLevel
}
type systemServerClasspathFragmentProperties struct {
@@ -116,6 +122,10 @@
return m
}
+func (m *SystemServerClasspathModule) UniqueApexVariations() bool {
+ return true
+}
+
func (s *SystemServerClasspathModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
if len(s.properties.Contents.GetOrDefault(ctx, nil)) == 0 && len(s.properties.Standalone_contents.GetOrDefault(ctx, nil)) == 0 {
ctx.PropertyErrorf("contents", "Either contents or standalone_contents needs to be non-empty")
diff --git a/java/systemserver_classpath_fragment_test.go b/java/systemserver_classpath_fragment_test.go
index ba328e7..704f5a4 100644
--- a/java/systemserver_classpath_fragment_test.go
+++ b/java/systemserver_classpath_fragment_test.go
@@ -25,6 +25,7 @@
)
func TestPlatformSystemServerClasspathVariant(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForTestWithSystemServerClasspath,
android.FixtureWithRootAndroidBp(`
@@ -39,6 +40,7 @@
}
func TestPlatformSystemServerClasspath_ClasspathFragmentPaths(t *testing.T) {
+ t.Parallel()
result := android.GroupFixturePreparers(
prepareForTestWithSystemServerClasspath,
android.FixtureWithRootAndroidBp(`
@@ -50,10 +52,11 @@
p := result.Module("platform-systemserverclasspath", "android_common").(*platformSystemServerClasspathModule)
android.AssertStringEquals(t, "output filepath", "systemserverclasspath.pb", p.ClasspathFragmentBase.outputFilepath.Base())
- android.AssertPathRelativeToTopEquals(t, "install filepath", "out/soong/target/product/test_device/system/etc/classpaths", p.ClasspathFragmentBase.installDirPath)
+ android.AssertPathRelativeToTopEquals(t, "install filepath", "out/target/product/test_device/system/etc/classpaths", p.ClasspathFragmentBase.installDirPath)
}
func TestPlatformSystemServerClasspathModule_AndroidMkEntries(t *testing.T) {
+ t.Parallel()
preparer := android.GroupFixturePreparers(
prepareForTestWithSystemServerClasspath,
android.FixtureWithRootAndroidBp(`
@@ -97,6 +100,7 @@
}
func TestSystemServerClasspathFragmentWithoutContents(t *testing.T) {
+ t.Parallel()
prepareForTestWithSystemServerClasspath.
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
`\QEither contents or standalone_contents needs to be non-empty\E`)).
diff --git a/java/testing.go b/java/testing.go
index ba33d90..a6e72cf 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -18,7 +18,6 @@
"fmt"
"reflect"
"regexp"
- "sort"
"strings"
"testing"
@@ -237,29 +236,6 @@
)
}
-func FixtureWithPrebuiltIncrementalApis(apiLevel2Modules map[string][]string) android.FixturePreparer {
- mockFS := android.MockFS{}
- path := "prebuilts/sdk/Android.bp"
-
- bp := fmt.Sprintf(`
- prebuilt_apis {
- name: "sdk",
- api_dirs: ["%s"],
- allow_incremental_platform_api: true,
- imports_sdk_version: "none",
- imports_compile_dex: true,
- }
- `, strings.Join(android.SortedKeys(apiLevel2Modules), `", "`))
-
- for release, modules := range apiLevel2Modules {
- mockFS.Merge(prebuiltApisFilesForModules([]string{release}, modules))
- }
- return android.GroupFixturePreparers(
- android.FixtureAddTextFile(path, bp),
- android.FixtureMergeMockFs(mockFS),
- )
-}
-
func prebuiltApisFilesForModules(apiLevels []string, modules []string) map[string][]byte {
libs := append([]string{"android"}, modules...)
@@ -378,7 +354,6 @@
RegisterAppBuildComponents(ctx)
RegisterAppImportBuildComponents(ctx)
RegisterAppSetBuildComponents(ctx)
- registerBootclasspathBuildComponents(ctx)
registerBootclasspathFragmentBuildComponents(ctx)
RegisterDexpreoptBootJarsComponents(ctx)
RegisterDocsBuildComponents(ctx)
@@ -611,19 +586,18 @@
func getModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant string) []string {
t.Helper()
- module := ctx.ModuleForTests(name, variant).Module()
+ module := ctx.ModuleForTests(t, name, variant).Module()
deps := []string{}
ctx.VisitDirectDeps(module, func(m blueprint.Module) {
deps = append(deps, m.Name())
})
- sort.Strings(deps)
-
- return deps
+ return android.SortedUniqueStrings(deps)
}
// CheckModuleDependencies checks if the expected dependencies of the module are
// identical to the actual dependencies.
func CheckModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant string, expected []string) {
+ t.Helper()
deps := getModuleDependencies(t, ctx, name, variant)
if actual := deps; !reflect.DeepEqual(expected, actual) {
@@ -643,7 +617,7 @@
// CheckModuleHasDependency returns true if the module depends on the expected dependency.
func CheckModuleHasDependencyWithTag(t *testing.T, ctx *android.TestContext, name, variant string, desiredTag blueprint.DependencyTag, expected string) bool {
- module := ctx.ModuleForTests(name, variant).Module()
+ module := ctx.ModuleForTests(t, name, variant).Module()
found := false
ctx.VisitDirectDepsWithTags(module, func(m blueprint.Module, tag blueprint.DependencyTag) {
if tag == desiredTag && m.Name() == expected {
@@ -658,7 +632,7 @@
func CheckPlatformBootclasspathModules(t *testing.T, result *android.TestResult, name string, expected []string) {
t.Helper()
platformBootclasspath := result.Module(name, "android_common").(*platformBootclasspathModule)
- pairs := ApexNamePairsFromModules(result.TestContext, platformBootclasspath.configuredModules)
+ pairs := apexNamePairsFromModules(result.TestContext, platformBootclasspath.configuredModules, platformBootclasspath.libraryToApex)
android.AssertDeepEquals(t, fmt.Sprintf("%s modules", "platform-bootclasspath"), expected, pairs)
}
@@ -673,23 +647,54 @@
android.AssertPathRelativeToTopEquals(t, "install filepath", installDir, info.ClasspathFragmentProtoInstallDir)
}
-// ApexNamePairsFromModules returns the apex:module pair for the supplied modules.
-func ApexNamePairsFromModules(ctx *android.TestContext, modules []android.Module) []string {
+// CheckPlatformBootclasspathDependencies checks the dependencies of the selected module against the expected list.
+//
+// The expected list must be a list of strings of the form "<apex>:<module>", where <apex> is the
+// name of the apex, or platform is it is not part of an apex and <module> is the module name.
+func CheckPlatformBootclasspathDependencies(t *testing.T, ctx *android.TestContext, name, variant string, expected []string) {
+ t.Helper()
+ platformBootclasspath := ctx.ModuleForTests(t, name, variant).Module().(*platformBootclasspathModule)
+ modules := []android.Module{}
+ ctx.VisitDirectDeps(platformBootclasspath, func(m blueprint.Module) {
+ modules = append(modules, m.(android.Module))
+ })
+
+ pairs := apexNamePairsFromModules(ctx, modules, platformBootclasspath.libraryToApex)
+ android.AssertDeepEquals(t, "module dependencies", expected, pairs)
+}
+
+// apexNamePairsFromModules returns the apex:module pair for the supplied modules.
+func apexNamePairsFromModules(ctx *android.TestContext, modules []android.Module, modulesToApex map[android.Module]string) []string {
pairs := []string{}
for _, module := range modules {
- pairs = append(pairs, apexNamePairFromModule(ctx, module))
+ pairs = append(pairs, apexNamePairFromModule(ctx, module, modulesToApex))
}
return pairs
}
-func apexNamePairFromModule(ctx *android.TestContext, module android.Module) string {
+// ApexFragmentPairsFromModules returns the apex:fragment pair for the supplied fragments.
+func ApexFragmentPairsFromModules(ctx *android.TestContext, fragments []android.Module, apexNameToFragment map[string]android.Module) []string {
+ pairs := []string{}
+ for _, fragment := range fragments {
+ found := false
+ for apex, apexFragment := range apexNameToFragment {
+ if apexFragment == fragment {
+ pairs = append(pairs, apex+":"+ctx.ModuleName(fragment))
+ found = true
+ }
+ }
+ if !found {
+ pairs = append(pairs, "platform:"+ctx.ModuleName(fragment))
+ }
+ }
+ return pairs
+}
+
+func apexNamePairFromModule(ctx *android.TestContext, module android.Module, modulesToApex map[android.Module]string) string {
name := module.Name()
- var apex string
- apexInfo, _ := android.OtherModuleProvider(ctx, module, android.ApexInfoProvider)
- if apexInfo.IsForPlatform() {
+ apex := modulesToApex[module]
+ if apex == "" {
apex = "platform"
- } else {
- apex = apexInfo.InApexVariants[0]
}
return fmt.Sprintf("%s:%s", apex, name)
@@ -700,7 +705,7 @@
func CheckPlatformBootclasspathFragments(t *testing.T, result *android.TestResult, name string, expected []string) {
t.Helper()
platformBootclasspath := result.Module(name, "android_common").(*platformBootclasspathModule)
- pairs := ApexNamePairsFromModules(result.TestContext, platformBootclasspath.fragments)
+ pairs := ApexFragmentPairsFromModules(result.TestContext, platformBootclasspath.fragments, platformBootclasspath.apexNameToFragment)
android.AssertDeepEquals(t, fmt.Sprintf("%s fragments", "platform-bootclasspath"), expected, pairs)
}
@@ -723,7 +728,7 @@
// Check that the merged file create by platform_compat_config_singleton has the correct inputs.
func CheckMergedCompatConfigInputs(t *testing.T, result *android.TestResult, message string, expectedPaths ...string) {
- sourceGlobalCompatConfig := result.SingletonForTests("platform_compat_config_singleton")
+ sourceGlobalCompatConfig := result.SingletonForTests(t, "platform_compat_config_singleton")
allOutputs := sourceGlobalCompatConfig.AllOutputs()
android.AssertIntEquals(t, message+": output len", 1, len(allOutputs))
output := sourceGlobalCompatConfig.Output(allOutputs[0])
@@ -801,5 +806,3 @@
config.installDir = installDir
})
}
-
-var PrepareForTestWithTransitiveClasspathEnabled = android.PrepareForTestWithBuildFlag("RELEASE_USE_TRANSITIVE_JARS_IN_CLASSPATH", "true")
diff --git a/java/tracereferences.go b/java/tracereferences.go
new file mode 100644
index 0000000..342b6a6
--- /dev/null
+++ b/java/tracereferences.go
@@ -0,0 +1,54 @@
+// Copyright 2025 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 (
+ "android/soong/android"
+
+ "github.com/google/blueprint"
+)
+
+var traceReferences = pctx.AndroidStaticRule("traceReferences",
+ blueprint.RuleParams{
+ Command: `${config.TraceReferencesCmd} ` +
+ // Note that we suppress missing def errors, as we're only interested
+ // in the direct deps between the sources and target.
+ `--map-diagnostics:MissingDefinitionsDiagnostic error none ` +
+ `--keep-rules ` +
+ `--output ${out} ` +
+ `--target ${in} ` +
+ // `--source` and `--lib` are already prepended to each
+ // jar reference in the sources and libs joined string args.
+ `${sources} ` +
+ `${libs}`,
+ CommandDeps: []string{"${config.TraceReferencesCmd}"},
+ }, "sources", "libs")
+
+// Generates keep rules in output corresponding to any references from sources
+// (a list of jars) onto target (the referenced jar) that are not included in
+// libs (a list of external jars).
+func TraceReferences(ctx android.ModuleContext, sources android.Paths, target android.Path, libs android.Paths,
+ output android.WritablePath) {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: traceReferences,
+ Input: target,
+ Output: output,
+ Implicits: append(sources, libs...),
+ Args: map[string]string{
+ "sources": android.JoinWithPrefix(sources.Strings(), "--source "),
+ "libs": android.JoinWithPrefix(libs.Strings(), "--lib "),
+ },
+ })
+}