summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/Android.bp3
-rw-r--r--java/aar.go466
-rw-r--r--java/android_manifest_test.go103
-rw-r--r--java/androidmk.go31
-rwxr-xr-xjava/app.go152
-rw-r--r--java/app_builder.go33
-rw-r--r--java/app_import.go117
-rw-r--r--java/app_import_test.go23
-rw-r--r--java/app_test.go712
-rw-r--r--java/base.go153
-rw-r--r--java/bootclasspath.go5
-rw-r--r--java/bootclasspath_fragment.go270
-rw-r--r--java/bootclasspath_fragment_test.go35
-rw-r--r--java/builder.go74
-rw-r--r--java/config/config.go4
-rw-r--r--java/config/makevars.go3
-rw-r--r--java/core-libraries/Android.bp142
-rw-r--r--java/core-libraries/TxtStubLibraries.bp40
-rw-r--r--java/device_host_converter.go2
-rw-r--r--java/device_host_converter_test.go3
-rw-r--r--java/dex.go21
-rw-r--r--java/dexpreopt.go33
-rw-r--r--java/dexpreopt_bootjars.go337
-rw-r--r--java/dexpreopt_check.go2
-rw-r--r--java/dexpreopt_config.go95
-rw-r--r--java/dexpreopt_config_test.go20
-rw-r--r--java/dexpreopt_config_testing.go188
-rw-r--r--java/droiddoc.go5
-rw-r--r--java/droidstubs.go11
-rw-r--r--java/fuzz.go29
-rw-r--r--java/fuzz_test.go4
-rw-r--r--java/generated_java_library.go94
-rw-r--r--java/generated_java_library_test.go66
-rw-r--r--java/hiddenapi.go2
-rw-r--r--java/hiddenapi_modular.go7
-rw-r--r--java/hiddenapi_singleton.go8
-rw-r--r--java/java.go359
-rw-r--r--java/java_test.go103
-rw-r--r--java/jdeps.go2
-rw-r--r--java/kotlin.go4
-rw-r--r--java/lint.go18
-rw-r--r--java/platform_bootclasspath.go93
-rw-r--r--java/platform_compat_config.go25
-rw-r--r--java/prebuilt_apis.go83
-rw-r--r--java/resourceshrinker.go3
-rw-r--r--java/robolectric.go68
-rw-r--r--java/sdk.go24
-rw-r--r--java/sdk_library.go170
-rw-r--r--java/sdk_library_test.go66
-rw-r--r--java/testing.go31
50 files changed, 3304 insertions, 1038 deletions
diff --git a/java/Android.bp b/java/Android.bp
index 4af2a14eb..4450c4275 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -48,6 +48,7 @@ bootstrap_go_package {
"droidstubs.go",
"fuzz.go",
"gen.go",
+ "generated_java_library.go",
"genrule.go",
"hiddenapi.go",
"hiddenapi_modular.go",
@@ -79,6 +80,7 @@ bootstrap_go_package {
],
testSrcs: [
"aar_test.go",
+ "android_manifest_test.go",
"androidmk_test.go",
"app_import_test.go",
"app_set_test.go",
@@ -92,6 +94,7 @@ bootstrap_go_package {
"droidstubs_test.go",
"fuzz_test.go",
"genrule_test.go",
+ "generated_java_library_test.go",
"hiddenapi_singleton_test.go",
"jacoco_test.go",
"java_test.go",
diff --git a/java/aar.go b/java/aar.go
index f1b137de1..180e1d726 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -31,10 +31,9 @@ import (
type AndroidLibraryDependency interface {
LibraryDependency
ExportPackage() android.Path
- ExportedRRODirs() []rroDir
- ExportedStaticPackages() android.Paths
- ExportedManifests() android.Paths
- ExportedAssets() android.OptionalPath
+ ResourcesNodeDepSet() *android.DepSet[*resourcesNode]
+ RRODirsDepSet() *android.DepSet[rroDir]
+ ManifestsDepSet() *android.DepSet[android.Path]
SetRROEnforcedForDependent(enforce bool)
IsRROEnforced(ctx android.BaseModuleContext) bool
}
@@ -89,35 +88,49 @@ type aaptProperties struct {
// do not include AndroidManifest from dependent libraries
Dont_merge_manifests *bool
+ // If use_resource_processor is set, use Bazel's resource processor instead of aapt2 to generate R.class files.
+ // The resource processor produces more optimal R.class files that only list resources in the package of the
+ // library that provided them, as opposed to aapt2 which produces R.java files for every package containing
+ // every resource. Using the resource processor can provide significant build time speedups, but requires
+ // fixing the module to use the correct package to reference each resource, and to avoid having any other
+ // libraries in the tree that use the same package name. Defaults to false, but will default to true in the
+ // future.
+ Use_resource_processor *bool
+
// true if RRO is enforced for any of the dependent modules
RROEnforcedForDependent bool `blueprint:"mutated"`
}
type aapt struct {
- aaptSrcJar android.Path
- exportPackage android.Path
- manifestPath android.Path
- transitiveManifestPaths android.Paths
- proguardOptionsFile android.Path
- rroDirs []rroDir
- rTxt android.Path
- extraAaptPackagesFile android.Path
- mergedManifestFile android.Path
- noticeFile android.OptionalPath
- assetPackage android.OptionalPath
- isLibrary bool
- defaultManifestVersion string
- useEmbeddedNativeLibs bool
- useEmbeddedDex bool
- usesNonSdkApis bool
- hasNoCode bool
- LoggingParent string
- resourceFiles android.Paths
+ aaptSrcJar android.Path
+ transitiveAaptRJars android.Paths
+ transitiveAaptResourcePackages android.Paths
+ exportPackage android.Path
+ manifestPath android.Path
+ proguardOptionsFile android.Path
+ rTxt android.Path
+ rJar android.Path
+ extraAaptPackagesFile android.Path
+ mergedManifestFile android.Path
+ noticeFile android.OptionalPath
+ assetPackage android.OptionalPath
+ isLibrary bool
+ defaultManifestVersion string
+ useEmbeddedNativeLibs bool
+ useEmbeddedDex bool
+ usesNonSdkApis bool
+ hasNoCode bool
+ LoggingParent string
+ resourceFiles android.Paths
splitNames []string
splits []split
aaptProperties aaptProperties
+
+ resourcesNodesDepSet *android.DepSet[*resourcesNode]
+ rroDirsDepSet *android.DepSet[rroDir]
+ manifestsDepSet *android.DepSet[android.Path]
}
type split struct {
@@ -138,20 +151,23 @@ func propagateRROEnforcementMutator(ctx android.TopDownMutatorContext) {
}
}
+func (a *aapt) useResourceProcessorBusyBox() bool {
+ return BoolDefault(a.aaptProperties.Use_resource_processor, false)
+}
+
func (a *aapt) ExportPackage() android.Path {
return a.exportPackage
}
-
-func (a *aapt) ExportedRRODirs() []rroDir {
- return a.rroDirs
+func (a *aapt) ResourcesNodeDepSet() *android.DepSet[*resourcesNode] {
+ return a.resourcesNodesDepSet
}
-func (a *aapt) ExportedManifests() android.Paths {
- return a.transitiveManifestPaths
+func (a *aapt) RRODirsDepSet() *android.DepSet[rroDir] {
+ return a.rroDirsDepSet
}
-func (a *aapt) ExportedAssets() android.OptionalPath {
- return a.assetPackage
+func (a *aapt) ManifestsDepSet() *android.DepSet[android.Path] {
+ return a.manifestsDepSet
}
func (a *aapt) SetRROEnforcedForDependent(enforce bool) {
@@ -175,8 +191,6 @@ func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext android.SdkConte
// Flags specified in Android.bp
linkFlags = append(linkFlags, a.aaptProperties.Aaptflags...)
- linkFlags = append(linkFlags, "--no-static-lib-packages")
-
// Find implicit or explicit asset and resource dirs
assetDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Asset_dirs, "assets")
resourceDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res")
@@ -291,7 +305,7 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon
classLoaderContexts dexpreopt.ClassLoaderContextMap, excludedLibs []string,
enforceDefaultTargetSdkVersion bool, extraLinkFlags ...string) {
- transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, assetPackages, libDeps, libFlags :=
+ staticResourcesNodesDepSet, staticRRODirsDepSet, staticManifestsDepSet, sharedDeps, libFlags :=
aaptLibs(ctx, sdkContext, classLoaderContexts)
// Exclude any libraries from the supplied list.
@@ -314,13 +328,20 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon
EnforceDefaultTargetSdkVersion: enforceDefaultTargetSdkVersion,
})
+ staticDeps := transitiveAarDeps(staticResourcesNodesDepSet.ToList())
+
// Add additional manifest files to transitive manifests.
additionalManifests := android.PathsForModuleSrc(ctx, a.aaptProperties.Additional_manifests)
- a.transitiveManifestPaths = append(android.Paths{manifestPath}, additionalManifests...)
- a.transitiveManifestPaths = append(a.transitiveManifestPaths, transitiveStaticLibManifests...)
-
- if len(a.transitiveManifestPaths) > 1 && !Bool(a.aaptProperties.Dont_merge_manifests) {
- a.mergedManifestFile = manifestMerger(ctx, a.transitiveManifestPaths[0], a.transitiveManifestPaths[1:], a.isLibrary)
+ transitiveManifestPaths := append(android.Paths{manifestPath}, additionalManifests...)
+ // TODO(b/288358614): Soong has historically not merged manifests from dependencies of android_library_import
+ // modules. Merging manifests from dependencies could remove the need for pom2bp to generate the "-nodeps" copies
+ // of androidx libraries, but doing so triggers errors due to errors introduced by existing dependencies of
+ // android_library_import modules. If this is fixed, staticManifestsDepSet can be dropped completely in favor of
+ // staticResourcesNodesDepSet.manifests()
+ transitiveManifestPaths = append(transitiveManifestPaths, staticManifestsDepSet.ToList()...)
+
+ if len(transitiveManifestPaths) > 1 && !Bool(a.aaptProperties.Dont_merge_manifests) {
+ a.mergedManifestFile = manifestMerger(ctx, transitiveManifestPaths[0], transitiveManifestPaths[1:], a.isLibrary)
if !a.isLibrary {
// Only use the merged manifest for applications. For libraries, the transitive closure of manifests
// will be propagated to the final application and merged there. The merged manifest for libraries is
@@ -333,14 +354,27 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon
compileFlags, linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resZips := a.aapt2Flags(ctx, sdkContext, manifestPath)
- rroDirs = append(rroDirs, staticRRODirs...)
linkFlags = append(linkFlags, libFlags...)
- linkDeps = append(linkDeps, libDeps...)
+ linkDeps = append(linkDeps, sharedDeps...)
+ linkDeps = append(linkDeps, staticDeps.resPackages()...)
linkFlags = append(linkFlags, extraLinkFlags...)
if a.isLibrary {
linkFlags = append(linkFlags, "--static-lib")
}
+ if a.isLibrary && a.useResourceProcessorBusyBox() {
+ // When building an android_library using ResourceProcessorBusyBox the resources are merged into
+ // package-res.apk with --merge-only, but --no-static-lib-packages is not used so that R.txt only
+ // contains resources from this library.
+ linkFlags = append(linkFlags, "--merge-only")
+ } else {
+ // When building and app or when building an android_library without ResourceProcessorBusyBox
+ // --no-static-lib-packages is used to put all the resources into the app. If ResourceProcessorBusyBox
+ // is used then the app's R.txt will be post-processed along with the R.txt files from dependencies to
+ // sort resources into the right packages in R.class.
+ linkFlags = append(linkFlags, "--no-static-lib-packages")
+ }
+
packageRes := android.PathForModuleOut(ctx, "package-res.apk")
// the subdir "android" is required to be filtered by package names
srcJar := android.PathForModuleGen(ctx, "android", "R.srcjar")
@@ -348,6 +382,7 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon
rTxt := android.PathForModuleOut(ctx, "R.txt")
// This file isn't used by Soong, but is generated for exporting
extraPackages := android.PathForModuleOut(ctx, "extra_packages")
+ var transitiveRJars android.Paths
var compiledResDirs []android.Paths
for _, dir := range resDirs {
@@ -363,7 +398,27 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon
var compiledRes, compiledOverlay android.Paths
- compiledOverlay = append(compiledOverlay, transitiveStaticLibs...)
+ // AAPT2 overlays are in lowest to highest priority order, reverse the topological order
+ // of transitiveStaticLibs.
+ transitiveStaticLibs := android.ReversePaths(staticDeps.resPackages())
+
+ if a.isLibrary && a.useResourceProcessorBusyBox() {
+ // When building an android_library with ResourceProcessorBusyBox enabled treat static library dependencies
+ // as imports. The resources from dependencies will not be merged into this module's package-res.apk, and
+ // instead modules depending on this module will reference package-res.apk from all transitive static
+ // dependencies.
+ for _, staticDep := range staticDeps {
+ linkDeps = append(linkDeps, staticDep.resPackage)
+ linkFlags = append(linkFlags, "-I "+staticDep.resPackage.String())
+ if staticDep.usedResourceProcessor {
+ transitiveRJars = append(transitiveRJars, staticDep.rJar)
+ }
+ }
+ } else {
+ // When building an app or building a library without ResourceProcessorBusyBox enabled all static
+ // dependencies are compiled into this module's package-res.apk as overlays.
+ compiledOverlay = append(compiledOverlay, transitiveStaticLibs...)
+ }
if len(transitiveStaticLibs) > 0 {
// If we are using static android libraries, every source file becomes an overlay.
@@ -404,12 +459,18 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon
})
}
+ // No need to specify assets from dependencies to aapt2Link for libraries, all transitive assets will be
+ // provided to the final app aapt2Link step.
+ var transitiveAssets android.Paths
+ if !a.isLibrary {
+ transitiveAssets = android.ReverseSliceInPlace(staticDeps.assets())
+ }
aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt, extraPackages,
- linkFlags, linkDeps, compiledRes, compiledOverlay, assetPackages, splitPackages)
+ linkFlags, linkDeps, compiledRes, compiledOverlay, transitiveAssets, splitPackages)
// Extract assets from the resource package output so that they can be used later in aapt2link
// for modules that depend on this one.
- if android.PrefixInList(linkFlags, "-A ") || len(assetPackages) > 0 {
+ if android.PrefixInList(linkFlags, "-A ") {
assets := android.PathForModuleOut(ctx, "assets.zip")
ctx.Build(pctx, android.BuildParams{
Rule: extractAssetsRule,
@@ -420,21 +481,142 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon
a.assetPackage = android.OptionalPathForPath(assets)
}
+ if a.useResourceProcessorBusyBox() {
+ rJar := android.PathForModuleOut(ctx, "busybox/R.jar")
+ resourceProcessorBusyBoxGenerateBinaryR(ctx, rTxt, a.mergedManifestFile, rJar, staticDeps, a.isLibrary)
+ transitiveRJars = append(transitiveRJars, rJar)
+ a.rJar = rJar
+ }
+
a.aaptSrcJar = srcJar
+ a.transitiveAaptRJars = transitiveRJars
+ a.transitiveAaptResourcePackages = staticDeps.resPackages()
a.exportPackage = packageRes
a.manifestPath = manifestPath
a.proguardOptionsFile = proguardOptionsFile
- a.rroDirs = rroDirs
a.extraAaptPackagesFile = extraPackages
a.rTxt = rTxt
a.splits = splits
+ a.resourcesNodesDepSet = android.NewDepSetBuilder[*resourcesNode](android.TOPOLOGICAL).
+ Direct(&resourcesNode{
+ resPackage: a.exportPackage,
+ manifest: a.manifestPath,
+ additionalManifests: additionalManifests,
+ rTxt: a.rTxt,
+ rJar: a.rJar,
+ assets: a.assetPackage,
+
+ usedResourceProcessor: a.useResourceProcessorBusyBox(),
+ }).
+ Transitive(staticResourcesNodesDepSet).Build()
+ a.rroDirsDepSet = android.NewDepSetBuilder[rroDir](android.TOPOLOGICAL).
+ Direct(rroDirs...).
+ Transitive(staticRRODirsDepSet).Build()
+ a.manifestsDepSet = android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL).
+ Direct(a.manifestPath).
+ DirectSlice(additionalManifests).
+ Transitive(staticManifestsDepSet).Build()
+}
+
+var resourceProcessorBusyBox = pctx.AndroidStaticRule("resourceProcessorBusyBox",
+ blueprint.RuleParams{
+ Command: "${config.JavaCmd} -cp ${config.ResourceProcessorBusyBox} " +
+ "com.google.devtools.build.android.ResourceProcessorBusyBox --tool=GENERATE_BINARY_R -- @${out}.args && " +
+ "if cmp -s ${out}.tmp ${out} ; then rm ${out}.tmp ; else mv ${out}.tmp ${out}; fi",
+ CommandDeps: []string{"${config.ResourceProcessorBusyBox}"},
+ Rspfile: "${out}.args",
+ RspfileContent: "--primaryRTxt ${rTxt} --primaryManifest ${manifest} --classJarOutput ${out}.tmp ${args}",
+ Restat: true,
+ }, "rTxt", "manifest", "args")
+
+// resourceProcessorBusyBoxGenerateBinaryR converts the R.txt file produced by aapt2 into R.class files
+// using Bazel's ResourceProcessorBusyBox tool, which is faster than compiling the R.java files and
+// supports producing classes for static dependencies that only include resources from that dependency.
+func resourceProcessorBusyBoxGenerateBinaryR(ctx android.ModuleContext, rTxt, manifest android.Path,
+ rJar android.WritablePath, transitiveDeps transitiveAarDeps, isLibrary bool) {
+
+ var args []string
+ var deps android.Paths
+
+ if !isLibrary {
+ // When compiling an app, pass all R.txt and AndroidManifest.xml from transitive static library dependencies
+ // to ResourceProcessorBusyBox so that it can regenerate R.class files with the final resource IDs for each
+ // package.
+ args, deps = transitiveDeps.resourceProcessorDeps()
+ } else {
+ // When compiling a library don't pass any dependencies as it only needs to generate an R.class file for this
+ // library. Pass --finalFields=false so that the R.class file contains non-final fields so they don't get
+ // inlined into the library before the final IDs are assigned during app compilation.
+ args = append(args, "--finalFields=false")
+ }
+
+ deps = append(deps, rTxt, manifest)
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: resourceProcessorBusyBox,
+ Output: rJar,
+ Implicits: deps,
+ Description: "ResourceProcessorBusyBox",
+ Args: map[string]string{
+ "rTxt": rTxt.String(),
+ "manifest": manifest.String(),
+ "args": strings.Join(args, " "),
+ },
+ })
+}
+
+type resourcesNode struct {
+ resPackage android.Path
+ manifest android.Path
+ additionalManifests android.Paths
+ rTxt android.Path
+ rJar android.Path
+ assets android.OptionalPath
+
+ usedResourceProcessor bool
+}
+
+type transitiveAarDeps []*resourcesNode
+
+func (t transitiveAarDeps) resPackages() android.Paths {
+ paths := make(android.Paths, 0, len(t))
+ for _, dep := range t {
+ paths = append(paths, dep.resPackage)
+ }
+ return paths
+}
+
+func (t transitiveAarDeps) manifests() android.Paths {
+ paths := make(android.Paths, 0, len(t))
+ for _, dep := range t {
+ paths = append(paths, dep.manifest)
+ paths = append(paths, dep.additionalManifests...)
+ }
+ return paths
+}
+
+func (t transitiveAarDeps) resourceProcessorDeps() (args []string, deps android.Paths) {
+ for _, dep := range t {
+ args = append(args, "--library="+dep.rTxt.String()+","+dep.manifest.String())
+ deps = append(deps, dep.rTxt, dep.manifest)
+ }
+ return args, deps
+}
+
+func (t transitiveAarDeps) assets() android.Paths {
+ paths := make(android.Paths, 0, len(t))
+ for _, dep := range t {
+ if dep.assets.Valid() {
+ paths = append(paths, dep.assets.Path())
+ }
+ }
+ return paths
}
// aaptLibs collects libraries from dependencies and sdk_version and converts them into paths
func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext, classLoaderContexts dexpreopt.ClassLoaderContextMap) (
- transitiveStaticLibs, transitiveStaticLibManifests android.Paths, staticRRODirs []rroDir, assets, deps android.Paths, flags []string) {
-
- var sharedLibs android.Paths
+ staticResourcesNodes *android.DepSet[*resourcesNode], staticRRODirs *android.DepSet[rroDir],
+ staticManifests *android.DepSet[android.Path], sharedLibs android.Paths, flags []string) {
if classLoaderContexts == nil {
// Not all callers need to compute class loader context, those who don't just pass nil.
@@ -447,6 +629,10 @@ func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext, classLoa
sharedLibs = append(sharedLibs, sdkDep.jars...)
}
+ var resourcesNodeDepSets []*android.DepSet[*resourcesNode]
+ rroDirsDepSetBuilder := android.NewDepSetBuilder[rroDir](android.TOPOLOGICAL)
+ manifestsDepSetBuilder := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL)
+
ctx.VisitDirectDeps(func(module android.Module) {
depTag := ctx.OtherModuleDependencyTag(module)
@@ -469,32 +655,28 @@ func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext, classLoa
}
case staticLibTag:
if exportPackage != nil {
- transitiveStaticLibs = append(transitiveStaticLibs, aarDep.ExportedStaticPackages()...)
- transitiveStaticLibs = append(transitiveStaticLibs, exportPackage)
- transitiveStaticLibManifests = append(transitiveStaticLibManifests, aarDep.ExportedManifests()...)
- if aarDep.ExportedAssets().Valid() {
- assets = append(assets, aarDep.ExportedAssets().Path())
- }
-
- outer:
- for _, d := range aarDep.ExportedRRODirs() {
- for _, e := range staticRRODirs {
- if d.path == e.path {
- continue outer
- }
- }
- staticRRODirs = append(staticRRODirs, d)
- }
+ resourcesNodeDepSets = append(resourcesNodeDepSets, aarDep.ResourcesNodeDepSet())
+ rroDirsDepSetBuilder.Transitive(aarDep.RRODirsDepSet())
+ manifestsDepSetBuilder.Transitive(aarDep.ManifestsDepSet())
}
}
addCLCFromDep(ctx, module, classLoaderContexts)
})
- deps = append(deps, sharedLibs...)
- deps = append(deps, transitiveStaticLibs...)
+ // AAPT2 overlays are in lowest to highest priority order, the topological order will be reversed later.
+ // Reverse the dependency order now going into the depset so that it comes out in order after the second
+ // reverse later.
+ // NOTE: this is legacy and probably incorrect behavior, for most other cases (e.g. conflicting classes in
+ // dependencies) the highest priority dependency is listed first, but for resources the highest priority
+ // dependency has to be listed last.
+ staticResourcesNodes = android.NewDepSet(android.TOPOLOGICAL, nil,
+ android.ReverseSliceInPlace(resourcesNodeDepSets))
- if len(transitiveStaticLibs) > 0 {
+ staticRRODirs = rroDirsDepSetBuilder.Build()
+ staticManifests = manifestsDepSetBuilder.Build()
+
+ if len(staticResourcesNodes.ToList()) > 0 {
flags = append(flags, "--auto-add-overlay")
}
@@ -502,10 +684,7 @@ func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext, classLoa
flags = append(flags, "-I "+sharedLib.String())
}
- transitiveStaticLibs = android.FirstUniquePaths(transitiveStaticLibs)
- transitiveStaticLibManifests = android.FirstUniquePaths(transitiveStaticLibManifests)
-
- return transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, assets, deps, flags
+ return staticResourcesNodes, staticRRODirs, staticManifests, sharedLibs, flags
}
type AndroidLibrary struct {
@@ -516,8 +695,6 @@ type AndroidLibrary struct {
androidLibraryProperties androidLibraryProperties
aarFile android.WritablePath
-
- exportedStaticPackages android.Paths
}
var _ android.OutputFileProducer = (*AndroidLibrary)(nil)
@@ -532,10 +709,6 @@ func (a *AndroidLibrary) OutputFiles(tag string) (android.Paths, error) {
}
}
-func (a *AndroidLibrary) ExportedStaticPackages() android.Paths {
- return a.exportedStaticPackages
-}
-
var _ AndroidLibraryDependency = (*AndroidLibrary)(nil)
func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -554,9 +727,14 @@ func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()
- ctx.CheckbuildFile(a.proguardOptionsFile)
- ctx.CheckbuildFile(a.exportPackage)
- ctx.CheckbuildFile(a.aaptSrcJar)
+ a.stem = proptools.StringDefault(a.overridableDeviceProperties.Stem, ctx.ModuleName())
+
+ ctx.CheckbuildFile(a.aapt.proguardOptionsFile)
+ ctx.CheckbuildFile(a.aapt.exportPackage)
+ ctx.CheckbuildFile(a.aapt.aaptSrcJar)
+ if a.useResourceProcessorBusyBox() {
+ ctx.CheckbuildFile(a.aapt.rJar)
+ }
// apps manifests are handled by aapt, don't let Module see them
a.properties.Manifest = nil
@@ -568,7 +746,22 @@ func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles,
a.proguardOptionsFile)
- a.Module.compile(ctx, a.aaptSrcJar)
+ var extraSrcJars android.Paths
+ var extraCombinedJars android.Paths
+ var extraClasspathJars android.Paths
+ if a.useResourceProcessorBusyBox() {
+ // When building a library with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox for this
+ // library and each of the transitive static android_library dependencies has already created an
+ // R.class file for the appropriate package. Add all of those R.class files to the classpath.
+ extraClasspathJars = a.transitiveAaptRJars
+ } else {
+ // When building a library without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing
+ // R.java files for the library's package and the packages from all transitive static android_library
+ // dependencies. Compile the srcjar alongside the rest of the sources.
+ extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
+ }
+
+ a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars)
a.aarFile = android.PathForModuleOut(ctx, ctx.ModuleName()+".aar")
var res android.Paths
@@ -579,19 +772,15 @@ func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
a.exportedProguardFlagFiles = append(a.exportedProguardFlagFiles,
android.PathsForModuleSrc(ctx, a.dexProperties.Optimize.Proguard_flags_files)...)
+
ctx.VisitDirectDeps(func(m android.Module) {
if ctx.OtherModuleDependencyTag(m) == staticLibTag {
if lib, ok := m.(LibraryDependency); ok {
a.exportedProguardFlagFiles = append(a.exportedProguardFlagFiles, lib.ExportedProguardFlagFiles()...)
}
- if alib, ok := m.(AndroidLibraryDependency); ok {
- a.exportedStaticPackages = append(a.exportedStaticPackages, alib.ExportPackage())
- a.exportedStaticPackages = append(a.exportedStaticPackages, alib.ExportedStaticPackages()...)
- }
}
})
a.exportedProguardFlagFiles = android.FirstUniquePaths(a.exportedProguardFlagFiles)
- a.exportedStaticPackages = android.FirstUniquePaths(a.exportedStaticPackages)
prebuiltJniPackages := android.Paths{}
ctx.VisitDirectDeps(func(module android.Module) {
@@ -674,14 +863,18 @@ type AARImport struct {
properties AARImportProperties
- classpathFile android.WritablePath
- proguardFlags android.WritablePath
- exportPackage android.WritablePath
- extraAaptPackagesFile android.WritablePath
- manifest android.WritablePath
- assetsPackage android.WritablePath
+ classpathFile android.WritablePath
+ proguardFlags android.WritablePath
+ exportPackage android.WritablePath
+ transitiveAaptResourcePackages android.Paths
+ extraAaptPackagesFile android.WritablePath
+ manifest android.WritablePath
+ assetsPackage android.WritablePath
+ rTxt android.WritablePath
+ rJar android.WritablePath
- exportedStaticPackages android.Paths
+ resourcesNodesDepSet *android.DepSet[*resourcesNode]
+ manifestsDepSet *android.DepSet[android.Path]
hideApexVariantFromMake bool
@@ -738,25 +931,20 @@ var _ AndroidLibraryDependency = (*AARImport)(nil)
func (a *AARImport) ExportPackage() android.Path {
return a.exportPackage
}
-
func (a *AARImport) ExportedProguardFlagFiles() android.Paths {
return android.Paths{a.proguardFlags}
}
-func (a *AARImport) ExportedRRODirs() []rroDir {
- return nil
-}
-
-func (a *AARImport) ExportedStaticPackages() android.Paths {
- return a.exportedStaticPackages
+func (a *AARImport) ResourcesNodeDepSet() *android.DepSet[*resourcesNode] {
+ return a.resourcesNodesDepSet
}
-func (a *AARImport) ExportedManifests() android.Paths {
- return android.Paths{a.manifest}
+func (a *AARImport) RRODirsDepSet() *android.DepSet[rroDir] {
+ return android.NewDepSet[rroDir](android.TOPOLOGICAL, nil, nil)
}
-func (a *AARImport) ExportedAssets() android.OptionalPath {
- return android.OptionalPathForPath(a.assetsPackage)
+func (a *AARImport) ManifestsDepSet() *android.DepSet[android.Path] {
+ return a.manifestsDepSet
}
// RRO enforcement is not available on aar_import since its RRO dirs are not
@@ -852,12 +1040,13 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.classpathFile = extractedAARDir.Join(ctx, "classes-combined.jar")
a.proguardFlags = extractedAARDir.Join(ctx, "proguard.txt")
a.manifest = extractedAARDir.Join(ctx, "AndroidManifest.xml")
+ aarRTxt := extractedAARDir.Join(ctx, "R.txt")
a.assetsPackage = android.PathForModuleOut(ctx, "assets.zip")
ctx.Build(pctx, android.BuildParams{
Rule: unzipAAR,
Input: a.aarPath,
- Outputs: android.WritablePaths{a.classpathFile, a.proguardFlags, a.manifest, a.assetsPackage},
+ Outputs: android.WritablePaths{a.classpathFile, a.proguardFlags, a.manifest, a.assetsPackage, aarRTxt},
Description: "unzip AAR",
Args: map[string]string{
"outDir": extractedAARDir.String(),
@@ -877,46 +1066,70 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// the subdir "android" is required to be filtered by package names
srcJar := android.PathForModuleGen(ctx, "android", "R.srcjar")
proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options")
- rTxt := android.PathForModuleOut(ctx, "R.txt")
+ a.rTxt = android.PathForModuleOut(ctx, "R.txt")
a.extraAaptPackagesFile = android.PathForModuleOut(ctx, "extra_packages")
var linkDeps android.Paths
linkFlags := []string{
"--static-lib",
- "--no-static-lib-packages",
+ "--merge-only",
"--auto-add-overlay",
}
linkFlags = append(linkFlags, "--manifest "+a.manifest.String())
linkDeps = append(linkDeps, a.manifest)
- transitiveStaticLibs, staticLibManifests, staticRRODirs, transitiveAssets, libDeps, libFlags :=
+ staticResourcesNodesDepSet, staticRRODirsDepSet, staticManifestsDepSet, sharedLibs, libFlags :=
aaptLibs(ctx, android.SdkContext(a), nil)
- _ = staticLibManifests
- _ = staticRRODirs
+ _ = staticRRODirsDepSet
+ staticDeps := transitiveAarDeps(staticResourcesNodesDepSet.ToList())
- linkDeps = append(linkDeps, libDeps...)
+ linkDeps = append(linkDeps, sharedLibs...)
+ linkDeps = append(linkDeps, staticDeps.resPackages()...)
linkFlags = append(linkFlags, libFlags...)
- overlayRes := append(android.Paths{flata}, transitiveStaticLibs...)
+ overlayRes := android.Paths{flata}
- aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, rTxt, a.extraAaptPackagesFile,
+ // Treat static library dependencies of static libraries as imports.
+ transitiveStaticLibs := staticDeps.resPackages()
+ linkDeps = append(linkDeps, transitiveStaticLibs...)
+ for _, staticLib := range transitiveStaticLibs {
+ linkFlags = append(linkFlags, "-I "+staticLib.String())
+ }
+
+ transitiveAssets := android.ReverseSliceInPlace(staticDeps.assets())
+ aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, a.rTxt, a.extraAaptPackagesFile,
linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil)
- // Merge this import's assets with its dependencies' assets (if there are any).
- if len(transitiveAssets) > 0 {
- mergedAssets := android.PathForModuleOut(ctx, "merged-assets.zip")
- inputZips := append(android.Paths{a.assetsPackage}, transitiveAssets...)
- ctx.Build(pctx, android.BuildParams{
- Rule: mergeAssetsRule,
- Inputs: inputZips,
- Output: mergedAssets,
- Description: "merge assets from dependencies and self",
- })
- a.assetsPackage = mergedAssets
- }
+ a.rJar = android.PathForModuleOut(ctx, "busybox/R.jar")
+ resourceProcessorBusyBoxGenerateBinaryR(ctx, a.rTxt, a.manifest, a.rJar, nil, true)
+
+ resourcesNodesDepSetBuilder := android.NewDepSetBuilder[*resourcesNode](android.TOPOLOGICAL)
+ resourcesNodesDepSetBuilder.Direct(&resourcesNode{
+ resPackage: a.exportPackage,
+ manifest: a.manifest,
+ rTxt: a.rTxt,
+ rJar: a.rJar,
+ assets: android.OptionalPathForPath(a.assetsPackage),
+
+ usedResourceProcessor: true,
+ })
+ resourcesNodesDepSetBuilder.Transitive(staticResourcesNodesDepSet)
+ a.resourcesNodesDepSet = resourcesNodesDepSetBuilder.Build()
+
+ manifestDepSetBuilder := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL).Direct(a.manifest)
+ // TODO(b/288358614): Soong has historically not merged manifests from dependencies of android_library_import
+ // modules. Merging manifests from dependencies could remove the need for pom2bp to generate the "-nodeps" copies
+ // of androidx libraries, but doing so triggers errors due to errors introduced by existing dependencies of
+ // android_library_import modules. If this is fixed, AndroidLibraryDependency.ManifestsDepSet can be dropped
+ // completely in favor of AndroidLibraryDependency.ResourceNodesDepSet.manifest
+ //manifestDepSetBuilder.Transitive(transitiveStaticDeps.manifests)
+ _ = staticManifestsDepSet
+ a.manifestsDepSet = manifestDepSetBuilder.Build()
+
+ a.transitiveAaptResourcePackages = staticDeps.resPackages()
a.collectTransitiveHeaderJars(ctx)
ctx.SetProvider(JavaInfoProvider, JavaInfo{
@@ -925,6 +1138,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
TransitiveStaticLibsHeaderJars: a.transitiveStaticLibsHeaderJars,
ImplementationAndResourcesJars: android.PathsIfNonNil(a.classpathFile),
ImplementationJars: android.PathsIfNonNil(a.classpathFile),
+ // TransitiveAconfigFiles: // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
})
if proptools.Bool(a.properties.Extract_jni) {
@@ -1056,7 +1270,7 @@ func (a *AARImport) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
ctx.CreateBazelTargetModule(
bazel.BazelTargetModuleProperties{
Rule_class: "aar_import",
- Bzl_load_location: "//build/bazel/rules/android:rules.bzl",
+ Bzl_load_location: "//build/bazel/rules/android:aar_import.bzl",
},
android.CommonAttributes{Name: name},
&bazelAndroidLibraryImport{
@@ -1086,7 +1300,7 @@ func (a *AARImport) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
func AndroidLibraryBazelTargetModuleProperties() bazel.BazelTargetModuleProperties {
return bazel.BazelTargetModuleProperties{
Rule_class: "android_library",
- Bzl_load_location: "//build/bazel/rules/android:rules.bzl",
+ Bzl_load_location: "//build/bazel/rules/android:android_library.bzl",
}
}
diff --git a/java/android_manifest_test.go b/java/android_manifest_test.go
new file mode 100644
index 000000000..b12d77896
--- /dev/null
+++ b/java/android_manifest_test.go
@@ -0,0 +1,103 @@
+// Copyright 2023 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java
+
+import (
+ "android/soong/android"
+ "testing"
+)
+
+func TestManifestMerger(t *testing.T) {
+ bp := `
+ android_app {
+ name: "app",
+ sdk_version: "current",
+ srcs: ["app/app.java"],
+ resource_dirs: ["app/res"],
+ manifest: "app/AndroidManifest.xml",
+ additional_manifests: ["app/AndroidManifest2.xml"],
+ static_libs: ["direct", "direct_import"],
+ }
+
+ android_library {
+ name: "direct",
+ sdk_version: "current",
+ srcs: ["direct/direct.java"],
+ resource_dirs: ["direct/res"],
+ manifest: "direct/AndroidManifest.xml",
+ additional_manifests: ["direct/AndroidManifest2.xml"],
+ static_libs: ["transitive", "transitive_import"],
+ }
+
+ android_library {
+ name: "transitive",
+ sdk_version: "current",
+ srcs: ["transitive/transitive.java"],
+ resource_dirs: ["transitive/res"],
+ manifest: "transitive/AndroidManifest.xml",
+ additional_manifests: ["transitive/AndroidManifest2.xml"],
+ }
+
+ android_library_import {
+ name: "direct_import",
+ sdk_version: "current",
+ aars: ["direct_import.aar"],
+ static_libs: ["direct_import_dep"],
+ }
+
+ android_library_import {
+ name: "direct_import_dep",
+ sdk_version: "current",
+ aars: ["direct_import_dep.aar"],
+ }
+
+ android_library_import {
+ name: "transitive_import",
+ sdk_version: "current",
+ aars: ["transitive_import.aar"],
+ static_libs: ["transitive_import_dep"],
+ }
+
+ android_library_import {
+ name: "transitive_import_dep",
+ sdk_version: "current",
+ aars: ["transitive_import_dep.aar"],
+ }
+ `
+
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ PrepareForTestWithOverlayBuildComponents,
+ ).RunTestWithBp(t, bp)
+
+ manifestMergerRule := result.ModuleForTests("app", "android_common").Rule("manifestMerger")
+ android.AssertPathRelativeToTopEquals(t, "main manifest",
+ "out/soong/.intermediates/app/android_common/manifest_fixer/AndroidManifest.xml",
+ manifestMergerRule.Input)
+ android.AssertPathsRelativeToTopEquals(t, "lib manifests",
+ []string{
+ "app/AndroidManifest2.xml",
+ "out/soong/.intermediates/direct/android_common/manifest_fixer/AndroidManifest.xml",
+ "direct/AndroidManifest2.xml",
+ "out/soong/.intermediates/transitive/android_common/manifest_fixer/AndroidManifest.xml",
+ "transitive/AndroidManifest2.xml",
+ "out/soong/.intermediates/transitive_import/android_common/aar/AndroidManifest.xml",
+ "out/soong/.intermediates/direct_import/android_common/aar/AndroidManifest.xml",
+ // TODO(b/288358614): Soong has historically not merged manifests from dependencies of
+ // android_library_import modules.
+
+ },
+ manifestMergerRule.Implicits)
+}
diff --git a/java/androidmk.go b/java/androidmk.go
index 9c21633fb..82505e9e3 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -123,6 +123,8 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries {
if library.dexpreopter.configPath != nil {
entries.SetPath("LOCAL_SOONG_DEXPREOPT_CONFIG", library.dexpreopter.configPath)
}
+
+ entries.SetOptionalPaths("LOCAL_ACONFIG_FILES", library.getTransitiveAconfigFiles().ToList())
},
},
})
@@ -220,6 +222,7 @@ func (prebuilt *Import) AndroidMkEntries() []android.AndroidMkEntries {
entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.combinedClasspathFile)
entries.SetString("LOCAL_SDK_VERSION", prebuilt.sdkVersion.String())
entries.SetString("LOCAL_MODULE_STEM", prebuilt.Stem())
+ // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
},
},
}}
@@ -244,6 +247,7 @@ func (prebuilt *DexImport) AndroidMkEntries() []android.AndroidMkEntries {
entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", prebuilt.dexpreopter.builtInstalled)
}
entries.SetString("LOCAL_MODULE_STEM", prebuilt.Stem())
+ // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
},
},
}}
@@ -265,10 +269,12 @@ func (prebuilt *AARImport) AndroidMkEntries() []android.AndroidMkEntries {
entries.SetPath("LOCAL_SOONG_HEADER_JAR", prebuilt.classpathFile)
entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.classpathFile)
entries.SetPath("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE", prebuilt.exportPackage)
+ entries.SetPaths("LOCAL_SOONG_TRANSITIVE_RES_PACKAGES", prebuilt.transitiveAaptResourcePackages)
entries.SetPath("LOCAL_SOONG_EXPORT_PROGUARD_FLAGS", prebuilt.proguardFlags)
entries.SetPath("LOCAL_SOONG_STATIC_LIBRARY_EXTRA_PACKAGES", prebuilt.extraAaptPackagesFile)
entries.SetPath("LOCAL_FULL_MANIFEST_FILE", prebuilt.manifest)
entries.SetString("LOCAL_SDK_VERSION", prebuilt.sdkVersion.String())
+ // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
},
},
}}
@@ -295,6 +301,7 @@ func (binary *Binary) AndroidMkEntries() []android.AndroidMkEntries {
if len(binary.dexpreopter.builtInstalled) > 0 {
entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", binary.dexpreopter.builtInstalled)
}
+ entries.SetOptionalPaths("LOCAL_ACONFIG_FILES", binary.getTransitiveAconfigFiles().ToList())
},
},
ExtraFooters: []android.AndroidMkExtraFootersFunc{
@@ -340,6 +347,9 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
// App module names can be overridden.
entries.SetString("LOCAL_MODULE", app.installApkName)
entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", app.appProperties.PreventInstall)
+ if app.headerJarFile != nil {
+ entries.SetPath("LOCAL_SOONG_HEADER_JAR", app.headerJarFile)
+ }
entries.SetPath("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE", app.exportPackage)
if app.dexJarFile.IsSet() {
entries.SetPath("LOCAL_SOONG_DEX_JAR", app.dexJarFile.Path())
@@ -368,8 +378,13 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
filterRRO := func(filter overlayType) android.Paths {
var paths android.Paths
- for _, d := range app.rroDirs {
+ seen := make(map[android.Path]bool)
+ for _, d := range app.rroDirsDepSet.ToList() {
if d.overlayType == filter {
+ if seen[d.path] {
+ continue
+ }
+ seen[d.path] = true
paths = append(paths, d.path)
}
}
@@ -432,6 +447,10 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
}
entries.SetOptionalPaths("LOCAL_SOONG_LINT_REPORTS", app.linter.reports)
+
+ if app.Name() != "framework-res" {
+ entries.SetOptionalPaths("LOCAL_ACONFIG_FILES", app.getTransitiveAconfigFiles().ToList())
+ }
},
},
ExtraFooters: []android.AndroidMkExtraFootersFunc{
@@ -450,11 +469,6 @@ func (a *AndroidApp) getOverriddenPackages() []string {
if len(a.overridableAppProperties.Overrides) > 0 {
overridden = append(overridden, a.overridableAppProperties.Overrides...)
}
- // When APK name is overridden via PRODUCT_PACKAGE_NAME_OVERRIDES
- // ensure that the original name is overridden.
- if a.Stem() != a.installApkName {
- overridden = append(overridden, a.Stem())
- }
return overridden
}
@@ -508,10 +522,12 @@ func (a *AndroidLibrary) AndroidMkEntries() []android.AndroidMkEntries {
}
entries.SetPath("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE", a.exportPackage)
+ entries.SetPaths("LOCAL_SOONG_TRANSITIVE_RES_PACKAGES", a.transitiveAaptResourcePackages)
entries.SetPath("LOCAL_SOONG_STATIC_LIBRARY_EXTRA_PACKAGES", a.extraAaptPackagesFile)
entries.SetPath("LOCAL_FULL_MANIFEST_FILE", a.mergedManifestFile)
entries.AddStrings("LOCAL_SOONG_EXPORT_PROGUARD_FLAGS", a.exportedProguardFlagFiles.Strings()...)
entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", true)
+ entries.SetOptionalPaths("LOCAL_ACONFIG_FILES", a.getTransitiveAconfigFiles().ToList())
})
return entriesList
@@ -684,6 +700,7 @@ func (a *AndroidAppImport) AndroidMkEntries() []android.AndroidMkEntries {
if Bool(a.properties.Export_package_resources) {
entries.SetPath("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE", a.outputFile)
}
+ // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
},
},
}}
@@ -717,6 +734,7 @@ func (r *RuntimeResourceOverlay) AndroidMkEntries() []android.AndroidMkEntries {
entries.SetString("LOCAL_CERTIFICATE", r.certificate.AndroidMkString())
entries.SetPath("LOCAL_MODULE_PATH", r.installDir)
entries.AddStrings("LOCAL_OVERRIDES_PACKAGES", r.properties.Overrides...)
+ // TODO: LOCAL_ACONFIG_FILES -- Might eventually need aconfig flags?
},
},
}}
@@ -734,6 +752,7 @@ func (apkSet *AndroidAppSet) AndroidMkEntries() []android.AndroidMkEntries {
entries.SetPath("LOCAL_APK_SET_INSTALL_FILE", apkSet.PackedAdditionalOutputs())
entries.SetPath("LOCAL_APKCERTS_FILE", apkSet.apkcertsFile)
entries.AddStrings("LOCAL_OVERRIDES_PACKAGES", apkSet.properties.Overrides...)
+ // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts -- Both declarations and values
},
},
},
diff --git a/java/app.go b/java/app.go
index 706f99a83..224bc8867 100755
--- a/java/app.go
+++ b/java/app.go
@@ -18,6 +18,7 @@ package java
// related module types, including their override variants.
import (
+ "fmt"
"path/filepath"
"strings"
@@ -33,8 +34,17 @@ import (
func init() {
RegisterAppBuildComponents(android.InitRegistrationContext)
+ pctx.HostBinToolVariable("ModifyAllowlistCmd", "modify_permissions_allowlist")
}
+var (
+ modifyAllowlist = pctx.AndroidStaticRule("modifyAllowlist",
+ blueprint.RuleParams{
+ Command: "${ModifyAllowlistCmd} $in $packageName $out",
+ CommandDeps: []string{"${ModifyAllowlistCmd}"},
+ }, "packageName")
+)
+
func RegisterAppBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("android_app", AndroidAppFactory)
ctx.RegisterModuleType("android_test", AndroidTestFactory)
@@ -115,6 +125,9 @@ type appProperties struct {
// Prefer using other specific properties if build behaviour must be changed; avoid using this
// flag for anything but neverallow rules (unless the behaviour change is invisible to owners).
Updatable *bool
+
+ // Specifies the file that contains the allowlist for this app.
+ Privapp_allowlist *string `android:"path"`
}
// android_app properties that can be overridden by override_android_app
@@ -179,6 +192,8 @@ type AndroidApp struct {
android.ApexBundleDepsInfo
javaApiUsedByOutputFile android.ModuleOutPath
+
+ privAppAllowlist android.OptionalPath
}
func (a *AndroidApp) IsInstallable() bool {
@@ -189,8 +204,8 @@ func (a *AndroidApp) ExportedProguardFlagFiles() android.Paths {
return nil
}
-func (a *AndroidApp) ExportedStaticPackages() android.Paths {
- return nil
+func (a *AndroidApp) ResourcesNodeDepSet() *android.DepSet[*resourcesNode] {
+ return a.aapt.resourcesNodesDepSet
}
func (a *AndroidApp) OutputFile() android.Path {
@@ -205,6 +220,10 @@ func (a *AndroidApp) JniCoverageOutputs() android.Paths {
return a.jniCoverageOutputs
}
+func (a *AndroidApp) PrivAppAllowlist() android.OptionalPath {
+ return a.privAppAllowlist
+}
+
var _ AndroidLibraryDependency = (*AndroidApp)(nil)
type Certificate struct {
@@ -269,6 +288,16 @@ func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutato
ctx.AddDependency(ctx.Module(), certificateTag, cert)
}
+ if a.appProperties.Privapp_allowlist != nil && !Bool(a.appProperties.Privileged) {
+ // There are a few uids that are explicitly considered privileged regardless of their
+ // app's location. Bluetooth is one such app. It should arguably be moved to priv-app,
+ // but for now, allow it not to be in priv-app.
+ privilegedBecauseOfUid := ctx.ModuleName() == "Bluetooth"
+ if !privilegedBecauseOfUid {
+ ctx.PropertyErrorf("privapp_allowlist", "privileged must be set in order to use privapp_allowlist (with a few exceptions)")
+ }
+ }
+
for _, cert := range a.appProperties.Additional_certificates {
cert = android.SrcIsModule(cert)
if cert != "" {
@@ -492,7 +521,23 @@ func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path {
a.dexpreopter.preventInstall = a.appProperties.PreventInstall
if ctx.ModuleName() != "framework-res" {
- a.Module.compile(ctx, a.aaptSrcJar)
+ var extraSrcJars android.Paths
+ var extraClasspathJars android.Paths
+ var extraCombinedJars android.Paths
+ if a.useResourceProcessorBusyBox() {
+ // When building an app with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox has already
+ // created R.class files that provide IDs for resources in busybox/R.jar. Pass that file in the
+ // classpath when compiling everything else, and add it to the final classes jar.
+ extraClasspathJars = android.Paths{a.aapt.rJar}
+ extraCombinedJars = android.Paths{a.aapt.rJar}
+ } else {
+ // When building an app without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing
+ // R.java files for the app's package and the packages from all transitive static android_library
+ // dependencies. Compile the srcjar alongside the rest of the sources.
+ extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
+ }
+
+ a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars)
}
return a.dexJarFile.PathOrNil()
@@ -591,7 +636,6 @@ func processMainCert(m android.ModuleBase, certPropValue string, certificates []
}
}
-
return mainCertificate, certificates
}
@@ -599,6 +643,35 @@ func (a *AndroidApp) InstallApkName() string {
return a.installApkName
}
+func (a *AndroidApp) createPrivappAllowlist(ctx android.ModuleContext) android.Path {
+ if a.appProperties.Privapp_allowlist == nil {
+ return nil
+ }
+
+ isOverrideApp := a.GetOverriddenBy() != ""
+ if !isOverrideApp {
+ // if this is not an override, we don't need to rewrite the existing privapp allowlist
+ return android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist)
+ }
+
+ if a.overridableAppProperties.Package_name == nil {
+ ctx.PropertyErrorf("privapp_allowlist", "package_name must be set to use privapp_allowlist")
+ }
+
+ packageName := *a.overridableAppProperties.Package_name
+ fileName := "privapp_allowlist_" + packageName + ".xml"
+ outPath := android.PathForModuleOut(ctx, fileName).OutputPath
+ ctx.Build(pctx, android.BuildParams{
+ Rule: modifyAllowlist,
+ Input: android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist),
+ Output: outPath,
+ Args: map[string]string{
+ "packageName": packageName,
+ },
+ })
+ return &outPath
+}
+
func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
var apkDeps android.Paths
@@ -609,8 +682,17 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx)
a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex)
+ // Unlike installApkName, a.stem should respect base module name for override_android_app.
+ // Therefore, use ctx.ModuleName() instead of a.Name().
+ a.stem = proptools.StringDefault(a.overridableDeviceProperties.Stem, ctx.ModuleName())
+
// Check if the install APK name needs to be overridden.
- a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(a.Stem())
+ // Both android_app and override_android_app module are expected to possess
+ // its module bound apk path. However, override_android_app inherits ctx.ModuleName()
+ // from the base module. Therefore, use a.Name() which represents
+ // the module name for both android_app and override_android_app.
+ a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(
+ proptools.StringDefault(a.overridableDeviceProperties.Stem, a.Name()))
if ctx.ModuleName() == "framework-res" {
// framework-res.apk is installed as system/framework/framework-res.apk
@@ -734,11 +816,21 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile)
a.bundleFile = bundleFile
+ allowlist := a.createPrivappAllowlist(ctx)
+ if allowlist != nil {
+ a.privAppAllowlist = android.OptionalPathForPath(allowlist)
+ }
+
apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
// Install the app package.
- if (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() &&
- !a.appProperties.PreventInstall {
+ shouldInstallAppPackage := (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() && !a.appProperties.PreventInstall
+ if shouldInstallAppPackage {
+ if a.privAppAllowlist.Valid() {
+ allowlistInstallPath := android.PathForModuleInstall(ctx, "etc", "permissions")
+ allowlistInstallFilename := a.installApkName + ".xml"
+ ctx.InstallFile(allowlistInstallPath, allowlistInstallFilename, a.privAppAllowlist.Path())
+ }
var extraInstalledPaths android.Paths
for _, extra := range a.extraOutputFiles {
@@ -925,6 +1017,10 @@ func (a *AndroidApp) DepIsInSameApex(ctx android.BaseModuleContext, dep android.
// For OutputFileProducer interface
func (a *AndroidApp) OutputFiles(tag string) (android.Paths, error) {
switch tag {
+ // In some instances, it can be useful to reference the aapt-generated flags from another
+ // target, e.g., system server implements services declared in the framework-res manifest.
+ case ".aapt.proguardOptionsFile":
+ return []android.Path{a.proguardOptionsFile}, nil
case ".aapt.srcjar":
return []android.Path{a.aaptSrcJar}, nil
case ".export-package.apk":
@@ -1327,10 +1423,15 @@ func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps boo
}
}
-// presentOptionalUsesLibs returns optional_uses_libs after filtering out MissingUsesLibraries, which don't exist in the
-// build.
+// presentOptionalUsesLibs returns optional_uses_libs after filtering out libraries that don't exist in the source tree.
func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string {
- optionalUsesLibs, _ := android.FilterList(u.usesLibraryProperties.Optional_uses_libs, ctx.Config().MissingUsesLibraries())
+ optionalUsesLibs := android.FilterListPred(u.usesLibraryProperties.Optional_uses_libs, func(s string) bool {
+ exists := ctx.OtherModuleExists(s)
+ if !exists && !android.InList(ctx.ModuleName(), ctx.Config().BuildWarningBadOptionalUsesLibsAllowlist()) {
+ fmt.Printf("Warning: Module '%s' depends on non-existing optional_uses_libs '%s'\n", ctx.ModuleName(), s)
+ }
+ return exists
+ })
return optionalUsesLibs
}
@@ -1462,10 +1563,8 @@ func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, man
// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the build
// system and returns the path to a copy of the APK.
-func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path) android.Path {
+func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path) {
u.verifyUsesLibraries(ctx, apk, nil) // for APKs manifest_check does not write output file
- outputFile := android.PathForModuleOut(ctx, "verify_uses_libraries", apk.Base())
- return outputFile
}
// For Bazel / bp2build
@@ -1490,14 +1589,16 @@ func androidAppCertificateBp2Build(ctx android.TopDownMutatorContext, module *An
props := bazel.BazelTargetModuleProperties{
Rule_class: "android_app_certificate",
- Bzl_load_location: "//build/bazel/rules/android:rules.bzl",
+ Bzl_load_location: "//build/bazel/rules/android:android_app_certificate.bzl",
}
ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, attrs)
}
type manifestValueAttribute struct {
- MinSdkVersion *string
+ MinSdkVersion *string
+ MaxSdkVersion *string
+ TargetSdkVersion *string
}
type bazelAndroidAppAttributes struct {
@@ -1527,12 +1628,25 @@ func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
// MinSdkVersion(ctx) calls SdkVersion(ctx) if no value for min_sdk_version is set
minSdkVersion := a.MinSdkVersion(ctx)
if !minSdkVersion.IsPreview() && !minSdkVersion.IsInvalid() {
- minSdkStr, err := minSdkVersion.EffectiveVersionString(ctx)
- if err == nil {
+ if minSdkStr, err := minSdkVersion.EffectiveVersionString(ctx); err == nil {
manifestValues.MinSdkVersion = &minSdkStr
}
}
+ maxSdkVersion := a.MaxSdkVersion(ctx)
+ if !maxSdkVersion.IsPreview() && !maxSdkVersion.IsInvalid() {
+ if maxSdkStr, err := maxSdkVersion.EffectiveVersionString(ctx); err == nil {
+ manifestValues.MaxSdkVersion = &maxSdkStr
+ }
+ }
+
+ targetSdkVersion := a.TargetSdkVersion(ctx)
+ if !targetSdkVersion.IsPreview() && !targetSdkVersion.IsInvalid() {
+ if targetSdkStr, err := targetSdkVersion.EffectiveVersionString(ctx); err == nil {
+ manifestValues.TargetSdkVersion = &targetSdkStr
+ }
+ }
+
appAttrs := &bazelAndroidAppAttributes{
// TODO(b/209576404): handle package name override by product variable PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES
Custom_package: a.overridableAppProperties.Package_name,
@@ -1543,7 +1657,7 @@ func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
props := bazel.BazelTargetModuleProperties{
Rule_class: "android_binary",
- Bzl_load_location: "//build/bazel/rules/android:rules.bzl",
+ Bzl_load_location: "//build/bazel/rules/android:android_binary.bzl",
}
if !bp2BuildInfo.hasKotlin {
@@ -1573,7 +1687,7 @@ func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
ctx.CreateBazelTargetModule(
props,
- android.CommonAttributes{Name: a.Name()},
+ android.CommonAttributes{Name: a.Name(), SkipData: proptools.BoolPtr(true)},
appAttrs,
)
diff --git a/java/app_builder.go b/java/app_builder.go
index d20a6bfe4..d397ff7f5 100644
--- a/java/app_builder.go
+++ b/java/app_builder.go
@@ -225,8 +225,6 @@ func BuildBundleModule(ctx android.ModuleContext, outputFile android.WritablePat
})
}
-const jniJarOutputPathString = "jniJarOutput.zip"
-
func TransformJniLibsToJar(
ctx android.ModuleContext,
outputFile android.WritablePath,
@@ -258,7 +256,10 @@ func TransformJniLibsToJar(
rule = zipRE
args["implicits"] = strings.Join(deps.Strings(), ",")
}
- jniJarPath := android.PathForModuleOut(ctx, jniJarOutputPathString)
+ var jniJarPath android.WritablePath = android.PathForModuleOut(ctx, "jniJarOutput.zip")
+ if len(prebuiltJniPackages) == 0 {
+ jniJarPath = outputFile
+ }
ctx.Build(pctx, android.BuildParams{
Rule: rule,
Description: "zip jni libs",
@@ -266,12 +267,26 @@ func TransformJniLibsToJar(
Implicits: deps,
Args: args,
})
- ctx.Build(pctx, android.BuildParams{
- Rule: mergeAssetsRule,
- Description: "merge prebuilt JNI packages",
- Inputs: append(prebuiltJniPackages, jniJarPath),
- Output: outputFile,
- })
+ if len(prebuiltJniPackages) > 0 {
+ var mergeJniJarPath android.WritablePath = android.PathForModuleOut(ctx, "mergeJniJarOutput.zip")
+ if !uncompressJNI {
+ mergeJniJarPath = outputFile
+ }
+ ctx.Build(pctx, android.BuildParams{
+ Rule: mergeAssetsRule,
+ Description: "merge prebuilt JNI packages",
+ Inputs: append(prebuiltJniPackages, jniJarPath),
+ Output: mergeJniJarPath,
+ })
+
+ if uncompressJNI {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: uncompressEmbeddedJniLibsRule,
+ Input: mergeJniJarPath,
+ Output: outputFile,
+ })
+ }
+ }
}
func (a *AndroidApp) generateJavaUsedByApex(ctx android.ModuleContext) {
diff --git a/java/app_import.go b/java/app_import.go
index 85b35ebaa..ad1765e9d 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -17,6 +17,7 @@ package java
// This file contains the module implementations for android_app_import and android_test_import.
import (
+ "fmt"
"reflect"
"github.com/google/blueprint"
@@ -49,6 +50,28 @@ var (
CommandDeps: []string{"${config.Zip2ZipCmd}"},
Description: "Uncompress dex files",
})
+
+ checkDexLibsAreUncompressedRule = pctx.AndroidStaticRule("check-dex-libs-are-uncompressed", blueprint.RuleParams{
+ // grep -v ' stor ' will search for lines that don't have ' stor '. stor means the file is stored uncompressed
+ Command: "if (zipinfo $in '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then " +
+ "echo $in: Contains compressed JNI libraries and/or dex files >&2;" +
+ "exit 1; " +
+ "else " +
+ "touch $out; " +
+ "fi",
+ Description: "Check for compressed JNI libs or dex files",
+ })
+
+ checkJniLibsAreUncompressedRule = pctx.AndroidStaticRule("check-jni-libs-are-uncompressed", blueprint.RuleParams{
+ // grep -v ' stor ' will search for lines that don't have ' stor '. stor means the file is stored uncompressed
+ Command: "if (zipinfo $in 'lib/*.so' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then " +
+ "echo $in: Contains compressed JNI libraries >&2;" +
+ "exit 1; " +
+ "else " +
+ "touch $out; " +
+ "fi",
+ Description: "Check for compressed JNI libs or dex files",
+ })
)
func RegisterAppImportBuildComponents(ctx android.RegistrationContext) {
@@ -73,8 +96,6 @@ type AndroidAppImport struct {
usesLibrary usesLibrary
- preprocessed bool
-
installPath android.InstallPath
hideApexVariantFromMake bool
@@ -128,6 +149,13 @@ type AndroidAppImportProperties struct {
// Optional. Install to a subdirectory of the default install path for the module
Relative_install_path *string
+
+ // Whether the prebuilt apk can be installed without additional processing. Default is false.
+ Preprocessed *bool
+
+ // Whether or not to skip checking the preprocessed apk for proper alignment and uncompressed
+ // JNI libs and dex files. Default is false
+ Skip_preprocessed_apk_checks *bool
}
func (a *AndroidAppImport) IsInstallable() bool {
@@ -201,7 +229,7 @@ func (a *AndroidAppImport) uncompressEmbeddedJniLibs(
ctx android.ModuleContext, inputPath android.Path, outputPath android.OutputPath) {
// Test apps don't need their JNI libraries stored uncompressed. As a matter of fact, messing
// with them may invalidate pre-existing signature data.
- if ctx.InstallInTestcases() && (Bool(a.properties.Presigned) || a.preprocessed) {
+ if ctx.InstallInTestcases() && (Bool(a.properties.Presigned) || Bool(a.properties.Preprocessed)) {
ctx.Build(pctx, android.BuildParams{
Rule: android.Cp,
Output: outputPath,
@@ -219,7 +247,7 @@ func (a *AndroidAppImport) uncompressEmbeddedJniLibs(
// 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() || a.preprocessed {
+ if ctx.Config().UnbundledBuild() || proptools.Bool(a.properties.Preprocessed) {
return false
}
@@ -297,7 +325,7 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext
a.dexpreopter.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
if a.usesLibrary.enforceUsesLibraries() {
- srcApk = a.usesLibrary.verifyUsesLibrariesAPK(ctx, srcApk)
+ a.usesLibrary.verifyUsesLibrariesAPK(ctx, srcApk)
}
a.dexpreopter.dexpreopt(ctx, jnisUncompressed)
@@ -317,8 +345,22 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext
// Sign or align the package if package has not been preprocessed
- if a.preprocessed {
- a.outputFile = srcApk
+ if proptools.Bool(a.properties.Preprocessed) {
+ var output android.WritablePath
+ if !proptools.Bool(a.properties.Skip_preprocessed_apk_checks) {
+ output = android.PathForModuleOut(ctx, "validated-prebuilt", apkFilename)
+ a.validatePreprocessedApk(ctx, srcApk, output)
+ } else {
+ // If using the input APK unmodified, still make a copy of it so that the output filename has the
+ // right basename.
+ output = android.PathForModuleOut(ctx, apkFilename)
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Input: srcApk,
+ Output: output,
+ })
+ }
+ a.outputFile = output
a.certificate = PresignedCertificate
} else if !Bool(a.properties.Presigned) {
// If the certificate property is empty at this point, default_dev_cert must be set to true.
@@ -352,6 +394,44 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext
// TODO: androidmk converter jni libs
}
+func (a *AndroidAppImport) validatePreprocessedApk(ctx android.ModuleContext, srcApk android.Path, dstApk android.WritablePath) {
+ var validations android.Paths
+
+ alignmentStamp := android.PathForModuleOut(ctx, "validated-prebuilt", "alignment.stamp")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: checkZipAlignment,
+ Input: srcApk,
+ Output: alignmentStamp,
+ })
+
+ validations = append(validations, alignmentStamp)
+ jniCompressionStamp := android.PathForModuleOut(ctx, "validated-prebuilt", "jni_compression.stamp")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: checkJniLibsAreUncompressedRule,
+ Input: srcApk,
+ Output: jniCompressionStamp,
+ })
+ validations = append(validations, jniCompressionStamp)
+
+ if a.Privileged() {
+ // It's ok for non-privileged apps to have compressed dex files, see go/gms-uncompressed-jni-slides
+ dexCompressionStamp := android.PathForModuleOut(ctx, "validated-prebuilt", "dex_compression.stamp")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: checkDexLibsAreUncompressedRule,
+ Input: srcApk,
+ Output: dexCompressionStamp,
+ })
+ validations = append(validations, dexCompressionStamp)
+ }
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Input: srcApk,
+ Output: dstApk,
+ Validations: validations,
+ })
+}
+
func (a *AndroidAppImport) Prebuilt() *android.Prebuilt {
return &a.prebuilt
}
@@ -364,6 +444,15 @@ func (a *AndroidAppImport) OutputFile() android.Path {
return a.outputFile
}
+func (a *AndroidAppImport) OutputFiles(tag string) (android.Paths, error) {
+ switch tag {
+ case "":
+ return []android.Path{a.outputFile}, nil
+ default:
+ return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+ }
+}
+
func (a *AndroidAppImport) JacocoReportClassesFile() android.Path {
return nil
}
@@ -376,6 +465,10 @@ func (a *AndroidAppImport) ProvenanceMetaDataFile() android.OutputPath {
return a.provenanceMetaDataFile
}
+func (a *AndroidAppImport) PrivAppAllowlist() android.OptionalPath {
+ return android.OptionalPath{}
+}
+
var dpiVariantGroupType reflect.Type
var archVariantGroupType reflect.Type
var supportedDpis = []string{"ldpi", "mdpi", "hdpi", "xhdpi", "xxhdpi", "xxxhdpi"}
@@ -487,11 +580,6 @@ func AndroidAppImportFactory() android.Module {
return module
}
-type androidTestImportProperties struct {
- // Whether the prebuilt apk can be installed without additional processing. Default is false.
- Preprocessed *bool
-}
-
type AndroidTestImport struct {
AndroidAppImport
@@ -508,14 +596,10 @@ type AndroidTestImport struct {
Per_testcase_directory *bool
}
- testImportProperties androidTestImportProperties
-
data android.Paths
}
func (a *AndroidTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- a.preprocessed = Bool(a.testImportProperties.Preprocessed)
-
a.generateAndroidBuildActions(ctx)
a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
@@ -532,7 +616,6 @@ func AndroidTestImportFactory() android.Module {
module.AddProperties(&module.properties)
module.AddProperties(&module.dexpreoptProperties)
module.AddProperties(&module.testProperties)
- module.AddProperties(&module.testImportProperties)
module.populateAllVariantStructs()
android.AddLoadHook(module, func(ctx android.LoadHookContext) {
module.processVariants(ctx)
diff --git a/java/app_import_test.go b/java/app_import_test.go
index 80930248e..bb8fab93b 100644
--- a/java/app_import_test.go
+++ b/java/app_import_test.go
@@ -657,6 +657,29 @@ func TestAndroidTestImport_Preprocessed(t *testing.T) {
}
}
+func TestAndroidAppImport_Preprocessed(t *testing.T) {
+ ctx, _ := testJava(t, `
+ android_app_import {
+ name: "foo",
+ apk: "prebuilts/apk/app.apk",
+ presigned: true,
+ preprocessed: true,
+ }
+ `)
+
+ apkName := "foo.apk"
+ variant := ctx.ModuleForTests("foo", "android_common")
+ outputBuildParams := variant.Output("validated-prebuilt/" + apkName).BuildParams
+ if outputBuildParams.Rule.String() != android.Cp.String() {
+ t.Errorf("Unexpected prebuilt android_app_import rule: " + outputBuildParams.Rule.String())
+ }
+
+ // Make sure compression and aligning were validated.
+ if len(outputBuildParams.Validations) != 2 {
+ t.Errorf("Expected compression/alignment validation rules, found %d validations", len(outputBuildParams.Validations))
+ }
+}
+
func TestAndroidTestImport_UncompressDex(t *testing.T) {
testCases := []struct {
name string
diff --git a/java/app_test.go b/java/app_test.go
index b154bc990..8474ea7d6 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -443,9 +443,9 @@ func TestUpdatableApps_JniLibShouldBeBuiltAgainstMinSdkVersion(t *testing.T) {
inputs := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared").Description("link").Implicits
var crtbeginFound, crtendFound bool
expectedCrtBegin := ctx.ModuleForTests("crtbegin_so",
- "android_arm64_armv8-a_sdk_29").Rule("partialLd").Output
+ "android_arm64_armv8-a_sdk_29").Rule("noAddrSig").Output
expectedCrtEnd := ctx.ModuleForTests("crtend_so",
- "android_arm64_armv8-a_sdk_29").Rule("partialLd").Output
+ "android_arm64_armv8-a_sdk_29").Rule("noAddrSig").Output
implicits := []string{}
for _, input := range inputs {
implicits = append(implicits, input.String())
@@ -599,7 +599,7 @@ func TestLibraryAssets(t *testing.T) {
android_library {
name: "lib3",
sdk_version: "current",
- static_libs: ["lib4"],
+ static_libs: ["lib4", "import"],
}
android_library {
@@ -607,6 +607,12 @@ func TestLibraryAssets(t *testing.T) {
sdk_version: "current",
asset_dirs: ["assets_b"],
}
+
+ android_library_import {
+ name: "import",
+ sdk_version: "current",
+ aars: ["import.aar"],
+ }
`
testCases := []struct {
@@ -616,11 +622,12 @@ func TestLibraryAssets(t *testing.T) {
}{
{
name: "foo",
- // lib1 has its own asset. lib3 doesn't have any, but provides lib4's transitively.
+ // lib1 has its own assets. lib3 doesn't have any, but lib4 and import have assets.
assetPackages: []string{
"out/soong/.intermediates/foo/android_common/aapt2/package-res.apk",
"out/soong/.intermediates/lib1/android_common/assets.zip",
- "out/soong/.intermediates/lib3/android_common/assets.zip",
+ "out/soong/.intermediates/lib4/android_common/assets.zip",
+ "out/soong/.intermediates/import/android_common/assets.zip",
},
},
{
@@ -632,10 +639,6 @@ func TestLibraryAssets(t *testing.T) {
},
{
name: "lib3",
- assetPackages: []string{
- "out/soong/.intermediates/lib3/android_common/aapt2/package-res.apk",
- "out/soong/.intermediates/lib4/android_common/assets.zip",
- },
},
{
name: "lib4",
@@ -717,7 +720,514 @@ func TestAppJavaResources(t *testing.T) {
}
}
-func TestAndroidResources(t *testing.T) {
+func TestAndroidResourceProcessor(t *testing.T) {
+ testCases := []struct {
+ name string
+ appUsesRP bool
+ directLibUsesRP bool
+ transitiveLibUsesRP bool
+
+ dontVerifyApp bool
+ appResources []string
+ appOverlays []string
+ appImports []string
+ appSrcJars []string
+ appClasspath []string
+ appCombined []string
+
+ dontVerifyDirect bool
+ directResources []string
+ directOverlays []string
+ directImports []string
+ directSrcJars []string
+ directClasspath []string
+ directCombined []string
+
+ dontVerifyTransitive bool
+ transitiveResources []string
+ transitiveOverlays []string
+ transitiveImports []string
+ transitiveSrcJars []string
+ transitiveClasspath []string
+ transitiveCombined []string
+
+ dontVerifyDirectImport bool
+ directImportResources []string
+ directImportOverlays []string
+ directImportImports []string
+
+ dontVerifyTransitiveImport bool
+ transitiveImportResources []string
+ transitiveImportOverlays []string
+ transitiveImportImports []string
+ }{
+ {
+ // Test with all modules set to use_resource_processor: false (except android_library_import modules,
+ // which always use resource processor).
+ name: "legacy",
+ appUsesRP: false,
+ directLibUsesRP: false,
+ transitiveLibUsesRP: false,
+
+ appResources: nil,
+ appOverlays: []string{
+ "out/soong/.intermediates/transitive/android_common/package-res.apk",
+ "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
+ "out/soong/.intermediates/transitive_import/android_common/package-res.apk",
+ "out/soong/.intermediates/direct/android_common/package-res.apk",
+ "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk",
+ "out/soong/.intermediates/direct_import/android_common/package-res.apk",
+ "out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat",
+ },
+ appImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
+ 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/direct/android_common/turbine-combined/direct.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.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/aar/classes-combined.jar",
+ },
+
+ directResources: nil,
+ directOverlays: []string{
+ "out/soong/.intermediates/transitive/android_common/package-res.apk",
+ "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
+ "out/soong/.intermediates/transitive_import/android_common/package-res.apk",
+ "out/soong/.intermediates/direct/android_common/aapt2/direct/res/values_strings.arsc.flat",
+ },
+ 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/aar/classes-combined.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/aar/classes-combined.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"},
+ transitiveCombined: nil,
+
+ directImportResources: nil,
+ directImportOverlays: []string{"out/soong/.intermediates/direct_import/android_common/flat-res/gen_res.flata"},
+ directImportImports: []string{
+ "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
+ "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk",
+ },
+
+ transitiveImportResources: nil,
+ transitiveImportOverlays: []string{"out/soong/.intermediates/transitive_import/android_common/flat-res/gen_res.flata"},
+ transitiveImportImports: []string{
+ "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
+ "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
+ },
+ },
+ {
+ // Test with all modules set to use_resource_processor: true.
+ name: "resource_processor",
+ appUsesRP: true,
+ directLibUsesRP: true,
+ transitiveLibUsesRP: true,
+
+ appResources: nil,
+ appOverlays: []string{
+ "out/soong/.intermediates/transitive/android_common/package-res.apk",
+ "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
+ "out/soong/.intermediates/transitive_import/android_common/package-res.apk",
+ "out/soong/.intermediates/direct/android_common/package-res.apk",
+ "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk",
+ "out/soong/.intermediates/direct_import/android_common/package-res.apk",
+ "out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat",
+ },
+ appImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
+ appSrcJars: nil,
+ appClasspath: []string{
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
+ "out/soong/.intermediates/app/android_common/busybox/R.jar",
+ "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+ },
+ appCombined: []string{
+ "out/soong/.intermediates/app/android_common/busybox/R.jar",
+ "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/aar/classes-combined.jar",
+ },
+
+ directResources: nil,
+ directOverlays: []string{"out/soong/.intermediates/direct/android_common/aapt2/direct/res/values_strings.arsc.flat"},
+ directImports: []string{
+ "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
+ "out/soong/.intermediates/transitive_import/android_common/package-res.apk",
+ "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
+ "out/soong/.intermediates/transitive/android_common/package-res.apk",
+ },
+ directSrcJars: nil,
+ directClasspath: []string{
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
+ "out/soong/.intermediates/transitive_import/android_common/busybox/R.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar",
+ "out/soong/.intermediates/transitive/android_common/busybox/R.jar",
+ "out/soong/.intermediates/direct/android_common/busybox/R.jar",
+ "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.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/aar/classes-combined.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: nil,
+ transitiveClasspath: []string{
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
+ "out/soong/.intermediates/transitive/android_common/busybox/R.jar",
+ },
+ transitiveCombined: nil,
+
+ directImportResources: nil,
+ directImportOverlays: []string{"out/soong/.intermediates/direct_import/android_common/flat-res/gen_res.flata"},
+ directImportImports: []string{
+ "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
+ "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk",
+ },
+
+ transitiveImportResources: nil,
+ transitiveImportOverlays: []string{"out/soong/.intermediates/transitive_import/android_common/flat-res/gen_res.flata"},
+ transitiveImportImports: []string{
+ "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
+ "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
+ },
+ }, {
+ // Test an app building with resource processor enabled but with dependencies built without
+ // resource processor.
+ name: "app_resource_processor",
+ appUsesRP: true,
+ directLibUsesRP: false,
+ transitiveLibUsesRP: false,
+
+ appResources: nil,
+ appOverlays: []string{
+ "out/soong/.intermediates/transitive/android_common/package-res.apk",
+ "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
+ "out/soong/.intermediates/transitive_import/android_common/package-res.apk",
+ "out/soong/.intermediates/direct/android_common/package-res.apk",
+ "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk",
+ "out/soong/.intermediates/direct_import/android_common/package-res.apk",
+ "out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat",
+ },
+ appImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
+ appSrcJars: nil,
+ appClasspath: []string{
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
+ // R.jar has to come before direct.jar
+ "out/soong/.intermediates/app/android_common/busybox/R.jar",
+ "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+ },
+ appCombined: []string{
+ "out/soong/.intermediates/app/android_common/busybox/R.jar",
+ "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/aar/classes-combined.jar",
+ },
+
+ dontVerifyDirect: true,
+ dontVerifyTransitive: true,
+ dontVerifyDirectImport: true,
+ dontVerifyTransitiveImport: true,
+ },
+ {
+ // Test an app building without resource processor enabled but with a dependency built with
+ // resource processor.
+ name: "app_dependency_lib_resource_processor",
+ appUsesRP: false,
+ directLibUsesRP: true,
+ transitiveLibUsesRP: false,
+
+ appOverlays: []string{
+ "out/soong/.intermediates/transitive/android_common/package-res.apk",
+ "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
+ "out/soong/.intermediates/transitive_import/android_common/package-res.apk",
+ "out/soong/.intermediates/direct/android_common/package-res.apk",
+ "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk",
+ "out/soong/.intermediates/direct_import/android_common/package-res.apk",
+ "out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat",
+ },
+ appImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
+ 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/direct/android_common/turbine-combined/direct.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.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/aar/classes-combined.jar",
+ },
+
+ directResources: nil,
+ directOverlays: []string{"out/soong/.intermediates/direct/android_common/aapt2/direct/res/values_strings.arsc.flat"},
+ directImports: []string{
+ "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk",
+ "out/soong/.intermediates/transitive_import/android_common/package-res.apk",
+ "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
+ "out/soong/.intermediates/transitive/android_common/package-res.apk",
+ },
+ directSrcJars: nil,
+ directClasspath: []string{
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
+ "out/soong/.intermediates/transitive_import/android_common/busybox/R.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar",
+ "out/soong/.intermediates/direct/android_common/busybox/R.jar",
+ "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
+ "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.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/aar/classes-combined.jar",
+ },
+
+ dontVerifyTransitive: true,
+ dontVerifyDirectImport: true,
+ dontVerifyTransitiveImport: true,
+ },
+ {
+ // Test a library building without resource processor enabled but with a dependency built with
+ // resource processor.
+ name: "lib_dependency_lib_resource_processor",
+ appUsesRP: false,
+ directLibUsesRP: false,
+ transitiveLibUsesRP: true,
+
+ appOverlays: []string{
+ "out/soong/.intermediates/transitive/android_common/package-res.apk",
+ "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
+ "out/soong/.intermediates/transitive_import/android_common/package-res.apk",
+ "out/soong/.intermediates/direct/android_common/package-res.apk",
+ "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk",
+ "out/soong/.intermediates/direct_import/android_common/package-res.apk",
+ "out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat",
+ },
+ appImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"},
+ 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/direct/android_common/turbine-combined/direct.jar",
+ "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.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/aar/classes-combined.jar",
+ },
+
+ directResources: nil,
+ directOverlays: []string{
+ "out/soong/.intermediates/transitive/android_common/package-res.apk",
+ "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk",
+ "out/soong/.intermediates/transitive_import/android_common/package-res.apk",
+ "out/soong/.intermediates/direct/android_common/aapt2/direct/res/values_strings.arsc.flat",
+ },
+ 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/aar/classes-combined.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/aar/classes-combined.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: nil,
+ transitiveClasspath: []string{
+ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
+ "out/soong/.intermediates/transitive/android_common/busybox/R.jar",
+ },
+ transitiveCombined: nil,
+
+ dontVerifyDirectImport: true,
+ dontVerifyTransitiveImport: true,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ bp := fmt.Sprintf(`
+ android_app {
+ name: "app",
+ sdk_version: "current",
+ srcs: ["app/app.java"],
+ resource_dirs: ["app/res"],
+ manifest: "app/AndroidManifest.xml",
+ static_libs: ["direct", "direct_import"],
+ use_resource_processor: %v,
+ }
+
+ android_library {
+ name: "direct",
+ sdk_version: "current",
+ srcs: ["direct/direct.java"],
+ resource_dirs: ["direct/res"],
+ manifest: "direct/AndroidManifest.xml",
+ static_libs: ["transitive", "transitive_import"],
+ use_resource_processor: %v,
+ }
+
+ android_library {
+ name: "transitive",
+ sdk_version: "current",
+ srcs: ["transitive/transitive.java"],
+ resource_dirs: ["transitive/res"],
+ manifest: "transitive/AndroidManifest.xml",
+ use_resource_processor: %v,
+ }
+
+ android_library_import {
+ name: "direct_import",
+ sdk_version: "current",
+ aars: ["direct_import.aar"],
+ static_libs: ["direct_import_dep"],
+ }
+
+ android_library_import {
+ name: "direct_import_dep",
+ sdk_version: "current",
+ aars: ["direct_import_dep.aar"],
+ }
+
+ android_library_import {
+ name: "transitive_import",
+ sdk_version: "current",
+ aars: ["transitive_import.aar"],
+ static_libs: ["transitive_import_dep"],
+ }
+
+ android_library_import {
+ name: "transitive_import_dep",
+ sdk_version: "current",
+ aars: ["transitive_import_dep.aar"],
+ }
+ `, testCase.appUsesRP, testCase.directLibUsesRP, testCase.transitiveLibUsesRP)
+
+ fs := android.MockFS{
+ "app/res/values/strings.xml": nil,
+ "direct/res/values/strings.xml": nil,
+ "transitive/res/values/strings.xml": nil,
+ }
+
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ PrepareForTestWithOverlayBuildComponents,
+ fs.AddToFixture(),
+ ).RunTestWithBp(t, bp)
+
+ type aaptInfo struct {
+ resources, overlays, imports, srcJars, classpath, combined android.Paths
+ }
+
+ getAaptInfo := func(moduleName string) (aaptInfo aaptInfo) {
+ mod := result.ModuleForTests(moduleName, "android_common")
+ resourceListRule := mod.MaybeOutput("aapt2/res.list")
+ overlayListRule := mod.MaybeOutput("aapt2/overlay.list")
+ aaptRule := mod.Rule("aapt2Link")
+ javacRule := mod.MaybeRule("javac")
+ combinedRule := mod.MaybeOutput("combined/" + moduleName + ".jar")
+
+ aaptInfo.resources = resourceListRule.Inputs
+ aaptInfo.overlays = overlayListRule.Inputs
+
+ aaptFlags := strings.Split(aaptRule.Args["flags"], " ")
+ for i, flag := range aaptFlags {
+ if flag == "-I" && i+1 < len(aaptFlags) {
+ aaptInfo.imports = append(aaptInfo.imports, android.PathForTesting(aaptFlags[i+1]))
+ }
+ }
+
+ if len(javacRule.Args["srcJars"]) > 0 {
+ aaptInfo.srcJars = android.PathsForTesting(strings.Split(javacRule.Args["srcJars"], " ")...)
+ }
+
+ if len(javacRule.Args["classpath"]) > 0 {
+ classpathArg := strings.TrimPrefix(javacRule.Args["classpath"], "-classpath ")
+ aaptInfo.classpath = android.PathsForTesting(strings.Split(classpathArg, ":")...)
+ }
+
+ aaptInfo.combined = combinedRule.Inputs
+ return
+ }
+
+ app := getAaptInfo("app")
+ direct := getAaptInfo("direct")
+ transitive := getAaptInfo("transitive")
+ directImport := getAaptInfo("direct_import")
+ transitiveImport := getAaptInfo("transitive_import")
+
+ if !testCase.dontVerifyApp {
+ android.AssertPathsRelativeToTopEquals(t, "app resources", testCase.appResources, app.resources)
+ android.AssertPathsRelativeToTopEquals(t, "app overlays", testCase.appOverlays, app.overlays)
+ android.AssertPathsRelativeToTopEquals(t, "app imports", testCase.appImports, app.imports)
+ android.AssertPathsRelativeToTopEquals(t, "app srcjars", testCase.appSrcJars, app.srcJars)
+ android.AssertPathsRelativeToTopEquals(t, "app classpath", testCase.appClasspath, app.classpath)
+ android.AssertPathsRelativeToTopEquals(t, "app combined", testCase.appCombined, app.combined)
+ }
+
+ if !testCase.dontVerifyDirect {
+ android.AssertPathsRelativeToTopEquals(t, "direct resources", testCase.directResources, direct.resources)
+ android.AssertPathsRelativeToTopEquals(t, "direct overlays", testCase.directOverlays, direct.overlays)
+ android.AssertPathsRelativeToTopEquals(t, "direct imports", testCase.directImports, direct.imports)
+ android.AssertPathsRelativeToTopEquals(t, "direct srcjars", testCase.directSrcJars, direct.srcJars)
+ android.AssertPathsRelativeToTopEquals(t, "direct classpath", testCase.directClasspath, direct.classpath)
+ android.AssertPathsRelativeToTopEquals(t, "direct combined", testCase.directCombined, direct.combined)
+ }
+
+ if !testCase.dontVerifyTransitive {
+ android.AssertPathsRelativeToTopEquals(t, "transitive resources", testCase.transitiveResources, transitive.resources)
+ android.AssertPathsRelativeToTopEquals(t, "transitive overlays", testCase.transitiveOverlays, transitive.overlays)
+ android.AssertPathsRelativeToTopEquals(t, "transitive imports", testCase.transitiveImports, transitive.imports)
+ android.AssertPathsRelativeToTopEquals(t, "transitive srcjars", testCase.transitiveSrcJars, transitive.srcJars)
+ android.AssertPathsRelativeToTopEquals(t, "transitive classpath", testCase.transitiveClasspath, transitive.classpath)
+ android.AssertPathsRelativeToTopEquals(t, "transitive combined", testCase.transitiveCombined, transitive.combined)
+ }
+
+ if !testCase.dontVerifyDirectImport {
+ android.AssertPathsRelativeToTopEquals(t, "direct_import resources", testCase.directImportResources, directImport.resources)
+ android.AssertPathsRelativeToTopEquals(t, "direct_import overlays", testCase.directImportOverlays, directImport.overlays)
+ android.AssertPathsRelativeToTopEquals(t, "direct_import imports", testCase.directImportImports, directImport.imports)
+ }
+
+ if !testCase.dontVerifyTransitiveImport {
+ android.AssertPathsRelativeToTopEquals(t, "transitive_import resources", testCase.transitiveImportResources, transitiveImport.resources)
+ android.AssertPathsRelativeToTopEquals(t, "transitive_import overlays", testCase.transitiveImportOverlays, transitiveImport.overlays)
+ android.AssertPathsRelativeToTopEquals(t, "transitive_import imports", testCase.transitiveImportImports, transitiveImport.imports)
+ }
+ })
+ }
+}
+
+func TestAndroidResourceOverlays(t *testing.T) {
testCases := []struct {
name string
enforceRROTargets []string
@@ -943,7 +1453,7 @@ func TestAndroidResources(t *testing.T) {
overlayFiles = resourceListToFiles(module, android.PathsRelativeToTop(overlayList.Inputs))
}
- for _, d := range module.Module().(AndroidLibraryDependency).ExportedRRODirs() {
+ for _, d := range module.Module().(AndroidLibraryDependency).RRODirsDepSet().ToList() {
var prefix string
if d.overlayType == device {
prefix = "device:"
@@ -1232,7 +1742,7 @@ func TestJNIABI(t *testing.T) {
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
app := ctx.ModuleForTests(test.name, "android_common")
- jniLibZip := app.Output(jniJarOutputPathString)
+ jniLibZip := app.Output("jnilibs.zip")
var abis []string
args := strings.Fields(jniLibZip.Args["jarArgs"])
for i := 0; i < len(args); i++ {
@@ -1365,7 +1875,7 @@ func TestJNIPackaging(t *testing.T) {
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
app := ctx.ModuleForTests(test.name, "android_common")
- jniLibZip := app.MaybeOutput(jniJarOutputPathString)
+ 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)
}
@@ -1456,7 +1966,7 @@ func TestJNISDK(t *testing.T) {
t.Run(test.name, func(t *testing.T) {
app := ctx.ModuleForTests(test.name, "android_common")
- jniLibZip := app.MaybeOutput(jniJarOutputPathString)
+ jniLibZip := app.MaybeOutput("jnilibs.zip")
if len(jniLibZip.Implicits) != 1 {
t.Fatalf("expected exactly one jni library, got %q", jniLibZip.Implicits.Strings())
}
@@ -2476,7 +2986,7 @@ func TestStl(t *testing.T) {
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
app := ctx.ModuleForTests(test.name, "android_common")
- jniLibZip := app.Output(jniJarOutputPathString)
+ jniLibZip := app.Output("jnilibs.zip")
var jnis []string
args := strings.Fields(jniLibZip.Args["jarArgs"])
for i := 0; i < len(args); i++ {
@@ -2645,7 +3155,7 @@ func TestUsesLibraries(t *testing.T) {
PrepareForTestWithJavaSdkLibraryFiles,
FixtureWithLastReleaseApis("runtime-library", "foo", "quuz", "qux", "bar", "fred"),
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.MissingUsesLibraries = []string{"baz"}
+ variables.BuildWarningBadOptionalUsesLibsAllowlist = []string{"app", "prebuilt"}
}),
).RunTestWithBp(t, bp)
@@ -2693,52 +3203,11 @@ func TestUsesLibraries(t *testing.T) {
`--optional-uses-library baz `
android.AssertStringDoesContain(t, "verify apk cmd args", verifyApkCmd, verifyApkArgs)
- // Test that all present libraries are preopted, including implicit SDK dependencies, possibly stubs
+ // Test that necessary args are passed for constructing CLC in Ninja phase.
cmd := app.Rule("dexpreopt").RuleParams.Command
- w := `--target-context-for-sdk any ` +
- `PCL[/system/framework/qux.jar]#` +
- `PCL[/system/framework/quuz.jar]#` +
- `PCL[/system/framework/foo.jar]#` +
- `PCL[/system/framework/non-sdk-lib.jar]#` +
- `PCL[/system/framework/bar.jar]#` +
- `PCL[/system/framework/runtime-library.jar]#` +
- `PCL[/system/framework/runtime-required-x.jar]#` +
- `PCL[/system/framework/runtime-optional-x.jar]#` +
- `PCL[/system/framework/runtime-required-y.jar]#` +
- `PCL[/system/framework/runtime-optional-y.jar] `
- android.AssertStringDoesContain(t, "dexpreopt app cmd args", cmd, w)
-
- // Test conditional context for target SDK version 28.
- android.AssertStringDoesContain(t, "dexpreopt app cmd 28", cmd,
- `--target-context-for-sdk 28`+
- ` PCL[/system/framework/org.apache.http.legacy.jar] `)
-
- // Test conditional context for target SDK version 29.
- android.AssertStringDoesContain(t, "dexpreopt app cmd 29", cmd,
- `--target-context-for-sdk 29`+
- ` PCL[/system/framework/android.hidl.manager-V1.0-java.jar]`+
- `#PCL[/system/framework/android.hidl.base-V1.0-java.jar] `)
-
- // Test conditional context for target SDK version 30.
- // "android.test.mock" is absent because "android.test.runner" is not used.
- android.AssertStringDoesContain(t, "dexpreopt app cmd 30", cmd,
- `--target-context-for-sdk 30`+
- ` PCL[/system/framework/android.test.base.jar] `)
-
- cmd = prebuilt.Rule("dexpreopt").RuleParams.Command
- android.AssertStringDoesContain(t, "dexpreopt prebuilt cmd", cmd,
- `--target-context-for-sdk any`+
- ` PCL[/system/framework/foo.jar]`+
- `#PCL[/system/framework/non-sdk-lib.jar]`+
- `#PCL[/system/framework/android.test.runner.jar]`+
- `#PCL[/system/framework/bar.jar] `)
-
- // Test conditional context for target SDK version 30.
- // "android.test.mock" is present because "android.test.runner" is used.
- android.AssertStringDoesContain(t, "dexpreopt prebuilt cmd 30", cmd,
- `--target-context-for-sdk 30`+
- ` PCL[/system/framework/android.test.base.jar]`+
- `#PCL[/system/framework/android.test.mock.jar] `)
+ android.AssertStringDoesContain(t, "dexpreopt app cmd context", cmd, "--context-json=")
+ android.AssertStringDoesContain(t, "dexpreopt app cmd product_packages", cmd,
+ "--product-packages=out/soong/.intermediates/app/android_common/dexpreopt/product_packages.txt")
}
func TestDexpreoptBcp(t *testing.T) {
@@ -3547,3 +4016,124 @@ func TestTargetSdkVersionMtsTests(t *testing.T) {
android.AssertStringDoesContain(t, testCase.desc, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
}
}
+
+func TestPrivappAllowlist(t *testing.T) {
+ testJavaError(t, "privileged must be set in order to use privapp_allowlist", `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ privapp_allowlist: "perms.xml",
+ }
+ `)
+
+ result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(
+ t,
+ `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ privapp_allowlist: "privapp_allowlist_com.android.foo.xml",
+ privileged: true,
+ sdk_version: "current",
+ }
+ override_android_app {
+ name: "bar",
+ base: "foo",
+ package_name: "com.google.android.foo",
+ }
+ `,
+ )
+ app := result.ModuleForTests("foo", "android_common")
+ overrideApp := result.ModuleForTests("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")
+ expectedAllowlistInput := "privapp_allowlist_com.android.foo.xml"
+ overrideActualAllowlistInput := overrideApp.Rule("modifyAllowlist").Input.String()
+ if expectedAllowlistInput != overrideActualAllowlistInput {
+ t.Errorf("expected override allowlist to be %q; got %q", expectedAllowlistInput, overrideActualAllowlistInput)
+ }
+
+ // 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")
+}
+
+func TestPrivappAllowlistAndroidMk(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ android.PrepareForTestWithAndroidMk,
+ ).RunTestWithBp(
+ t,
+ `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ privapp_allowlist: "privapp_allowlist_com.android.foo.xml",
+ privileged: true,
+ sdk_version: "current",
+ }
+ override_android_app {
+ name: "bar",
+ base: "foo",
+ package_name: "com.google.android.foo",
+ }
+ `,
+ )
+ baseApp := result.ModuleForTests("foo", "android_common")
+ overrideApp := result.ModuleForTests("foo", "android_common_bar")
+
+ baseAndroidApp := baseApp.Module().(*AndroidApp)
+ baseEntries := android.AndroidMkEntriesForTest(t, result.TestContext, baseAndroidApp)[0]
+ android.AssertStringMatches(
+ t,
+ "androidmk has incorrect LOCAL_SOONG_INSTALLED_MODULE; expected to find foo.apk",
+ baseEntries.EntryMap["LOCAL_SOONG_INSTALLED_MODULE"][0],
+ "\\S+foo.apk",
+ )
+ android.AssertStringMatches(
+ t,
+ "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include foo.apk",
+ baseEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
+ "\\S+foo.apk",
+ )
+ android.AssertStringMatches(
+ t,
+ "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include app",
+ baseEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
+ "\\S+foo.apk:\\S+/target/product/test_device/system/priv-app/foo/foo.apk",
+ )
+ android.AssertStringMatches(
+ t,
+ "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include privapp_allowlist",
+ baseEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
+ "privapp_allowlist_com.android.foo.xml:\\S+/target/product/test_device/system/etc/permissions/foo.xml",
+ )
+
+ overrideAndroidApp := overrideApp.Module().(*AndroidApp)
+ overrideEntries := android.AndroidMkEntriesForTest(t, result.TestContext, overrideAndroidApp)[0]
+ android.AssertStringMatches(
+ t,
+ "androidmk has incorrect LOCAL_SOONG_INSTALLED_MODULE; expected to find bar.apk",
+ overrideEntries.EntryMap["LOCAL_SOONG_INSTALLED_MODULE"][0],
+ "\\S+bar.apk",
+ )
+ android.AssertStringMatches(
+ t,
+ "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include bar.apk",
+ overrideEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
+ "\\S+bar.apk",
+ )
+ android.AssertStringMatches(
+ t,
+ "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include app",
+ overrideEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
+ "\\S+bar.apk:\\S+/target/product/test_device/system/priv-app/bar/bar.apk",
+ )
+ android.AssertStringMatches(
+ t,
+ "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include privapp_allowlist",
+ overrideEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
+ "\\S+soong/.intermediates/foo/android_common_bar/privapp_allowlist_com.google.android.foo.xml:\\S+/target/product/test_device/system/etc/permissions/bar.xml",
+ )
+}
diff --git a/java/base.go b/java/base.go
index 991132321..f5eb01c4b 100644
--- a/java/base.go
+++ b/java/base.go
@@ -20,6 +20,8 @@ import (
"strconv"
"strings"
+ "android/soong/ui/metrics/bp2build_metrics_proto"
+
"github.com/google/blueprint/pathtools"
"github.com/google/blueprint/proptools"
@@ -79,6 +81,9 @@ type CommonProperties struct {
// list of java libraries that will be compiled into the resulting jar
Static_libs []string `android:"arch_variant"`
+ // list of java libraries that should not be used to build this module
+ Exclude_static_libs []string `android:"arch_variant"`
+
// manifest file to be included in resulting jar
Manifest *string `android:"path"`
@@ -184,6 +189,9 @@ type CommonProperties struct {
// A list of java_library instances that provide additional hiddenapi annotations for the library.
Hiddenapi_additional_annotations []string
+
+ // Additional srcJars tacked in by GeneratedJavaLibraryModule
+ Generated_srcjars []android.Path `android:"mutated"`
}
// Properties that are specific to device modules. Host module factories should not add these when
@@ -493,6 +501,21 @@ type Module struct {
maxSdkVersion android.ApiLevel
sourceExtensions []string
+
+ annoSrcJars android.Paths
+
+ // output file name based on Stem property.
+ // This should be set in every ModuleWithStem's GenerateAndroidBuildActions
+ // or the module should override Stem().
+ stem string
+
+ // Aconfig "cache files" that went directly into this module. Transitive ones are
+ // tracked via JavaInfo.TransitiveAconfigFiles
+ // TODO: Extract to something standalone to propagate tags via GeneratedJavaLibraryModule
+ aconfigIntermediates android.Paths
+
+ // Aconfig files for all transitive deps. Also exposed via JavaInfo
+ transitiveAconfigFiles *android.DepSet[android.Path]
}
func (j *Module) CheckStableSdkVersion(ctx android.BaseModuleContext) error {
@@ -724,6 +747,8 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) {
}
libDeps := ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
+
+ j.properties.Static_libs = android.RemoveListFromList(j.properties.Static_libs, j.properties.Exclude_static_libs)
ctx.AddVariationDependencies(nil, staticLibTag, j.properties.Static_libs...)
// Add dependency on libraries that provide additional hidden api annotations.
@@ -1036,7 +1061,11 @@ func (j *Module) AddJSONData(d *map[string]interface{}) {
}
-func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
+func (module *Module) addGeneratedSrcJars(path android.Path) {
+ module.properties.Generated_srcjars = append(module.properties.Generated_srcjars, path)
+}
+
+func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspathJars, extraCombinedJars android.Paths) {
j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs)
deps := j.collectDeps(ctx)
@@ -1074,16 +1103,15 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
srcJars := srcFiles.FilterByExt(".srcjar")
srcJars = append(srcJars, deps.srcJars...)
- if aaptSrcJar != nil {
- srcJars = append(srcJars, aaptSrcJar)
- }
+ srcJars = append(srcJars, extraSrcJars...)
+ srcJars = append(srcJars, j.properties.Generated_srcjars...)
srcFiles = srcFiles.FilterOutByExt(".srcjar")
if j.properties.Jarjar_rules != nil {
j.expandJarjarRules = android.PathForModuleSrc(ctx, *j.properties.Jarjar_rules)
}
- jarName := ctx.ModuleName() + ".jar"
+ jarName := j.Stem() + ".jar"
var uniqueJavaFiles android.Paths
set := make(map[string]bool)
@@ -1118,6 +1146,11 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
var kotlinJars android.Paths
var kotlinHeaderJars android.Paths
+ // Prepend extraClasspathJars to classpath so that the resource processor R.jar comes before
+ // any dependencies so that it can override any non-final R classes from dependencies with the
+ // final R classes from the app.
+ flags.classpath = append(android.CopyOf(extraClasspathJars), flags.classpath...)
+
if srcFiles.HasExt(".kt") {
// When using kotlin sources turbine is used to generate annotation processor sources,
// including for annotation processors that generate API, so we can use turbine for
@@ -1211,8 +1244,9 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
// allow for the use of annotation processors that do function correctly
// with sharding enabled. See: b/77284273.
}
+ extraJars := append(android.CopyOf(extraCombinedJars), kotlinHeaderJars...)
headerJarFileWithoutDepsOrJarjar, j.headerJarFile =
- j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, kotlinHeaderJars)
+ j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, extraJars)
if ctx.Failed() {
return
}
@@ -1241,8 +1275,9 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
// 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, errorproneFlags, nil,
+ transformJavaToClasses(ctx, errorprone, -1, uniqueJavaFiles, srcJars, errorproneAnnoSrcJar, errorproneFlags, nil,
"errorprone", "errorprone")
extraJarDeps = append(extraJarDeps, errorprone)
@@ -1362,6 +1397,8 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
jars = append(jars, servicesJar)
}
+ jars = append(android.CopyOf(extraCombinedJars), jars...)
+
// Combine the classes built from sources, any manifests, and any static libraries into
// classes.jar. If there is only one input jar this step will be skipped.
var outputFile android.OutputPath
@@ -1372,12 +1409,20 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
// prebuilt dependencies until we support modules in the platform build, so there shouldn't be
// any if len(jars) == 1.
+ // moduleStubLinkType determines if the module is the TopLevelStubLibrary generated
+ // from sdk_library. The TopLevelStubLibrary contains only one static lib,
+ // either with .from-source or .from-text suffix.
+ // outputFile should be agnostic to the build configuration,
+ // thus "combine" the single static lib in order to prevent the static lib from being exposed
+ // to the copy rules.
+ stub, _ := moduleStubLinkType(ctx.ModuleName())
+
// Transform the single path to the jar into an OutputPath as that is required by the following
// code.
- if moduleOutPath, ok := jars[0].(android.ModuleOutPath); ok {
+ if moduleOutPath, ok := jars[0].(android.ModuleOutPath); ok && !stub {
// The path contains an embedded OutputPath so reuse that.
outputFile = moduleOutPath.OutputPath
- } else if outputPath, ok := jars[0].(android.OutputPath); ok {
+ } else if outputPath, ok := jars[0].(android.OutputPath); ok && !stub {
// The path is an OutputPath so reuse it directly.
outputFile = outputPath
} else {
@@ -1446,7 +1491,13 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
j.implementationJarFile = outputFile
if j.headerJarFile == nil {
- j.headerJarFile = j.implementationJarFile
+ // If this module couldn't generate a header jar (for example due to api generating annotation processors)
+ // then use the implementation jar. Run it through zip2zip first to remove any files in META-INF/services
+ // so that javac on modules that depend on this module don't pick up annotation processors (which may be
+ // missing their implementations) from META-INF/services/javax.annotation.processing.Processor.
+ headerJarFile := android.PathForModuleOut(ctx, "javac-header", jarName)
+ convertImplementationJarToHeaderJar(ctx, j.implementationJarFile, headerJarFile)
+ j.headerJarFile = headerJarFile
}
// enforce syntax check to jacoco filters for any build (http://b/183622051)
@@ -1592,6 +1643,8 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
ctx.CheckbuildFile(outputFile)
+ j.collectTransitiveAconfigFiles(ctx)
+
ctx.SetProvider(JavaInfoProvider, JavaInfo{
HeaderJars: android.PathsIfNonNil(j.headerJarFile),
TransitiveLibsHeaderJars: j.transitiveLibsHeaderJars,
@@ -1606,6 +1659,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
ExportedPluginClasses: j.exportedPluginClasses,
ExportedPluginDisableTurbine: j.exportedDisableTurbine,
JacocoReportClassesFile: j.jacocoReportClassesFile,
+ TransitiveAconfigFiles: j.transitiveAconfigFiles,
})
// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
@@ -1635,13 +1689,15 @@ func (j *Module) compileJavaClasses(ctx android.ModuleContext, jarName string, i
srcFiles, srcJars android.Paths, flags javaBuilderFlags, extraJarDeps android.Paths) android.WritablePath {
kzipName := pathtools.ReplaceExtension(jarName, "kzip")
+ annoSrcJar := android.PathForModuleOut(ctx, "javac", "anno.srcjar")
if idx >= 0 {
kzipName = strings.TrimSuffix(jarName, filepath.Ext(jarName)) + strconv.Itoa(idx) + ".kzip"
+ annoSrcJar = android.PathForModuleOut(ctx, "javac", "anno-"+strconv.Itoa(idx)+".srcjar")
jarName += strconv.Itoa(idx)
}
classes := android.PathForModuleOut(ctx, "javac", jarName).OutputPath
- TransformJavaToClasses(ctx, classes, idx, srcFiles, srcJars, flags, extraJarDeps)
+ TransformJavaToClasses(ctx, classes, idx, srcFiles, srcJars, annoSrcJar, flags, extraJarDeps)
if ctx.Config().EmitXrefRules() {
extractionFile := android.PathForModuleOut(ctx, kzipName)
@@ -1649,6 +1705,10 @@ func (j *Module) compileJavaClasses(ctx android.ModuleContext, jarName string, i
j.kytheFiles = append(j.kytheFiles, extractionFile)
}
+ if len(flags.processorPath) > 0 {
+ j.annoSrcJars = append(j.annoSrcJars, annoSrcJar)
+ }
+
return classes
}
@@ -1734,24 +1794,24 @@ func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags,
type providesTransitiveHeaderJars struct {
// set of header jars for all transitive libs deps
- transitiveLibsHeaderJars *android.DepSet
+ transitiveLibsHeaderJars *android.DepSet[android.Path]
// set of header jars for all transitive static libs deps
- transitiveStaticLibsHeaderJars *android.DepSet
+ transitiveStaticLibsHeaderJars *android.DepSet[android.Path]
}
-func (j *providesTransitiveHeaderJars) TransitiveLibsHeaderJars() *android.DepSet {
+func (j *providesTransitiveHeaderJars) TransitiveLibsHeaderJars() *android.DepSet[android.Path] {
return j.transitiveLibsHeaderJars
}
-func (j *providesTransitiveHeaderJars) TransitiveStaticLibsHeaderJars() *android.DepSet {
+func (j *providesTransitiveHeaderJars) TransitiveStaticLibsHeaderJars() *android.DepSet[android.Path] {
return j.transitiveStaticLibsHeaderJars
}
func (j *providesTransitiveHeaderJars) collectTransitiveHeaderJars(ctx android.ModuleContext) {
directLibs := android.Paths{}
directStaticLibs := android.Paths{}
- transitiveLibs := []*android.DepSet{}
- transitiveStaticLibs := []*android.DepSet{}
+ transitiveLibs := []*android.DepSet[android.Path]{}
+ transitiveStaticLibs := []*android.DepSet[android.Path]{}
ctx.VisitDirectDeps(func(module android.Module) {
// don't add deps of the prebuilt version of the same library
if ctx.ModuleName() == android.RemoveOptionalPrebuiltPrefix(module.Name()) {
@@ -1828,6 +1888,7 @@ func (j *Module) IDEInfo(dpInfo *android.IdeInfo) {
dpInfo.Paths = append(dpInfo.Paths, j.modulePaths...)
dpInfo.Static_libs = append(dpInfo.Static_libs, j.properties.Static_libs...)
dpInfo.Libs = append(dpInfo.Libs, j.properties.Libs...)
+ dpInfo.SrcJars = append(dpInfo.SrcJars, j.annoSrcJars.Strings()...)
}
func (j *Module) CompilerDeps() []string {
@@ -1865,7 +1926,10 @@ func (j *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersi
}
func (j *Module) Stem() string {
- return proptools.StringDefault(j.overridableDeviceProperties.Stem, j.Name())
+ if j.stem == "" {
+ panic("Stem() called before stem property was set")
+ }
+ return j.stem
}
func (j *Module) JacocoReportClassesFile() android.Path {
@@ -1876,6 +1940,34 @@ func (j *Module) IsInstallable() bool {
return Bool(j.properties.Installable)
}
+func (j *Module) collectTransitiveAconfigFiles(ctx android.ModuleContext) {
+ // Aconfig files from this module
+ mine := j.aconfigIntermediates
+
+ // Aconfig files from transitive dependencies
+ fromDeps := []*android.DepSet[android.Path]{}
+ ctx.VisitDirectDeps(func(module android.Module) {
+ dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
+ if dep.TransitiveAconfigFiles != nil {
+ fromDeps = append(fromDeps, dep.TransitiveAconfigFiles)
+ }
+ })
+
+ // DepSet containing aconfig files myself and from dependencies
+ j.transitiveAconfigFiles = android.NewDepSet(android.POSTORDER, mine, fromDeps)
+}
+
+func (j *Module) AddAconfigIntermediate(path android.Path) {
+ j.aconfigIntermediates = append(j.aconfigIntermediates, path)
+}
+
+func (j *Module) getTransitiveAconfigFiles() *android.DepSet[android.Path] {
+ if j.transitiveAconfigFiles == nil {
+ panic(fmt.Errorf("java.Moduile: getTransitiveAconfigFiles called before collectTransitiveAconfigFiles module=%s", j.Name()))
+ }
+ return j.transitiveAconfigFiles
+}
+
type sdkLinkType int
const (
@@ -1923,19 +2015,22 @@ type moduleWithSdkDep interface {
func (m *Module) getSdkLinkType(ctx android.BaseModuleContext, name string) (ret sdkLinkType, stubs bool) {
switch name {
- case android.SdkCore.JavaLibraryName(ctx.Config()), "legacy.core.platform.api.stubs", "stable.core.platform.api.stubs",
+ case android.SdkCore.DefaultJavaLibraryName(),
+ "legacy.core.platform.api.stubs",
+ "stable.core.platform.api.stubs",
"stub-annotations", "private-stub-annotations-jar",
- "core-lambda-stubs", "core-generated-annotation-stubs":
+ "core-lambda-stubs",
+ "core-generated-annotation-stubs":
return javaCore, true
- case android.SdkPublic.JavaLibraryName(ctx.Config()):
+ case android.SdkPublic.DefaultJavaLibraryName():
return javaSdk, true
- case android.SdkSystem.JavaLibraryName(ctx.Config()):
+ case android.SdkSystem.DefaultJavaLibraryName():
return javaSystem, true
- case android.SdkModule.JavaLibraryName(ctx.Config()):
+ case android.SdkModule.DefaultJavaLibraryName():
return javaModule, true
- case android.SdkSystemServer.JavaLibraryName(ctx.Config()):
+ case android.SdkSystemServer.DefaultJavaLibraryName():
return javaSystemServer, true
- case android.SdkTest.JavaLibraryName(ctx.Config()):
+ case android.SdkTest.DefaultJavaLibraryName():
return javaSystem, true
}
@@ -2177,7 +2272,7 @@ var _ ModuleWithStem = (*Module)(nil)
func (j *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
switch ctx.ModuleType() {
- case "java_library", "java_library_host", "java_library_static":
+ case "java_library", "java_library_host", "java_library_static", "tradefed_java_library_host":
if lib, ok := ctx.Module().(*Library); ok {
javaLibraryBp2Build(ctx, lib)
}
@@ -2185,5 +2280,11 @@ func (j *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
if binary, ok := ctx.Module().(*Binary); ok {
javaBinaryHostBp2Build(ctx, binary)
}
+ case "java_test_host":
+ if testHost, ok := ctx.Module().(*TestHost); ok {
+ javaTestHostBp2Build(ctx, testHost)
+ }
+ default:
+ ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_TYPE_UNSUPPORTED, "")
}
}
diff --git a/java/bootclasspath.go b/java/bootclasspath.go
index f4cef7fa6..c7dc3afae 100644
--- a/java/bootclasspath.go
+++ b/java/bootclasspath.go
@@ -77,7 +77,7 @@ func addDependencyOntoApexVariants(ctx android.BottomUpMutatorContext, propertyN
// Use gatherApexModulePairDepsWithTag to retrieve the dependencies.
func addDependencyOntoApexModulePair(ctx android.BottomUpMutatorContext, apex string, name string, tag blueprint.DependencyTag) {
var variations []blueprint.Variation
- if apex != "platform" && apex != "system_ext" {
+ if !android.IsConfiguredJarForPlatform(apex) {
// Pick the correct apex variant.
variations = []blueprint.Variation{
{Mutator: "apex", Variation: apex},
@@ -185,6 +185,9 @@ 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 108fdd483..dcc2dece7 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -242,7 +242,7 @@ type BootclasspathFragmentModule struct {
modulePaths []string
// Path to the boot image profile.
- profilePath android.Path
+ profilePath android.WritablePath
}
// commonBootclasspathFragment defines the methods that are implemented by both source and prebuilt
@@ -256,16 +256,6 @@ type commonBootclasspathFragment interface {
// versioned sdk.
produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, fragments []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput
- // produceBootImageFiles will attempt to produce rules to create the boot image files at the paths
- // predefined in the bootImageConfig.
- //
- // If it could not create the files then it will return nil. Otherwise, it will return a map from
- // android.ArchType to the predefined paths of the boot image files.
- produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs
-
- // getImageName returns the `image_name` property of this fragment.
- getImageName() *string
-
// getProfilePath returns the path to the boot image profile.
getProfilePath() android.Path
}
@@ -295,9 +285,6 @@ func bootclasspathFragmentFactory() android.Module {
return
}
}
-
- // Initialize the contents property from the image_name.
- bootclasspathFragmentInitContentsFromImage(ctx, m)
})
return m
}
@@ -308,9 +295,7 @@ func testBootclasspathFragmentFactory() android.Module {
return m
}
-// bootclasspathFragmentInitContentsFromImage will initialize the contents property from the image_name if
-// necessary.
-func bootclasspathFragmentInitContentsFromImage(ctx android.EarlyModuleContext, m *BootclasspathFragmentModule) {
+func (m *BootclasspathFragmentModule) bootclasspathFragmentPropertyCheck(ctx android.EarlyModuleContext) {
contents := m.properties.Contents
if len(contents) == 0 {
ctx.PropertyErrorf("contents", "required property is missing")
@@ -332,6 +317,18 @@ func bootclasspathFragmentInitContentsFromImage(ctx android.EarlyModuleContext,
// too early in the Soong processing for that to work.
global := dexpreopt.GetGlobalConfig(ctx)
modules := global.ArtApexJars
+ configuredJars := modules.CopyOfJars()
+
+ // Skip the check if the configured jars list is empty as that is a common configuration when
+ // building targets that do not result in a system image.
+ if len(configuredJars) == 0 {
+ return
+ }
+
+ if !reflect.DeepEqual(configuredJars, contents) {
+ ctx.ModuleErrorf("inconsistency in specification of contents. ArtApexJars configuration specifies %#v, contents property specifies %#v",
+ configuredJars, contents)
+ }
// Make sure that the apex specified in the configuration is consistent and is one for which
// this boot image is available.
@@ -357,42 +354,11 @@ func bootclasspathFragmentInitContentsFromImage(ctx android.EarlyModuleContext,
}
}
-// bootclasspathImageNameContentsConsistencyCheck checks that the configuration that applies to this
-// module (if any) matches the contents.
-//
-// This should be a noop as if image_name="art" then the contents will be set from the ArtApexJars
-// config by bootclasspathFragmentInitContentsFromImage so it will be guaranteed to match. However,
-// in future this will not be the case.
-func (b *BootclasspathFragmentModule) bootclasspathImageNameContentsConsistencyCheck(ctx android.BaseModuleContext) {
- imageName := proptools.String(b.properties.Image_name)
- if imageName == "art" {
- // Get the configuration for the art apex jars.
- modules := b.getImageConfig(ctx).modules
- configuredJars := modules.CopyOfJars()
-
- // Skip the check if the configured jars list is empty as that is a common configuration when
- // building targets that do not result in a system image.
- if len(configuredJars) == 0 {
- return
- }
-
- contents := b.properties.Contents
- if !reflect.DeepEqual(configuredJars, contents) {
- ctx.ModuleErrorf("inconsistency in specification of contents. ArtApexJars configuration specifies %#v, contents property specifies %#v",
- configuredJars, contents)
- }
- }
-}
-
var BootclasspathFragmentApexContentInfoProvider = blueprint.NewProvider(BootclasspathFragmentApexContentInfo{})
// BootclasspathFragmentApexContentInfo contains the bootclasspath_fragments contributions to the
// apex contents.
type BootclasspathFragmentApexContentInfo struct {
- // The configured modules, will be empty if this is from a bootclasspath_fragment that does not
- // set image_name: "art".
- modules android.ConfiguredJarList
-
// Map from the base module name (without prebuilt_ prefix) of a fragment's contents module to the
// hidden API encoded dex jar path.
contentModuleDexJarPaths bootDexJarByModule
@@ -405,10 +371,6 @@ type BootclasspathFragmentApexContentInfo struct {
profileInstallPathInApex string
}
-func (i BootclasspathFragmentApexContentInfo) Modules() android.ConfiguredJarList {
- return i.modules
-}
-
// DexBootJarPathForContentModule returns the path to the dex boot jar for specified module.
//
// The dex boot jar is one which has had hidden API encoding performed on it.
@@ -479,8 +441,6 @@ func (b *BootclasspathFragmentModule) DepsMutator(ctx android.BottomUpMutatorCon
for _, apiScope := range hiddenAPISdkLibrarySupportedScopes {
// Add a dependency onto a possibly scope specific stub library.
scopeSpecificDependency := apiScope.scopeSpecificStubModule(ctx, additionalStubModule)
- // Use JavaApiLibraryName function to be redirected to stubs generated from .txt if applicable
- scopeSpecificDependency = android.JavaApiLibraryName(ctx.Config(), scopeSpecificDependency)
tag := hiddenAPIStubsDependencyTag{apiScope: apiScope, fromAdditionalDependency: true}
ctx.AddVariationDependencies(nil, tag, scopeSpecificDependency)
}
@@ -505,7 +465,7 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo
// unused prebuilt that was created without instrumentation from breaking an instrumentation
// build.
if isActiveModule(ctx.Module()) {
- b.bootclasspathImageNameContentsConsistencyCheck(ctx)
+ b.bootclasspathFragmentPropertyCheck(ctx)
}
// Generate classpaths.proto config
@@ -525,34 +485,15 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo
fragments := gatherApexModulePairDepsWithTag(ctx, bootclasspathFragmentDepTag)
- // Verify that the image_name specified on a bootclasspath_fragment is valid even if this is a
- // prebuilt which will not use the image config.
- imageConfig := b.getImageConfig(ctx)
-
// Perform hidden API processing.
hiddenAPIOutput := b.generateHiddenAPIBuildActions(ctx, contents, fragments)
- var bootImageFiles bootImageOutputs
- if imageConfig != nil {
- // Delegate the production of the boot image files to a module type specific method.
- common := ctx.Module().(commonBootclasspathFragment)
- bootImageFiles = common.produceBootImageFiles(ctx, imageConfig)
- b.profilePath = bootImageFiles.profile
-
- if shouldCopyBootFilesToPredefinedLocations(ctx, imageConfig) {
- // Zip the boot image files up, if available. This will generate the zip file in a
- // predefined location.
- buildBootImageZipInPredefinedLocation(ctx, imageConfig, bootImageFiles.byArch)
-
- // Copy the dex jars of this fragment's content modules to their predefined locations.
- copyBootJarsToPredefinedLocations(ctx, hiddenAPIOutput.EncodedBootDexFilesByModule, imageConfig.dexPathsByModule)
- }
- }
-
- // A prebuilt fragment cannot contribute to an apex.
- if !android.IsModulePrebuilt(ctx.Module()) {
- // Provide the apex content info.
- b.provideApexContentInfo(ctx, imageConfig, hiddenAPIOutput, bootImageFiles)
+ if android.IsModulePrebuilt(ctx.Module()) {
+ b.profilePath = ctx.Module().(*PrebuiltBootclasspathFragmentModule).produceBootImageProfile(ctx)
+ } else {
+ b.profilePath = b.produceBootImageProfileFromSource(ctx, contents, hiddenAPIOutput.EncodedBootDexFilesByModule)
+ // Provide the apex content info. A prebuilt fragment cannot contribute to an apex.
+ b.provideApexContentInfo(ctx, hiddenAPIOutput, b.profilePath)
}
// In order for information about bootclasspath_fragment modules to be added to module-info.json
@@ -566,45 +507,37 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo
}
}
-// shouldCopyBootFilesToPredefinedLocations determines whether the current module should copy boot
-// files, e.g. boot dex jars or boot image files, to the predefined location expected by the rest
-// of the build.
-//
-// This ensures that only a single module will copy its files to the image configuration.
-func shouldCopyBootFilesToPredefinedLocations(ctx android.ModuleContext, imageConfig *bootImageConfig) bool {
- // Bootclasspath fragment modules that are for the platform do not produce boot related files.
- apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
- if apexInfo.IsForPlatform() {
- return false
+// getProfileProviderApex returns the name of the apex that provides a boot image profile, or an
+// empty string if this module should not provide a boot image profile.
+func (b *BootclasspathFragmentModule) getProfileProviderApex(ctx android.BaseModuleContext) string {
+ // Only use the profile from the module that is preferred.
+ if !isActiveModule(ctx.Module()) {
+ return ""
}
- // If the image configuration has no modules specified then it means that the build has been
- // configured to build something other than a boot image, e.g. an sdk, so do not try and copy the
- // files.
- if imageConfig.modules.Len() == 0 {
- return false
+ // Bootclasspath fragment modules that are for the platform do not produce boot related files.
+ apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
+ for _, apex := range apexInfo.InApexVariants {
+ if isProfileProviderApex(ctx, apex) {
+ return apex
+ }
}
- // Only copy files from the module that is preferred.
- return isActiveModule(ctx.Module())
+ return ""
}
// provideApexContentInfo creates, initializes and stores the apex content info for use by other
// modules.
-func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleContext, imageConfig *bootImageConfig, hiddenAPIOutput *HiddenAPIOutput, bootImageFiles bootImageOutputs) {
+func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleContext, hiddenAPIOutput *HiddenAPIOutput, profile android.WritablePath) {
// Construct the apex content info from the config.
info := BootclasspathFragmentApexContentInfo{
// Populate the apex content info with paths to the dex jars.
contentModuleDexJarPaths: hiddenAPIOutput.EncodedBootDexFilesByModule,
}
- if imageConfig != nil {
- info.modules = imageConfig.modules
- global := dexpreopt.GetGlobalConfig(ctx)
- if !global.DisableGenerateProfile {
- info.profilePathOnHost = bootImageFiles.profile
- info.profileInstallPathInApex = imageConfig.profileInstallPathInApex
- }
+ if profile != nil {
+ info.profilePathOnHost = profile
+ info.profileInstallPathInApex = profileInstallPathInApex
}
// Make the apex content info available for other modules.
@@ -625,12 +558,12 @@ func (b *BootclasspathFragmentModule) generateClasspathProtoBuildActions(ctx and
}
func (b *BootclasspathFragmentModule) configuredJars(ctx android.ModuleContext) android.ConfiguredJarList {
+ global := dexpreopt.GetGlobalConfig(ctx)
+
if "art" == proptools.String(b.properties.Image_name) {
- return b.getImageConfig(ctx).modules
+ return global.ArtApexJars
}
- global := dexpreopt.GetGlobalConfig(ctx)
-
possibleUpdatableModules := gatherPossibleApexModuleNamesAndStems(ctx, b.properties.Contents, bootclasspathFragmentContentDepTag)
jars, unknown := global.ApexBootJars.Filter(possibleUpdatableModules)
@@ -656,25 +589,6 @@ func (b *BootclasspathFragmentModule) configuredJars(ctx android.ModuleContext)
return jars
}
-func (b *BootclasspathFragmentModule) getImageConfig(ctx android.EarlyModuleContext) *bootImageConfig {
- // Get a map of the image configs that are supported.
- imageConfigs := genBootImageConfigs(ctx)
-
- // Retrieve the config for this image.
- imageNamePtr := b.properties.Image_name
- if imageNamePtr == nil {
- return nil
- }
-
- imageName := *imageNamePtr
- imageConfig := imageConfigs[imageName]
- if imageConfig == nil {
- ctx.PropertyErrorf("image_name", "Unknown image name %q, expected one of %s", imageName, strings.Join(android.SortedKeys(imageConfigs), ", "))
- return nil
- }
- return imageConfig
-}
-
// generateHiddenAPIBuildActions generates all the hidden API related build rules.
func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, contents []android.Module, fragments []android.Module) *HiddenAPIOutput {
@@ -857,48 +771,22 @@ func (b *BootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleC
return output
}
-// produceBootImageFiles builds the boot image files from the source if it is required.
-func (b *BootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs {
- // Only generate the boot image if the configuration does not skip it.
- return b.generateBootImageBuildActions(ctx, imageConfig)
-}
-
-// generateBootImageBuildActions generates ninja rules to create the boot image if required for this
-// module.
-//
-// If it could not create the files then it will return nil. Otherwise, it will return a map from
-// android.ArchType to the predefined paths of the boot image files.
-func (b *BootclasspathFragmentModule) generateBootImageBuildActions(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs {
- global := dexpreopt.GetGlobalConfig(ctx)
- if !shouldBuildBootImages(ctx.Config(), global) {
- return bootImageOutputs{}
- }
-
- // Bootclasspath fragment modules that are for the platform do not produce a boot image.
- apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
- if apexInfo.IsForPlatform() {
- return bootImageOutputs{}
+// produceBootImageProfileFromSource builds the boot image profile from the source if it is required.
+func (b *BootclasspathFragmentModule) produceBootImageProfileFromSource(ctx android.ModuleContext, contents []android.Module, modules bootDexJarByModule) android.WritablePath {
+ apex := b.getProfileProviderApex(ctx)
+ if apex == "" {
+ return nil
}
- // Build a profile for the image config and then use that to build the boot image.
- profile := bootImageProfileRule(ctx, imageConfig)
-
- // If dexpreopt of boot image jars should be skipped, generate only a profile.
- if SkipDexpreoptBootJars(ctx) {
- return bootImageOutputs{
- profile: profile,
- }
+ dexPaths := make(android.Paths, 0, len(contents))
+ dexLocations := make([]string, 0, len(contents))
+ for _, module := range contents {
+ dexPaths = append(dexPaths, modules[module.Name()])
+ dexLocations = append(dexLocations, filepath.Join("/", "apex", apex, "javalib", module.Name() + ".jar"))
}
- // Build boot image files for the host variants.
- buildBootImageVariantsForBuildOs(ctx, imageConfig, profile)
-
- // Build boot image files for the android variants.
- bootImageFiles := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile)
-
- // Return the boot image files for the android variants for inclusion in an APEX and to be zipped
- // up for the dist.
- return bootImageFiles
+ // Build a profile for the modules in this fragment.
+ return bootImageProfileRuleCommon(ctx, b.Name(), dexPaths, dexLocations)
}
func (b *BootclasspathFragmentModule) AndroidMkEntries() []android.AndroidMkEntries {
@@ -921,10 +809,6 @@ func (b *BootclasspathFragmentModule) AndroidMkEntries() []android.AndroidMkEntr
return entriesList
}
-func (b *BootclasspathFragmentModule) getImageName() *string {
- return b.properties.Image_name
-}
-
func (b *BootclasspathFragmentModule) getProfilePath() android.Path {
return b.profilePath
}
@@ -1194,39 +1078,19 @@ func (module *PrebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx an
return &output
}
-// produceBootImageFiles extracts the boot image files from the APEX if available.
-func (module *PrebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs {
- if !shouldCopyBootFilesToPredefinedLocations(ctx, imageConfig) {
- return bootImageOutputs{}
+// produceBootImageProfile extracts the boot image profile from the APEX if available.
+func (module *PrebuiltBootclasspathFragmentModule) produceBootImageProfile(ctx android.ModuleContext) android.WritablePath {
+ // This module does not provide a boot image profile.
+ if module.getProfileProviderApex(ctx) == "" {
+ return nil
}
di := android.FindDeapexerProviderForModule(ctx)
if di == nil {
- return bootImageOutputs{} // An error has been reported by FindDeapexerProviderForModule.
+ return nil // An error has been reported by FindDeapexerProviderForModule.
}
- profile := (android.WritablePath)(nil)
- if imageConfig.profileInstallPathInApex != "" {
- profile = di.PrebuiltExportPath(imageConfig.profileInstallPathInApex)
- }
-
- // Build the boot image files for the host variants. These are always built from the dex files
- // provided by the contents of this module as prebuilt versions of the host boot image files are
- // not available, i.e. there is no host specific prebuilt apex containing them. This has to be
- // built without a profile as the prebuilt modules do not provide a profile.
- buildBootImageVariantsForBuildOs(ctx, imageConfig, profile)
-
- if profile == nil && imageConfig.isProfileGuided() {
- ctx.ModuleErrorf("Unable to produce boot image files: profiles not found in the prebuilt apex")
- return bootImageOutputs{}
- }
- // Build boot image files for the android variants from the dex files provided by the contents
- // of this module.
- return buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile)
-}
-
-func (b *PrebuiltBootclasspathFragmentModule) getImageName() *string {
- return b.properties.Image_name
+ return di.PrebuiltExportPath(profileInstallPathInApex)
}
func (b *PrebuiltBootclasspathFragmentModule) getProfilePath() android.Path {
@@ -1241,14 +1105,10 @@ var _ commonBootclasspathFragment = (*PrebuiltBootclasspathFragmentModule)(nil)
// If there is no image config associated with this fragment then it returns nil. Otherwise, it
// returns the files that are listed in the image config.
func (module *PrebuiltBootclasspathFragmentModule) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) []string {
- imageConfig := module.getImageConfig(ctx)
- if imageConfig != nil {
- files := []string{}
- if imageConfig.profileInstallPathInApex != "" {
- // Add the boot image profile.
- files = append(files, imageConfig.profileInstallPathInApex)
+ for _, apex := range module.ApexProperties.Apex_available {
+ if isProfileProviderApex(ctx, apex) {
+ return []string{profileInstallPathInApex}
}
- return files
}
return nil
}
@@ -1264,9 +1124,5 @@ func prebuiltBootclasspathFragmentFactory() android.Module {
android.InitApexModule(m)
android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibCommon)
- // Initialize the contents property from the image_name.
- android.AddLoadHook(m, func(ctx android.LoadHookContext) {
- bootclasspathFragmentInitContentsFromImage(ctx, &m.BootclasspathFragmentModule)
- })
return m
}
diff --git a/java/bootclasspath_fragment_test.go b/java/bootclasspath_fragment_test.go
index 2541f14ff..888caad16 100644
--- a/java/bootclasspath_fragment_test.go
+++ b/java/bootclasspath_fragment_test.go
@@ -40,6 +40,12 @@ func TestBootclasspathFragment_UnknownImageName(t *testing.T) {
image_name: "unknown",
contents: ["foo"],
}
+
+ java_library {
+ name: "foo",
+ srcs: ["foo.java"],
+ installable: true,
+ }
`)
}
@@ -53,6 +59,11 @@ func TestPrebuiltBootclasspathFragment_UnknownImageName(t *testing.T) {
image_name: "unknown",
contents: ["foo"],
}
+
+ java_import {
+ name: "foo",
+ jars: ["foo.jar"],
+ }
`)
}
@@ -72,6 +83,18 @@ func TestBootclasspathFragmentInconsistentArtConfiguration_Platform(t *testing.T
"apex",
],
}
+
+ java_library {
+ name: "foo",
+ srcs: ["foo.java"],
+ installable: true,
+ }
+
+ java_library {
+ name: "bar",
+ srcs: ["bar.java"],
+ installable: true,
+ }
`)
}
@@ -92,6 +115,18 @@ func TestBootclasspathFragmentInconsistentArtConfiguration_ApexMixture(t *testin
"apex2",
],
}
+
+ java_library {
+ name: "foo",
+ srcs: ["foo.java"],
+ installable: true,
+ }
+
+ java_library {
+ name: "bar",
+ srcs: ["bar.java"],
+ installable: true,
+ }
`)
}
diff --git a/java/builder.go b/java/builder.go
index 462626712..debf49a00 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -42,7 +42,8 @@ var (
// TODO(b/143658984): goma can't handle the --system argument to javac.
javac, javacRE = pctx.MultiCommandRemoteStaticRules("javac",
blueprint.RuleParams{
- Command: `rm -rf "$outDir" "$annoDir" "$srcJarDir" "$out" && mkdir -p "$outDir" "$annoDir" "$srcJarDir" && ` +
+ Command: `rm -rf "$outDir" "$annoDir" "$annoSrcJar.tmp" "$srcJarDir" "$out.tmp" && ` +
+ `mkdir -p "$outDir" "$annoDir" "$srcJarDir" && ` +
`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
`(if [ -s $srcJarDir/list ] || [ -s $out.rsp ] ; then ` +
`${config.SoongJavacWrapper} $javaTemplate${config.JavacCmd} ` +
@@ -50,14 +51,18 @@ var (
`$processorpath $processor $javacFlags $bootClasspath $classpath ` +
`-source $javaVersion -target $javaVersion ` +
`-d $outDir -s $annoDir @$out.rsp @$srcJarDir/list ; fi ) && ` +
- `$zipTemplate${config.SoongZipCmd} -jar -o $out -C $outDir -D $outDir && ` +
- `rm -rf "$srcJarDir"`,
+ `$annoSrcJarTemplate${config.SoongZipCmd} -jar -o $annoSrcJar.tmp -C $annoDir -D $annoDir && ` +
+ `$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 && ` +
+ `rm -rf "$srcJarDir" "$outDir"`,
CommandDeps: []string{
"${config.JavacCmd}",
"${config.SoongZipCmd}",
"${config.ZipSyncCmd}",
},
CommandOrderOnly: []string{"${config.SoongJavacWrapper}"},
+ Restat: true,
Rspfile: "$out.rsp",
RspfileContent: "$in",
}, map[string]*remoteexec.REParams{
@@ -69,12 +74,19 @@ var (
"$zipTemplate": &remoteexec.REParams{
Labels: map[string]string{"type": "tool", "name": "soong_zip"},
Inputs: []string{"${config.SoongZipCmd}", "$outDir"},
- OutputFiles: []string{"$out"},
+ OutputFiles: []string{"$out.tmp"},
+ ExecStrategy: "${config.REJavacExecStrategy}",
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ },
+ "$annoSrcJarTemplate": &remoteexec.REParams{
+ Labels: map[string]string{"type": "tool", "name": "soong_zip"},
+ Inputs: []string{"${config.SoongZipCmd}", "$annoDir"},
+ OutputFiles: []string{"$annoSrcJar.tmp"},
ExecStrategy: "${config.REJavacExecStrategy}",
Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
},
}, []string{"javacFlags", "bootClasspath", "classpath", "processorpath", "processor", "srcJars", "srcJarDir",
- "outDir", "annoDir", "javaVersion"}, nil)
+ "outDir", "annoDir", "annoSrcJar", "javaVersion"}, nil)
_ = pctx.VariableFunc("kytheCorpus",
func(ctx android.PackageVarContext) string { return ctx.Config().XrefCorpusName() })
@@ -246,6 +258,25 @@ var (
CommandDeps: []string{"${config.ZipAlign}"},
},
)
+
+ checkZipAlignment = pctx.AndroidStaticRule("checkzipalign",
+ blueprint.RuleParams{
+ Command: "if ! ${config.ZipAlign} -c -p 4 $in > /dev/null; then " +
+ "echo $in: Improper package alignment >&2; " +
+ "exit 1; " +
+ "else " +
+ "touch $out; " +
+ "fi",
+ CommandDeps: []string{"${config.ZipAlign}"},
+ Description: "Check zip alignment",
+ },
+ )
+
+ convertImplementationJarToHeaderJarRule = pctx.AndroidStaticRule("convertImplementationJarToHeaderJar",
+ blueprint.RuleParams{
+ Command: `${config.Zip2ZipCmd} -i ${in} -o ${out} -x 'META-INF/services/**/*'`,
+ CommandDeps: []string{"${config.Zip2ZipCmd}"},
+ })
)
func init() {
@@ -292,8 +323,14 @@ type javaBuilderFlags struct {
proto android.ProtoFlags
}
+func DefaultJavaBuilderFlags() javaBuilderFlags {
+ return javaBuilderFlags{
+ javaVersion: JAVA_VERSION_8,
+ }
+}
+
func TransformJavaToClasses(ctx android.ModuleContext, outputFile android.WritablePath, shardIdx int,
- srcFiles, srcJars android.Paths, flags javaBuilderFlags, deps android.Paths) {
+ srcFiles, srcJars android.Paths, annoSrcJar android.WritablePath, flags javaBuilderFlags, deps android.Paths) {
// Compile java sources into .class files
desc := "javac"
@@ -301,7 +338,7 @@ func TransformJavaToClasses(ctx android.ModuleContext, outputFile android.Writab
desc += strconv.Itoa(shardIdx)
}
- transformJavaToClasses(ctx, outputFile, shardIdx, srcFiles, srcJars, flags, deps, "javac", desc)
+ transformJavaToClasses(ctx, outputFile, shardIdx, srcFiles, srcJars, annoSrcJar, flags, deps, "javac", desc)
}
// Emits the rule to generate Xref input file (.kzip file) for the given set of source files and source jars
@@ -475,7 +512,7 @@ func TurbineApt(ctx android.ModuleContext, outputSrcJar, outputResJar android.Wr
// suffix will be appended to various intermediate files and directories to avoid collisions when
// this function is called twice in the same module directory.
func transformJavaToClasses(ctx android.ModuleContext, outputFile android.WritablePath,
- shardIdx int, srcFiles, srcJars android.Paths,
+ shardIdx int, srcFiles, srcJars android.Paths, annoSrcJar android.WritablePath,
flags javaBuilderFlags, deps android.Paths,
intermediatesDir, desc string) {
@@ -522,11 +559,12 @@ func transformJavaToClasses(ctx android.ModuleContext, outputFile android.Writab
rule = javacRE
}
ctx.Build(pctx, android.BuildParams{
- Rule: rule,
- Description: desc,
- Output: outputFile,
- Inputs: srcFiles,
- Implicits: deps,
+ Rule: rule,
+ Description: desc,
+ Output: outputFile,
+ ImplicitOutput: annoSrcJar,
+ Inputs: srcFiles,
+ Implicits: deps,
Args: map[string]string{
"javacFlags": flags.javacFlags,
"bootClasspath": bootClasspath,
@@ -537,6 +575,7 @@ func transformJavaToClasses(ctx android.ModuleContext, outputFile android.Writab
"srcJarDir": android.PathForModuleOut(ctx, intermediatesDir, srcJarDir).String(),
"outDir": android.PathForModuleOut(ctx, intermediatesDir, outDir).String(),
"annoDir": android.PathForModuleOut(ctx, intermediatesDir, annoDir).String(),
+ "annoSrcJar": annoSrcJar.String(),
"javaVersion": flags.javaVersion.String(),
},
})
@@ -600,6 +639,15 @@ func TransformJarsToJar(ctx android.ModuleContext, outputFile android.WritablePa
})
}
+func convertImplementationJarToHeaderJar(ctx android.ModuleContext, implementationJarFile android.Path,
+ headerJarFile android.WritablePath) {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: convertImplementationJarToHeaderJarRule,
+ Input: implementationJarFile,
+ Output: headerJarFile,
+ })
+}
+
func TransformJarJar(ctx android.ModuleContext, outputFile android.WritablePath,
classesJar android.Path, rulesFile android.Path) {
ctx.Build(pctx, android.BuildParams{
diff --git a/java/config/config.go b/java/config/config.go
index b82a137e7..83c27d309 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -98,7 +98,7 @@ func init() {
"-JDcom.android.tools.r8.emitRecordAnnotationsExInDex",
}, dexerJavaVmFlagsList...))
exportedVars.ExportStringListStaticVariable("R8Flags", append([]string{
- "-JXmx2048M",
+ "-JXmx4096M",
"-JDcom.android.tools.r8.emitRecordAnnotationsInDex",
"-JDcom.android.tools.r8.emitPermittedSubclassesAnnotationsInDex",
"-JDcom.android.tools.r8.emitRecordAnnotationsExInDex",
@@ -148,6 +148,8 @@ func init() {
pctx.SourcePathVariable("JavaKytheExtractorJar", "prebuilts/build-tools/common/framework/javac_extractor.jar")
pctx.SourcePathVariable("Ziptime", "prebuilts/build-tools/${hostPrebuiltTag}/bin/ziptime")
+ pctx.SourcePathVariable("ResourceProcessorBusyBox", "prebuilts/bazel/common/android_tools/android_tools/all_android_tools_deploy.jar")
+
pctx.HostBinToolVariable("GenKotlinBuildFileCmd", "gen-kotlin-build-file")
pctx.SourcePathVariable("JarArgsCmd", "build/soong/scripts/jar-args.sh")
diff --git a/java/config/makevars.go b/java/config/makevars.go
index 273aca0b4..4e0919537 100644
--- a/java/config/makevars.go
+++ b/java/config/makevars.go
@@ -28,7 +28,8 @@ func makeVarsProvider(ctx android.MakeVarsContext) {
ctx.Strict("FRAMEWORK_LIBRARIES", strings.Join(FrameworkLibraries, " "))
// These are used by make when LOCAL_PRIVATE_PLATFORM_APIS is set (equivalent to platform_apis in blueprint):
- ctx.Strict("LEGACY_CORE_PLATFORM_BOOTCLASSPATH_LIBRARIES", strings.Join(LegacyCorePlatformBootclasspathLibraries, " "))
+ ctx.Strict("LEGACY_CORE_PLATFORM_BOOTCLASSPATH_LIBRARIES",
+ strings.Join(LegacyCorePlatformBootclasspathLibraries, " "))
ctx.Strict("LEGACY_CORE_PLATFORM_SYSTEM_MODULES", LegacyCorePlatformSystemModules)
ctx.Strict("ANDROID_JAVA_HOME", "${JavaHome}")
diff --git a/java/core-libraries/Android.bp b/java/core-libraries/Android.bp
index 958f4cead..de9a82d09 100644
--- a/java/core-libraries/Android.bp
+++ b/java/core-libraries/Android.bp
@@ -33,19 +33,45 @@ dist_targets = [
"win_sdk",
]
-java_library {
- name: "core.current.stubs",
+java_defaults {
+ name: "core.current.stubs.defaults",
visibility: ["//visibility:public"],
+ sdk_version: "none",
+ system_modules: "none",
+ dist: {
+ targets: dist_targets,
+ },
+}
+
+java_library {
+ name: "core.current.stubs.from-source",
+ defaults: [
+ "core.current.stubs.defaults",
+ ],
static_libs: [
"art.module.public.api.stubs",
"conscrypt.module.public.api.stubs",
"i18n.module.public.api.stubs",
],
- sdk_version: "none",
- system_modules: "none",
+}
- dist: {
- targets: dist_targets,
+java_library {
+ name: "core.current.stubs",
+ defaults: [
+ "core.current.stubs.defaults",
+ ],
+ static_libs: [
+ "core.current.stubs.from-source",
+ ],
+ product_variables: {
+ build_from_text_stub: {
+ static_libs: [
+ "core.current.stubs.from-text",
+ ],
+ exclude_static_libs: [
+ "core.current.stubs.from-source",
+ ],
+ },
},
}
@@ -120,12 +146,43 @@ java_system_modules {
],
}
+java_defaults {
+ name: "core.module_lib.stubs.defaults",
+ visibility: ["//visibility:private"],
+ sdk_version: "none",
+ system_modules: "none",
+}
+
+
// A stubs target containing the parts of the public SDK & @SystemApi(MODULE_LIBRARIES) API
// provided by the core libraries.
//
// Don't use this directly, use "sdk_version: module_current".
java_library {
name: "core.module_lib.stubs",
+ defaults: [
+ "core.module_lib.stubs.defaults",
+ ],
+ static_libs: [
+ "core.module_lib.stubs.from-source",
+ ],
+ product_variables: {
+ build_from_text_stub: {
+ static_libs: [
+ "core.module_lib.stubs.from-text",
+ ],
+ exclude_static_libs: [
+ "core.module_lib.stubs.from-source",
+ ],
+ },
+ },
+}
+
+java_library {
+ name: "core.module_lib.stubs.from-source",
+ defaults: [
+ "core.module_lib.stubs.defaults",
+ ],
static_libs: [
"art.module.public.api.stubs.module_lib",
@@ -135,9 +192,6 @@ java_library {
"conscrypt.module.public.api.stubs",
"i18n.module.public.api.stubs",
],
- sdk_version: "none",
- system_modules: "none",
- visibility: ["//visibility:private"],
}
// Produces a dist file that is used by the
@@ -199,18 +253,46 @@ core_platform_visibility = ["//visibility:public"]
// API annotations are available to the dex tools that enable enforcement of runtime
// accessibility. b/119068555
java_library {
+ name: "legacy.core.platform.api.stubs.from-source",
+ visibility: core_platform_visibility,
+ defaults: [
+ "core.platform.api.stubs.defaults",
+ ],
+ static_libs: [
+ "art.module.public.api.stubs.module_lib",
+ "conscrypt.module.platform.api.stubs",
+ "legacy.i18n.module.platform.api.stubs",
+ ],
+}
+
+java_library {
name: "legacy.core.platform.api.stubs",
visibility: core_platform_visibility,
+ defaults: [
+ "core.platform.api.stubs.defaults",
+ ],
+ static_libs: [
+ "legacy.core.platform.api.stubs.from-source",
+ ],
+ product_variables: {
+ build_from_text_stub: {
+ static_libs: [
+ "legacy.core.platform.api.stubs.from-text",
+ ],
+ exclude_static_libs: [
+ "legacy.core.platform.api.stubs.from-source",
+ ],
+ },
+ },
+}
+
+java_defaults {
+ name: "core.platform.api.stubs.defaults",
hostdex: true,
compile_dex: true,
sdk_version: "none",
system_modules: "none",
- static_libs: [
- "art.module.public.api.stubs.module_lib",
- "conscrypt.module.platform.api.stubs",
- "legacy.i18n.module.platform.api.stubs",
- ],
patch_module: "java.base",
}
@@ -233,20 +315,38 @@ java_library {
}
java_library {
- name: "stable.core.platform.api.stubs",
+ name: "stable.core.platform.api.stubs.from-source",
visibility: core_platform_visibility,
- hostdex: true,
- compile_dex: true,
-
- sdk_version: "none",
- system_modules: "none",
+ defaults: [
+ "core.platform.api.stubs.defaults",
+ ],
static_libs: [
"art.module.public.api.stubs.module_lib",
// conscrypt only has a stable version, so it is okay to depend on it here:
"conscrypt.module.platform.api.stubs",
"stable.i18n.module.platform.api.stubs",
],
- patch_module: "java.base",
+}
+
+java_library {
+ name: "stable.core.platform.api.stubs",
+ visibility: core_platform_visibility,
+ defaults: [
+ "core.platform.api.stubs.defaults",
+ ],
+ static_libs: [
+ "stable.core.platform.api.stubs.from-source",
+ ],
+ product_variables: {
+ build_from_text_stub: {
+ static_libs: [
+ "stable.core.platform.api.stubs.from-text",
+ ],
+ exclude_static_libs: [
+ "stable.core.platform.api.stubs.from-source",
+ ],
+ },
+ },
}
// Same as stable.core.platform.api.stubs, but android annotations are
diff --git a/java/core-libraries/TxtStubLibraries.bp b/java/core-libraries/TxtStubLibraries.bp
index 813187e54..c46f8b8ea 100644
--- a/java/core-libraries/TxtStubLibraries.bp
+++ b/java/core-libraries/TxtStubLibraries.bp
@@ -22,8 +22,6 @@ java_system_modules {
libs: [
"core-current-stubs-for-system-modules-no-annotations.from-text",
],
- // TODO: Enable after stub generation from .txt file is available
- enabled: false,
}
java_library {
@@ -36,8 +34,6 @@ java_library {
"core.current.stubs.from-text",
"core-lambda-stubs.from-text",
],
- // TODO: Enable after stub generation from .txt file is available
- enabled: false,
}
// Same as core-module-lib-stubs-system-modules, but the stubs are generated from .txt files
@@ -47,8 +43,6 @@ java_system_modules {
libs: [
"core-module-lib-stubs-for-system-modules-no-annotations.from-text",
],
- // TODO: Enable after stub generation from .txt file is available
- enabled: false,
}
java_library {
@@ -61,26 +55,26 @@ java_library {
"core.module_lib.stubs.from-text",
"core-lambda-stubs.from-text",
],
- // TODO: Enable after stub generation from .txt file is available
- enabled: false,
}
-java_library {
+java_api_library {
name: "core.module_lib.stubs.from-text",
- static_libs: [
- "art.module.public.api.stubs.module_lib.from-text",
+ api_surface: "module-lib",
+ api_contributions: [
+ "art.module.public.api.stubs.source.api.contribution",
+ "art.module.public.api.stubs.source.system.api.contribution",
+ "art.module.public.api.stubs.source.module_lib.api.contribution",
- // Replace the following with the module-lib correspondence when Conscrypt or i18N module
+ // Add the module-lib correspondence when Conscrypt or i18N module
// provides @SystemApi(MODULE_LIBRARIES). Currently, assume that only ART module provides
// @SystemApi(MODULE_LIBRARIES).
- "conscrypt.module.public.api.stubs.from-text",
- "i18n.module.public.api.stubs.from-text",
+ "conscrypt.module.public.api.stubs.source.api.contribution",
+ "i18n.module.public.api.stubs.source.api.contribution",
+ ],
+ libs: [
+ "stub-annotations",
],
- sdk_version: "none",
- system_modules: "none",
visibility: ["//visibility:private"],
- // TODO: Enable after stub generation from .txt file is available
- enabled: false,
}
// Same as legacy-core-platform-api-stubs-system-modules, but the stubs are generated from .txt files
@@ -91,8 +85,6 @@ java_system_modules {
"legacy.core.platform.api.no.annotations.stubs.from-text",
"core-lambda-stubs.from-text",
],
- // TODO: Enable after stub generation from .txt file is available
- enabled: false,
}
java_library {
@@ -108,8 +100,6 @@ java_library {
"legacy.core.platform.api.stubs.from-text",
],
patch_module: "java.base",
- // TODO: Enable after stub generation from .txt file is available
- enabled: false,
}
// Same as stable-core-platform-api-stubs-system-modules, but the stubs are generated from .txt files
@@ -120,8 +110,6 @@ java_system_modules {
"stable.core.platform.api.no.annotations.stubs.from-text",
"core-lambda-stubs.from-text",
],
- // TODO: Enable after stub generation from .txt file is available
- enabled: false,
}
java_library {
@@ -137,8 +125,6 @@ java_library {
"stable.core.platform.api.stubs.from-text",
],
patch_module: "java.base",
- // TODO: Enable after stub generation from .txt file is available
- enabled: false,
}
java_api_library {
@@ -151,6 +137,4 @@ java_api_library {
// LambdaMetaFactory depends on CallSite etc. which is part of the Core API surface
"core.current.stubs.from-text",
],
- // TODO: Enable after stub generation from .txt file is available
- enabled: false,
}
diff --git a/java/device_host_converter.go b/java/device_host_converter.go
index 3581040f8..5460dc993 100644
--- a/java/device_host_converter.go
+++ b/java/device_host_converter.go
@@ -143,6 +143,8 @@ func (d *DeviceHostConverter) GenerateAndroidBuildActions(ctx android.ModuleCont
ResourceJars: d.resourceJars,
SrcJarArgs: d.srcJarArgs,
SrcJarDeps: d.srcJarDeps,
+ // TODO: Not sure if aconfig flags that have been moved between device and host variants
+ // make sense.
})
}
diff --git a/java/device_host_converter_test.go b/java/device_host_converter_test.go
index 3c9a0f3f1..3413da03d 100644
--- a/java/device_host_converter_test.go
+++ b/java/device_host_converter_test.go
@@ -135,6 +135,7 @@ func TestHostForDevice(t *testing.T) {
hostModule := ctx.ModuleForTests("host_module", config.BuildOSCommonTarget.String())
hostJavac := hostModule.Output("javac/host_module.jar")
+ hostJavacHeader := hostModule.Output("javac-header/host_module.jar")
hostRes := hostModule.Output("res/host_module.jar")
hostImportModule := ctx.ModuleForTests("host_import_module", config.BuildOSCommonTarget.String())
@@ -148,7 +149,7 @@ func TestHostForDevice(t *testing.T) {
// check classpath of device module with dependency on host_for_device_module
expectedClasspath := "-classpath " + strings.Join(android.Paths{
- hostJavac.Output,
+ hostJavacHeader.Output,
hostImportCombined.Output,
}.Strings(), ":")
diff --git a/java/dex.go b/java/dex.go
index 4d6aa3456..7e7da00fd 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -140,7 +140,7 @@ var r8, r8RE = pctx.MultiCommandRemoteStaticRules("r8",
`$r8Template${config.R8Cmd} ${config.R8Flags} -injars $tmpJar --output $outDir ` +
`--no-data-resources ` +
`-printmapping ${outDict} ` +
- `--pg-conf-output ${outConfig} ` +
+ `-printconfiguration ${outConfig} ` +
`-printusage ${outUsage} ` +
`--deps-file ${out}.d ` +
`$r8Flags && ` +
@@ -161,7 +161,7 @@ var r8, r8RE = pctx.MultiCommandRemoteStaticRules("r8",
"$r8Template": &remoteexec.REParams{
Labels: map[string]string{"type": "compile", "compiler": "r8"},
Inputs: []string{"$implicits", "${config.R8Jar}"},
- OutputFiles: []string{"${outUsage}"},
+ OutputFiles: []string{"${outUsage}", "${outConfig}", "${outDict}"},
ExecStrategy: "${config.RER8ExecStrategy}",
ToolchainInputs: []string{"${config.JavaCmd}"},
Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
@@ -399,13 +399,16 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam
args["implicits"] = strings.Join(r8Deps.Strings(), ",")
}
ctx.Build(pctx, android.BuildParams{
- Rule: rule,
- Description: "r8",
- Output: javalibJar,
- ImplicitOutputs: android.WritablePaths{proguardDictionary, proguardUsageZip},
- Input: dexParams.classesJar,
- Implicits: r8Deps,
- Args: args,
+ Rule: rule,
+ Description: "r8",
+ Output: javalibJar,
+ ImplicitOutputs: android.WritablePaths{
+ proguardDictionary,
+ proguardUsageZip,
+ proguardConfiguration},
+ Input: dexParams.classesJar,
+ Implicits: r8Deps,
+ Args: args,
})
} else {
d8Flags, d8Deps := d8Flags(dexParams.flags)
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index a96b31281..998730e08 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -16,6 +16,7 @@ package java
import (
"path/filepath"
+ "sort"
"strings"
"android/soong/android"
@@ -390,7 +391,37 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr
globalSoong := dexpreopt.GetGlobalSoongConfig(ctx)
- dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(ctx, globalSoong, global, dexpreoptConfig)
+ // The root "product_packages.txt" is generated by `build/make/core/Makefile`. It contains a list
+ // of all packages that are installed on the device. We use `grep` to filter the list by the app's
+ // dependencies to create a per-app list, and use `rsync --checksum` to prevent the file's mtime
+ // from being changed if the contents don't change. This avoids unnecessary dexpreopt reruns.
+ productPackages := android.PathForModuleInPartitionInstall(ctx, "", "product_packages.txt")
+ appProductPackages := android.PathForModuleOut(ctx, "dexpreopt", "product_packages.txt")
+ appProductPackagesStaging := appProductPackages.ReplaceExtension(ctx, "txt.tmp")
+ clcNames, _ := dexpreopt.ComputeClassLoaderContextDependencies(dexpreoptConfig.ClassLoaderContexts)
+ sort.Strings(clcNames) // The order needs to be deterministic.
+ productPackagesRule := android.NewRuleBuilder(pctx, ctx)
+ if len(clcNames) > 0 {
+ productPackagesRule.Command().
+ Text("grep -F -x").
+ FlagForEachArg("-e ", clcNames).
+ Input(productPackages).
+ FlagWithOutput("> ", appProductPackagesStaging).
+ Text("|| true")
+ } else {
+ productPackagesRule.Command().
+ Text("rm -f").Output(appProductPackagesStaging).
+ Text("&&").
+ Text("touch").Output(appProductPackagesStaging)
+ }
+ productPackagesRule.Command().
+ Text("rsync --checksum").
+ Input(appProductPackagesStaging).
+ Output(appProductPackages)
+ productPackagesRule.Restat().Build("product_packages", "dexpreopt product_packages")
+
+ dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(
+ ctx, globalSoong, global, dexpreoptConfig, appProductPackages)
if err != nil {
ctx.ModuleErrorf("error generating dexpreopt rule: %s", err.Error())
return
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index f477f404e..003f2de22 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -16,7 +16,6 @@ package java
import (
"path/filepath"
- "sort"
"strings"
"android/soong/android"
@@ -224,6 +223,11 @@ var artApexNames = []string{
"com.google.android.art.testing",
}
+var (
+ dexpreoptBootJarDepTag = bootclasspathDependencyTag{name: "dexpreopt-boot-jar"}
+ dexBootJarsFragmentsKey = android.NewOnceKey("dexBootJarsFragments")
+)
+
func init() {
RegisterDexpreoptBootJarsComponents(android.InitRegistrationContext)
}
@@ -241,6 +245,9 @@ type bootImageConfig struct {
// Image name (used in directory names and ninja rule names).
name string
+ // If the module with the given name exists, this config is enabled.
+ enabledIfExists string
+
// Basename of the image: the resulting filenames are <stem>[-<jar>].{art,oat,vdex}.
stem string
@@ -257,10 +264,6 @@ type bootImageConfig struct {
// the location is relative to "/".
installDir string
- // Install path of the boot image profile if it needs to be installed in the APEX, or empty if not
- // needed.
- profileInstallPathInApex string
-
// A list of (location, jar) pairs for the Java modules in this image.
modules android.ConfiguredJarList
@@ -296,10 +299,9 @@ type bootImageConfig struct {
// The "--single-image" argument.
singleImage bool
- // Profiles imported from other boot image configs. Each element must represent a
- // `bootclasspath_fragment` of an APEX (i.e., the `name` field of each element must refer to the
- // `image_name` property of a `bootclasspath_fragment`).
- profileImports []*bootImageConfig
+ // 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
}
// Target-dependent description of a boot image.
@@ -384,7 +386,7 @@ func (image bootImageConfig) moduleName(ctx android.PathContext, idx int) string
m := image.modules.Jar(idx)
name := image.stem
if idx != 0 || image.extends != nil {
- name += "-" + android.ModuleStem(m)
+ name += "-" + android.ModuleStem(ctx.Config(), image.modules.Apex(idx), m)
}
return name
}
@@ -458,18 +460,26 @@ func (image *bootImageConfig) isProfileGuided() bool {
return image.compilerFilter == "speed-profile"
}
+func (image *bootImageConfig) isEnabled(ctx android.BaseModuleContext) bool {
+ return ctx.OtherModuleExists(image.enabledIfExists)
+}
+
func dexpreoptBootJarsFactory() android.SingletonModule {
m := &dexpreoptBootJars{}
- android.InitAndroidModule(m)
+ android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
return m
}
func RegisterDexpreoptBootJarsComponents(ctx android.RegistrationContext) {
- ctx.RegisterSingletonModuleType("dex_bootjars", dexpreoptBootJarsFactory)
+ ctx.RegisterParallelSingletonModuleType("dex_bootjars", dexpreoptBootJarsFactory)
+ ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
+ ctx.BottomUp("dex_bootjars_deps", DexpreoptBootJarsMutator).Parallel()
+ })
}
func SkipDexpreoptBootJars(ctx android.PathContext) bool {
- return dexpreopt.GetGlobalConfig(ctx).DisablePreoptBootImages
+ global := dexpreopt.GetGlobalConfig(ctx)
+ return global.DisablePreoptBootImages || !shouldBuildBootImages(ctx.Config(), global)
}
// Singleton module for generating boot image build rules.
@@ -492,39 +502,90 @@ type dexpreoptBootJars struct {
dexpreoptConfigForMake android.WritablePath
}
-// Provide paths to boot images for use by modules that depend upon them.
-//
-// The build rules are created in GenerateSingletonBuildActions().
-func (d *dexpreoptBootJars) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- // Placeholder for now.
-}
-
-// Generate build rules for boot images.
-func (d *dexpreoptBootJars) GenerateSingletonBuildActions(ctx android.SingletonContext) {
- if dexpreopt.GetCachedGlobalSoongConfig(ctx) == nil {
- // No module has enabled dexpreopting, so we assume there will be no boot image to make.
+func DexpreoptBootJarsMutator(ctx android.BottomUpMutatorContext) {
+ if _, ok := ctx.Module().(*dexpreoptBootJars); !ok {
return
}
- archType := ctx.Config().Targets[android.Android][0].Arch.ArchType
- d.dexpreoptConfigForMake = android.PathForOutput(ctx, toDexpreoptDirName(archType), "dexpreopt.config")
- writeGlobalConfigForMake(ctx, d.dexpreoptConfigForMake)
- global := dexpreopt.GetGlobalConfig(ctx)
- if !shouldBuildBootImages(ctx.Config(), global) {
- 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)
}
- defaultImageConfig := defaultBootImageConfig(ctx)
- d.defaultBootImage = defaultImageConfig
imageConfigs := genBootImageConfigs(ctx)
- d.otherImages = make([]*bootImageConfig, 0, len(imageConfigs)-1)
for _, config := range imageConfigs {
- if config != defaultImageConfig {
+ if !config.isEnabled(ctx) {
+ continue
+ }
+ // For accessing the boot jars.
+ addDependenciesOntoBootImageModules(ctx, config.modules, dexpreoptBootJarDepTag)
+ }
+
+ if ctx.OtherModuleExists("platform-bootclasspath") {
+ // For accessing all bootclasspath fragments.
+ addDependencyOntoApexModulePair(ctx, "platform", "platform-bootclasspath", platformBootclasspathDepTag)
+ } 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)
+ }
+}
+
+func gatherBootclasspathFragments(ctx android.ModuleContext) map[string]android.Module {
+ return ctx.Config().Once(dexBootJarsFragmentsKey, func() interface{} {
+ fragments := make(map[string]android.Module)
+ ctx.WalkDeps(func(child, parent android.Module) bool {
+ if !isActiveModule(child) {
+ return false
+ }
+ tag := ctx.OtherModuleDependencyTag(child)
+ if tag == platformBootclasspathDepTag {
+ return true
+ }
+ if tag == bootclasspathFragmentDepTag {
+ apexInfo := ctx.OtherModuleProvider(child, android.ApexInfoProvider).(android.ApexInfo)
+ for _, apex := range apexInfo.InApexVariants {
+ fragments[apex] = child
+ }
+ return false
+ }
+ return false
+ })
+ return fragments
+ }).(map[string]android.Module)
+}
+
+func getBootclasspathFragmentByApex(ctx android.ModuleContext, apexName string) android.Module {
+ return gatherBootclasspathFragments(ctx)[apexName]
+}
+
+// GenerateAndroidBuildActions generates the build rules for boot images.
+func (d *dexpreoptBootJars) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ imageConfigs := genBootImageConfigs(ctx)
+ d.defaultBootImage = defaultBootImageConfig(ctx)
+ d.otherImages = make([]*bootImageConfig, 0, len(imageConfigs)-1)
+ for _, name := range getImageNames() {
+ config := imageConfigs[name]
+ if config != d.defaultBootImage {
d.otherImages = append(d.otherImages, config)
}
+ if !config.isEnabled(ctx) {
+ continue
+ }
+ generateBootImage(ctx, config)
+ if config == d.defaultBootImage {
+ bootFrameworkProfileRule(ctx, config)
+ }
}
}
+// GenerateSingletonBuildActions generates build rules for the dexpreopt config for Make.
+func (d *dexpreoptBootJars) GenerateSingletonBuildActions(ctx android.SingletonContext) {
+ d.dexpreoptConfigForMake = android.PathForOutput(ctx, getDexpreoptDirName(ctx), "dexpreopt.config")
+ writeGlobalConfigForMake(ctx, d.dexpreoptConfigForMake)
+}
+
// shouldBuildBootImages determines whether boot images should be built.
func shouldBuildBootImages(config android.Config, global *dexpreopt.GlobalConfig) bool {
// Skip recompiling the boot image for the second sanitization phase. We'll get separate paths
@@ -537,6 +598,101 @@ func shouldBuildBootImages(config android.Config, global *dexpreopt.GlobalConfig
return true
}
+func generateBootImage(ctx android.ModuleContext, imageConfig *bootImageConfig) {
+ apexJarModulePairs := getModulesForImage(ctx, imageConfig)
+
+ // Copy module dex jars to their predefined locations.
+ bootDexJarsByModule := extractEncodedDexJarsFromModulesOrBootclasspathFragments(ctx, apexJarModulePairs)
+ copyBootJarsToPredefinedLocations(ctx, bootDexJarsByModule, imageConfig.dexPathsByModule)
+
+ // Build a profile for the image config from the profile at the default path. The profile will
+ // then be used along with profiles imported from APEXes to build the boot image.
+ profile := bootImageProfileRule(ctx, imageConfig)
+
+ // If dexpreopt of boot image jars should be skipped, stop after generating a profile.
+ if SkipDexpreoptBootJars(ctx) {
+ return
+ }
+
+ // Build boot image files for the android variants.
+ androidBootImageFiles := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile)
+
+ // Zip the android variant boot image files up.
+ buildBootImageZipInPredefinedLocation(ctx, imageConfig, androidBootImageFiles.byArch)
+
+ // Build boot image files for the host variants. There are use directly by ART host side tests.
+ buildBootImageVariantsForBuildOs(ctx, imageConfig, profile)
+
+ // Create a `dump-oat-<image-name>` rule that runs `oatdump` for debugging purposes.
+ dumpOatRules(ctx, imageConfig)
+}
+
+type apexJarModulePair struct {
+ apex string
+ jarModule android.Module
+}
+
+func getModulesForImage(ctx android.ModuleContext, imageConfig *bootImageConfig) []apexJarModulePair {
+ modules := make([]apexJarModulePair, 0, imageConfig.modules.Len())
+ for i := 0; i < imageConfig.modules.Len(); i++ {
+ found := false
+ for _, module := range gatherApexModulePairDepsWithTag(ctx, dexpreoptBootJarDepTag) {
+ name := android.RemoveOptionalPrebuiltPrefix(module.Name())
+ if name == imageConfig.modules.Jar(i) {
+ modules = append(modules, apexJarModulePair{
+ apex: imageConfig.modules.Apex(i),
+ jarModule: module,
+ })
+ found = true
+ break
+ }
+ }
+ if !found && !ctx.Config().AllowMissingDependencies() {
+ ctx.ModuleErrorf(
+ "Boot image '%s' module '%s' not added as a dependency of dex_bootjars",
+ imageConfig.name,
+ imageConfig.modules.Jar(i))
+ return []apexJarModulePair{}
+ }
+ }
+ return modules
+}
+
+// extractEncodedDexJarsFromModulesOrBootclasspathFragments gets the hidden API encoded dex jars for
+// the given modules.
+func extractEncodedDexJarsFromModulesOrBootclasspathFragments(ctx android.ModuleContext, apexJarModulePairs []apexJarModulePair) bootDexJarByModule {
+ encodedDexJarsByModuleName := bootDexJarByModule{}
+ for _, pair := range apexJarModulePairs {
+ var path android.Path
+ if android.IsConfiguredJarForPlatform(pair.apex) || android.IsModulePrebuilt(pair.jarModule) {
+ // This gives us the dex jar with the hidden API flags encoded from the monolithic hidden API
+ // files or the dex jar extracted from a prebuilt APEX. We can't use this for a boot jar for
+ // a source APEX because there is no guarantee that it is the same as the jar packed into the
+ // APEX. In practice, they are the same when we are building from a full source tree, but they
+ // are different when we are building from a thin manifest (e.g., master-art), where there is
+ // no monolithic hidden API files at all.
+ path = retrieveEncodedBootDexJarFromModule(ctx, pair.jarModule)
+ } else {
+ // Use exactly the same jar that is packed into the APEX.
+ fragment := getBootclasspathFragmentByApex(ctx, pair.apex)
+ if fragment == nil {
+ ctx.ModuleErrorf("Boot jar '%[1]s' is from APEX '%[2]s', but a bootclasspath_fragment for "+
+ "APEX '%[2]s' doesn't exist or is not added as a dependency of dex_bootjars",
+ pair.jarModule.Name(),
+ pair.apex)
+ }
+ bootclasspathFragmentInfo := ctx.OtherModuleProvider(fragment, BootclasspathFragmentApexContentInfoProvider).(BootclasspathFragmentApexContentInfo)
+ jar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(pair.jarModule)
+ if err != nil {
+ ctx.ModuleErrorf("%s", err)
+ }
+ path = jar
+ }
+ encodedDexJarsByModuleName.addPath(pair.jarModule, path)
+ }
+ return encodedDexJarsByModuleName
+}
+
// copyBootJarsToPredefinedLocations generates commands that will copy boot jars to predefined
// paths in the global config.
func copyBootJarsToPredefinedLocations(ctx android.ModuleContext, srcBootDexJarsByModule bootDexJarByModule, dstBootJarsByModule map[string]android.WritablePath) {
@@ -687,10 +843,12 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p
rule.Command().Text("rm").Flag("-f").
Flag(symbolsDir.Join(ctx, "*.art").String()).
Flag(symbolsDir.Join(ctx, "*.oat").String()).
+ Flag(symbolsDir.Join(ctx, "*.vdex").String()).
Flag(symbolsDir.Join(ctx, "*.invocation").String())
rule.Command().Text("rm").Flag("-f").
Flag(outputDir.Join(ctx, "*.art").String()).
Flag(outputDir.Join(ctx, "*.oat").String()).
+ Flag(outputDir.Join(ctx, "*.vdex").String()).
Flag(outputDir.Join(ctx, "*.invocation").String())
cmd := rule.Command()
@@ -712,36 +870,31 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p
Flag("--runtime-arg").FlagWithArg("-Xms", global.Dex2oatImageXms).
Flag("--runtime-arg").FlagWithArg("-Xmx", global.Dex2oatImageXmx)
- if profile != nil {
- cmd.FlagWithInput("--profile-file=", profile)
- }
-
- fragments := make(map[string]commonBootclasspathFragment)
- ctx.VisitDirectDepsWithTag(bootclasspathFragmentDepTag, func(child android.Module) {
- fragment := child.(commonBootclasspathFragment)
- if fragment.getImageName() != nil && android.IsModulePreferred(child) {
- fragments[*fragment.getImageName()] = fragment
+ if image.isProfileGuided() && !global.DisableGenerateProfile {
+ if profile != nil {
+ cmd.FlagWithInput("--profile-file=", profile)
}
- })
- for _, profileImport := range image.profileImports {
- fragment := fragments[profileImport.name]
- if fragment == nil {
- ctx.ModuleErrorf("Boot image config '%[1]s' imports profile from '%[2]s', but a "+
- "bootclasspath_fragment with image name '%[2]s' doesn't exist or is not added as a "+
- "dependency of '%[1]s'",
- image.name,
- profileImport.name)
- return bootImageVariantOutputs{}
- }
- if fragment.getProfilePath() == nil {
- ctx.ModuleErrorf("Boot image config '%[1]s' imports profile from '%[2]s', but '%[2]s' "+
- "doesn't provide a profile",
- image.name,
- profileImport.name)
- return bootImageVariantOutputs{}
+ for _, apex := range image.profileImports {
+ fragment := getBootclasspathFragmentByApex(ctx, apex)
+ if fragment == nil {
+ ctx.ModuleErrorf("Boot image config '%[1]s' imports profile from '%[2]s', but a "+
+ "bootclasspath_fragment for APEX '%[2]s' doesn't exist or is not added as a "+
+ "dependency of dex_bootjars",
+ image.name,
+ apex)
+ return bootImageVariantOutputs{}
+ }
+ importedProfile := fragment.(commonBootclasspathFragment).getProfilePath()
+ if importedProfile == nil {
+ ctx.ModuleErrorf("Boot image config '%[1]s' imports profile from '%[2]s', but '%[2]s' "+
+ "doesn't provide a profile",
+ image.name,
+ apex)
+ return bootImageVariantOutputs{}
+ }
+ cmd.FlagWithInput("--profile-file=", importedProfile)
}
- cmd.FlagWithInput("--profile-file=", fragment.getProfilePath())
}
dirtyImageFile := "frameworks/base/config/dirty-image-objects"
@@ -789,7 +942,6 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p
Flag("--generate-build-id").
Flag("--image-format=lz4hc").
FlagWithArg("--oat-symbols=", symbolsFile.String()).
- Flag("--strip").
FlagWithArg("--oat-file=", outputPath.String()).
FlagWithArg("--oat-location=", oatLocation).
FlagWithArg("--image=", imagePath.String()).
@@ -799,6 +951,11 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p
Flag("--force-determinism").
Flag("--abort-on-hard-verifier-error")
+ // We don't strip on host to make perf tools work.
+ if image.target.Os == android.Android {
+ cmd.Flag("--strip")
+ }
+
// If the image is profile-guided but the profile is disabled, we omit "--compiler-filter" to
// leave the decision to dex2oat to pick the compiler filter.
if !(image.isProfileGuided() && global.DisableGenerateProfile) {
@@ -816,7 +973,7 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p
cmd.FlagWithArg("--instruction-set-features=", global.InstructionSetFeatures[arch])
}
- if global.EnableUffdGc {
+ if global.EnableUffdGc && image.target.Os == android.Android {
cmd.Flag("--runtime-arg").Flag("-Xgc:CMC")
}
@@ -881,11 +1038,7 @@ const failureMessage = `ERROR: Dex2oat failed to compile a boot image.
It is likely that the boot classpath is inconsistent.
Rebuild with ART_BOOT_IMAGE_EXTRA_ARGS="--runtime-arg -verbose:verifier" to see verification errors.`
-func bootImageProfileRule(ctx android.ModuleContext, image *bootImageConfig) android.WritablePath {
- if !image.isProfileGuided() {
- return nil
- }
-
+func bootImageProfileRuleCommon(ctx android.ModuleContext, name string, dexFiles android.Paths, dexLocations []string) android.WritablePath {
globalSoong := dexpreopt.GetGlobalSoongConfig(ctx)
global := dexpreopt.GetGlobalConfig(ctx)
@@ -912,28 +1065,39 @@ func bootImageProfileRule(ctx android.ModuleContext, image *bootImageConfig) and
if path := android.ExistentPathForSource(ctx, extraProfile); path.Valid() {
profiles = append(profiles, path.Path())
}
- bootImageProfile := image.dir.Join(ctx, "boot-image-profile.txt")
+ bootImageProfile := android.PathForModuleOut(ctx, name, "boot-image-profile.txt")
rule.Command().Text("cat").Inputs(profiles).Text(">").Output(bootImageProfile)
- profile := image.dir.Join(ctx, "boot.prof")
+ profile := android.PathForModuleOut(ctx, name, "boot.prof")
rule.Command().
Text(`ANDROID_LOG_TAGS="*:e"`).
Tool(globalSoong.Profman).
Flag("--output-profile-type=boot").
FlagWithInput("--create-profile-from=", bootImageProfile).
- FlagForEachInput("--apk=", image.dexPathsDeps.Paths()).
- FlagForEachArg("--dex-location=", image.getAnyAndroidVariant().dexLocationsDeps).
+ FlagForEachInput("--apk=", dexFiles).
+ FlagForEachArg("--dex-location=", dexLocations).
FlagWithOutput("--reference-profile-file=", profile)
+ rule.Build("bootJarsProfile_"+name, "profile boot jars "+name)
+
+ return profile
+}
+
+func bootImageProfileRule(ctx android.ModuleContext, image *bootImageConfig) android.WritablePath {
+ if !image.isProfileGuided() {
+ return nil
+ }
+
+ profile := bootImageProfileRuleCommon(ctx, image.name, image.dexPathsDeps.Paths(), image.getAnyAndroidVariant().dexLocationsDeps)
+
if image == defaultBootImageConfig(ctx) {
+ rule := android.NewRuleBuilder(pctx, ctx)
rule.Install(profile, "/system/etc/boot-image.prof")
image.profileInstalls = append(image.profileInstalls, rule.Installs()...)
image.profileLicenseMetadataFile = android.OptionalPathForPath(ctx.LicenseMetadataFile())
}
- rule.Build("bootJarsProfile", "profile boot jars")
-
return profile
}
@@ -972,6 +1136,8 @@ func bootFrameworkProfileRule(ctx android.ModuleContext, image *bootImageConfig)
func dumpOatRules(ctx android.ModuleContext, image *bootImageConfig) {
var allPhonies android.Paths
+ name := image.name
+ global := dexpreopt.GetGlobalConfig(ctx)
for _, image := range image.variants {
arch := image.target.Arch.ArchType
suffix := arch.String()
@@ -980,36 +1146,39 @@ func dumpOatRules(ctx android.ModuleContext, image *bootImageConfig) {
suffix = "host-" + suffix
}
// Create a rule to call oatdump.
- output := android.PathForOutput(ctx, "boot."+suffix+".oatdump.txt")
+ output := android.PathForOutput(ctx, name+"."+suffix+".oatdump.txt")
rule := android.NewRuleBuilder(pctx, ctx)
imageLocationsOnHost, _ := image.imageLocations()
- rule.Command().
+ cmd := rule.Command().
BuiltTool("oatdump").
FlagWithInputList("--runtime-arg -Xbootclasspath:", image.dexPathsDeps.Paths(), ":").
FlagWithList("--runtime-arg -Xbootclasspath-locations:", image.dexLocationsDeps, ":").
FlagWithArg("--image=", strings.Join(imageLocationsOnHost, ":")).Implicits(image.imagesDeps.Paths()).
FlagWithOutput("--output=", output).
FlagWithArg("--instruction-set=", arch.String())
- rule.Build("dump-oat-boot-"+suffix, "dump oat boot "+arch.String())
+ if global.EnableUffdGc && image.target.Os == android.Android {
+ cmd.Flag("--runtime-arg").Flag("-Xgc:CMC")
+ }
+ rule.Build("dump-oat-"+name+"-"+suffix, "dump oat "+name+" "+arch.String())
// Create a phony rule that depends on the output file and prints the path.
- phony := android.PathForPhony(ctx, "dump-oat-boot-"+suffix)
+ phony := android.PathForPhony(ctx, "dump-oat-"+name+"-"+suffix)
rule = android.NewRuleBuilder(pctx, ctx)
rule.Command().
Implicit(output).
ImplicitOutput(phony).
Text("echo").FlagWithArg("Output in ", output.String())
- rule.Build("phony-dump-oat-boot-"+suffix, "dump oat boot "+arch.String())
+ rule.Build("phony-dump-oat-"+name+"-"+suffix, "dump oat "+name+" "+arch.String())
allPhonies = append(allPhonies, phony)
}
- phony := android.PathForPhony(ctx, "dump-oat-boot")
+ phony := android.PathForPhony(ctx, "dump-oat-"+name)
ctx.Build(pctx, android.BuildParams{
Rule: android.Phony,
Output: phony,
Inputs: allPhonies,
- Description: "dump-oat-boot",
+ Description: "dump-oat-"+name,
})
}
@@ -1044,11 +1213,9 @@ func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) {
ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_FILES", strings.Join(dexPaths.Strings(), " "))
ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS", strings.Join(dexLocations, " "))
- var imageNames []string
// The primary ART boot image is exposed to Make for testing (gtests) and benchmarking
// (golem) purposes.
for _, current := range append(d.otherImages, image) {
- imageNames = append(imageNames, current.name)
for _, variant := range current.variants {
suffix := ""
if variant.target.Os.Class == android.Host {
@@ -1069,8 +1236,6 @@ func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) {
ctx.Strict("DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICE"+current.name, strings.Join(imageLocationsOnDevice, ":"))
ctx.Strict("DEXPREOPT_IMAGE_ZIP_"+current.name, current.zip.String())
}
- // Ensure determinism.
- sort.Strings(imageNames)
- ctx.Strict("DEXPREOPT_IMAGE_NAMES", strings.Join(imageNames, " "))
+ ctx.Strict("DEXPREOPT_IMAGE_NAMES", strings.Join(getImageNames(), " "))
}
}
diff --git a/java/dexpreopt_check.go b/java/dexpreopt_check.go
index 83c088cd4..7499481de 100644
--- a/java/dexpreopt_check.go
+++ b/java/dexpreopt_check.go
@@ -28,7 +28,7 @@ func init() {
}
func RegisterDexpreoptCheckBuildComponents(ctx android.RegistrationContext) {
- ctx.RegisterSingletonModuleType("dexpreopt_systemserver_check", dexpreoptSystemserverCheckFactory)
+ ctx.RegisterParallelSingletonModuleType("dexpreopt_systemserver_check", dexpreoptSystemserverCheckFactory)
}
// A build-time check to verify if all compilation artifacts of system server jars are installed
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index 9100e87c6..0f4bd9b34 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -40,57 +40,67 @@ func dexpreoptTargets(ctx android.PathContext) []android.Target {
}
var (
- bootImageConfigKey = android.NewOnceKey("bootImageConfig")
- bootImageConfigRawKey = android.NewOnceKey("bootImageConfigRaw")
- artBootImageName = "art"
- frameworkBootImageName = "boot"
- mainlineBootImageName = "mainline"
- bootImageStem = "boot"
+ bootImageConfigKey = android.NewOnceKey("bootImageConfig")
+ bootImageConfigRawKey = android.NewOnceKey("bootImageConfigRaw")
+ frameworkBootImageName = "boot"
+ mainlineBootImageName = "mainline"
+ bootImageStem = "boot"
+ profileInstallPathInApex = "etc/boot-image.prof"
)
+// getImageNames returns an ordered list of image names. The order doesn't matter but needs to be
+// deterministic. The names listed here must match the map keys returned by genBootImageConfigs.
+func getImageNames() []string {
+ return []string{"art", "boot", "mainline"}
+}
+
func genBootImageConfigRaw(ctx android.PathContext) map[string]*bootImageConfig {
return ctx.Config().Once(bootImageConfigRawKey, func() interface{} {
global := dexpreopt.GetGlobalConfig(ctx)
- artModules := global.ArtApexJars
- frameworkModules := global.BootJars // This includes `artModules`.
+ artBootImageName := "art" // Keep this local to avoid accidental references.
+ frameworkModules := global.BootJars // This includes `global.ArtApexJars`.
mainlineBcpModules := global.ApexBootJars
frameworkSubdir := "system/framework"
- // ART config for the primary boot image in the ART apex.
- // It includes the Core Libraries.
+ profileImports := []string{"com.android.art"}
+
+ // ART boot image for testing only. Do not rely on it to make any build-time decision.
artCfg := bootImageConfig{
- name: artBootImageName,
- stem: bootImageStem,
- installDir: "apex/art_boot_images/javalib",
- profileInstallPathInApex: "etc/boot-image.prof",
- modules: artModules,
- preloadedClassesFile: "art/build/boot/preloaded-classes",
- compilerFilter: "speed-profile",
- singleImage: false,
+ 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,
}
// Framework config for the boot image extension.
// It includes framework libraries and depends on the ART config.
frameworkCfg := bootImageConfig{
name: frameworkBootImageName,
+ enabledIfExists: "platform-bootclasspath",
stem: bootImageStem,
installDir: frameworkSubdir,
modules: frameworkModules,
preloadedClassesFile: "frameworks/base/config/preloaded-classes",
compilerFilter: "speed-profile",
singleImage: false,
- profileImports: []*bootImageConfig{&artCfg},
+ profileImports: profileImports,
}
mainlineCfg := bootImageConfig{
- extends: &frameworkCfg,
- name: mainlineBootImageName,
- stem: bootImageStem,
- installDir: frameworkSubdir,
- modules: mainlineBcpModules,
- compilerFilter: "verify",
- singleImage: true,
+ extends: &frameworkCfg,
+ name: mainlineBootImageName,
+ enabledIfExists: "platform-bootclasspath",
+ stem: bootImageStem,
+ installDir: frameworkSubdir,
+ modules: mainlineBcpModules,
+ compilerFilter: "verify",
+ singleImage: true,
}
return map[string]*bootImageConfig{
@@ -105,8 +115,7 @@ func genBootImageConfigRaw(ctx android.PathContext) map[string]*bootImageConfig
func genBootImageConfigs(ctx android.PathContext) map[string]*bootImageConfig {
return ctx.Config().Once(bootImageConfigKey, func() interface{} {
targets := dexpreoptTargets(ctx)
- archType := ctx.Config().Targets[android.Android][0].Arch.ArchType
- deviceDir := android.PathForOutput(ctx, toDexpreoptDirName(archType))
+ deviceDir := android.PathForOutput(ctx, getDexpreoptDirName(ctx))
configs := genBootImageConfigRaw(ctx)
@@ -181,10 +190,6 @@ func calculateDepsRecursive(c *bootImageConfig, targets []android.Target, visite
}
}
-func artBootImageConfig(ctx android.PathContext) *bootImageConfig {
- return genBootImageConfigs(ctx)[artBootImageName]
-}
-
func defaultBootImageConfig(ctx android.PathContext) *bootImageConfig {
return genBootImageConfigs(ctx)[frameworkBootImageName]
}
@@ -193,6 +198,18 @@ func mainlineBootImageConfig(ctx android.PathContext) *bootImageConfig {
return genBootImageConfigs(ctx)[mainlineBootImageName]
}
+// isProfileProviderApex returns true if this apex provides a boot image profile.
+func isProfileProviderApex(ctx android.PathContext, apexName string) bool {
+ for _, config := range genBootImageConfigs(ctx) {
+ for _, profileImport := range config.profileImports {
+ if profileImport == apexName {
+ return true
+ }
+ }
+ }
+ return false
+}
+
// Apex boot config allows to access build/install paths of apex boot jars without going
// through the usual trouble of registering dependencies on those modules and extracting build paths
// from those dependencies.
@@ -218,8 +235,7 @@ var updatableBootConfigKey = android.NewOnceKey("apexBootConfig")
func GetApexBootConfig(ctx android.PathContext) apexBootConfig {
return ctx.Config().Once(updatableBootConfigKey, func() interface{} {
apexBootJars := dexpreopt.GetGlobalConfig(ctx).ApexBootJars
- archType := ctx.Config().Targets[android.Android][0].Arch.ArchType
- dir := android.PathForOutput(ctx, toDexpreoptDirName(archType), "apex_bootjars")
+ dir := android.PathForOutput(ctx, getDexpreoptDirName(ctx), "apex_bootjars")
dexPaths := apexBootJars.BuildPaths(ctx, dir)
dexPathsByModuleName := apexBootJars.BuildPathsByModule(ctx, dir)
@@ -250,8 +266,6 @@ func bcpForDexpreopt(ctx android.PathContext, withUpdatable bool) (android.Writa
var defaultBootclasspathKey = android.NewOnceKey("defaultBootclasspath")
-var copyOf = android.CopyOf
-
func init() {
android.RegisterMakeVarsProvider(pctx, dexpreoptConfigMakevars)
}
@@ -260,6 +274,11 @@ func dexpreoptConfigMakevars(ctx android.MakeVarsContext) {
ctx.Strict("DEXPREOPT_BOOT_JARS_MODULES", strings.Join(defaultBootImageConfig(ctx).modules.CopyOfApexJarPairs(), ":"))
}
-func toDexpreoptDirName(arch android.ArchType) string {
- return "dexpreopt_" + arch.String()
+func getDexpreoptDirName(ctx android.PathContext) string {
+ prefix := "dexpreopt_"
+ targets := ctx.Config().Targets[android.Android]
+ if len(targets) > 0 {
+ return prefix+targets[0].Arch.ArchType.String()
+ }
+ return prefix+"unknown_target"
}
diff --git a/java/dexpreopt_config_test.go b/java/dexpreopt_config_test.go
index cd7f295c8..44d2127fd 100644
--- a/java/dexpreopt_config_test.go
+++ b/java/dexpreopt_config_test.go
@@ -16,6 +16,7 @@ package java
import (
"runtime"
+ "sort"
"testing"
"android/soong/android"
@@ -35,3 +36,22 @@ func TestBootImageConfig(t *testing.T) {
CheckFrameworkBootImageConfig(t, result)
CheckMainlineBootImageConfig(t, result)
}
+
+func TestImageNames(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ PrepareForBootImageConfigTest,
+ ).RunTest(t)
+
+ names := getImageNames()
+ sort.Strings(names)
+
+ ctx := &android.TestPathContext{TestResult: result}
+ configs := genBootImageConfigs(ctx)
+ namesFromConfigs := make([]string, 0, len(configs))
+ for name, _ := range configs {
+ namesFromConfigs = append(namesFromConfigs, name)
+ }
+ sort.Strings(namesFromConfigs)
+
+ android.AssertArrayString(t, "getImageNames vs genBootImageConfigs", names, namesFromConfigs)
+}
diff --git a/java/dexpreopt_config_testing.go b/java/dexpreopt_config_testing.go
index 6f3aa2be8..176c251fd 100644
--- a/java/dexpreopt_config_testing.go
+++ b/java/dexpreopt_config_testing.go
@@ -29,6 +29,7 @@ import (
"testing"
"android/soong/android"
+ "android/soong/dexpreopt"
)
// PrepareForBootImageConfigTest is the minimal set of preparers that are needed to be able to use
@@ -36,7 +37,17 @@ import (
var PrepareForBootImageConfigTest = android.GroupFixturePreparers(
android.PrepareForTestWithArchMutator,
android.PrepareForTestAccessingMakeVars,
+ PrepareForTestWithDexpreopt,
FixtureConfigureBootJars("com.android.art:core1", "com.android.art:core2", "platform:framework"),
+ dexpreopt.FixtureSetTestOnlyArtBootImageJars("com.android.art:core1", "com.android.art:core2", "platform:extra1"),
+ android.FixtureAddTextFile("extra1/Android.bp", `
+ java_library {
+ name: "extra1",
+ srcs: ["extra1.java"],
+ installable: true,
+ }
+ `),
+ android.FixtureAddFile("extra1/extra1.java", nil),
)
var PrepareApexBootJarConfigs = FixtureConfigureApexBootJars(
@@ -44,18 +55,18 @@ var PrepareApexBootJarConfigs = FixtureConfigureApexBootJars(
var PrepareApexBootJarConfigsAndModules = android.GroupFixturePreparers(
PrepareApexBootJarConfigs,
- prepareApexBootJarModule("com.android.foo", "framework-foo"),
- prepareApexBootJarModule("com.android.bar", "framework-bar"),
+ PrepareApexBootJarModule("com.android.foo", "framework-foo"),
+ PrepareApexBootJarModule("com.android.bar", "framework-bar"),
)
var ApexBootJarFragmentsForPlatformBootclasspath = fmt.Sprintf(`
{
apex: "%[1]s",
- module: "%[1]s-bootclasspathfragment",
+ module: "%[1]s-bootclasspath-fragment",
},
{
apex: "%[2]s",
- module: "%[2]s-bootclasspathfragment",
+ module: "%[2]s-bootclasspath-fragment",
},
`, "com.android.foo", "com.android.bar")
@@ -64,15 +75,22 @@ var ApexBootJarDexJarPaths = []string{
"out/soong/.intermediates/packages/modules/com.android.foo/framework-foo/android_common_apex10000/aligned/framework-foo.jar",
}
-func prepareApexBootJarModule(apexName string, moduleName string) android.FixturePreparer {
+func PrepareApexBootJarModule(apexName string, moduleName string) android.FixturePreparer {
moduleSourceDir := fmt.Sprintf("packages/modules/%s", apexName)
+ fragmentName := apexName+"-bootclasspath-fragment"
+ imageNameProp := ""
+ if apexName == "com.android.art" {
+ fragmentName = "art-bootclasspath-fragment"
+ imageNameProp = `image_name: "art",`
+ }
+
return android.GroupFixturePreparers(
android.FixtureAddTextFile(moduleSourceDir+"/Android.bp", fmt.Sprintf(`
apex {
name: "%[1]s",
key: "%[1]s.key",
bootclasspath_fragments: [
- "%[1]s-bootclasspathfragment",
+ "%[3]s",
],
updatable: false,
}
@@ -84,7 +102,8 @@ func prepareApexBootJarModule(apexName string, moduleName string) android.Fixtur
}
bootclasspath_fragment {
- name: "%[1]s-bootclasspathfragment",
+ name: "%[3]s",
+ %[4]s
contents: ["%[2]s"],
apex_available: ["%[1]s"],
hidden_api: {
@@ -100,7 +119,7 @@ func prepareApexBootJarModule(apexName string, moduleName string) android.Fixtur
compile_dex: true,
apex_available: ["%[1]s"],
}
- `, apexName, moduleName)),
+ `, apexName, moduleName, fragmentName, imageNameProp)),
android.FixtureMergeMockFs(android.MockFS{
fmt.Sprintf("%s/apex_manifest.json", moduleSourceDir): nil,
fmt.Sprintf("%s/%s.avbpubkey", moduleSourceDir, apexName): nil,
@@ -192,7 +211,7 @@ func CheckArtBootImageConfig(t *testing.T, result *android.TestResult) {
// getArtImageConfig gets the ART bootImageConfig that was created during the test.
func getArtImageConfig(result *android.TestResult) *bootImageConfig {
pathCtx := &android.TestPathContext{TestResult: result}
- imageConfig := artBootImageConfig(pathCtx)
+ imageConfig := genBootImageConfigs(pathCtx)["art"]
return imageConfig
}
@@ -210,15 +229,15 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b
symbolsDir: "out/soong/dexpreopt_arm64/dex_artjars_unstripped",
installDir: "apex/art_boot_images/javalib",
profileInstallPathInApex: "etc/boot-image.prof",
- modules: android.CreateTestConfiguredJarList([]string{"com.android.art:core1", "com.android.art:core2"}),
- dexPaths: []string{"out/soong/dexpreopt_arm64/dex_artjars_input/core1.jar", "out/soong/dexpreopt_arm64/dex_artjars_input/core2.jar"},
- dexPathsDeps: []string{"out/soong/dexpreopt_arm64/dex_artjars_input/core1.jar", "out/soong/dexpreopt_arm64/dex_artjars_input/core2.jar"},
+ modules: android.CreateTestConfiguredJarList([]string{"com.android.art:core1", "com.android.art:core2", "platform:extra1"}),
+ dexPaths: []string{"out/soong/dexpreopt_arm64/dex_artjars_input/core1.jar", "out/soong/dexpreopt_arm64/dex_artjars_input/core2.jar", "out/soong/dexpreopt_arm64/dex_artjars_input/extra1.jar"},
+ dexPathsDeps: []string{"out/soong/dexpreopt_arm64/dex_artjars_input/core1.jar", "out/soong/dexpreopt_arm64/dex_artjars_input/core2.jar", "out/soong/dexpreopt_arm64/dex_artjars_input/extra1.jar"},
zip: "out/soong/dexpreopt_arm64/dex_artjars/art.zip",
variants: []*expectedVariant{
{
archType: android.Arm64,
- dexLocations: []string{"/apex/com.android.art/javalib/core1.jar", "/apex/com.android.art/javalib/core2.jar"},
- dexLocationsDeps: []string{"/apex/com.android.art/javalib/core1.jar", "/apex/com.android.art/javalib/core2.jar"},
+ dexLocations: []string{"/apex/com.android.art/javalib/core1.jar", "/apex/com.android.art/javalib/core2.jar", "/system/framework/extra1.jar"},
+ dexLocationsDeps: []string{"/apex/com.android.art/javalib/core1.jar", "/apex/com.android.art/javalib/core2.jar", "/system/framework/extra1.jar"},
imagePathOnHost: "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art",
imagePathOnDevice: "/apex/art_boot_images/javalib/arm64/boot.art",
imagesDeps: []string{
@@ -228,6 +247,9 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b
"out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.art",
"out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat",
"out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex",
+ "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-extra1.art",
+ "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-extra1.oat",
+ "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-extra1.vdex",
},
installs: []normalizedInstall{
{
@@ -246,6 +268,14 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b
from: "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat",
to: "/apex/art_boot_images/javalib/arm64/boot-core2.oat",
},
+ {
+ from: "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-extra1.art",
+ to: "/apex/art_boot_images/javalib/arm64/boot-extra1.art",
+ },
+ {
+ from: "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-extra1.oat",
+ to: "/apex/art_boot_images/javalib/arm64/boot-extra1.oat",
+ },
},
vdexInstalls: []normalizedInstall{
{
@@ -256,6 +286,10 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b
from: "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex",
to: "/apex/art_boot_images/javalib/arm64/boot-core2.vdex",
},
+ {
+ from: "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-extra1.vdex",
+ to: "/apex/art_boot_images/javalib/arm64/boot-extra1.vdex",
+ },
},
unstrippedInstalls: []normalizedInstall{
{
@@ -266,13 +300,17 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b
from: "out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot-core2.oat",
to: "/apex/art_boot_images/javalib/arm64/boot-core2.oat",
},
+ {
+ from: "out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot-extra1.oat",
+ to: "/apex/art_boot_images/javalib/arm64/boot-extra1.oat",
+ },
},
licenseMetadataFile: expectedLicenseMetadataFile,
},
{
archType: android.Arm,
- dexLocations: []string{"/apex/com.android.art/javalib/core1.jar", "/apex/com.android.art/javalib/core2.jar"},
- dexLocationsDeps: []string{"/apex/com.android.art/javalib/core1.jar", "/apex/com.android.art/javalib/core2.jar"},
+ dexLocations: []string{"/apex/com.android.art/javalib/core1.jar", "/apex/com.android.art/javalib/core2.jar", "/system/framework/extra1.jar"},
+ dexLocationsDeps: []string{"/apex/com.android.art/javalib/core1.jar", "/apex/com.android.art/javalib/core2.jar", "/system/framework/extra1.jar"},
imagePathOnHost: "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art",
imagePathOnDevice: "/apex/art_boot_images/javalib/arm/boot.art",
imagesDeps: []string{
@@ -282,6 +320,9 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b
"out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.art",
"out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat",
"out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex",
+ "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-extra1.art",
+ "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-extra1.oat",
+ "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-extra1.vdex",
},
installs: []normalizedInstall{
{
@@ -300,6 +341,14 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b
from: "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat",
to: "/apex/art_boot_images/javalib/arm/boot-core2.oat",
},
+ {
+ from: "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-extra1.art",
+ to: "/apex/art_boot_images/javalib/arm/boot-extra1.art",
+ },
+ {
+ from: "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-extra1.oat",
+ to: "/apex/art_boot_images/javalib/arm/boot-extra1.oat",
+ },
},
vdexInstalls: []normalizedInstall{
{
@@ -310,6 +359,10 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b
from: "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex",
to: "/apex/art_boot_images/javalib/arm/boot-core2.vdex",
},
+ {
+ from: "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-extra1.vdex",
+ to: "/apex/art_boot_images/javalib/arm/boot-extra1.vdex",
+ },
},
unstrippedInstalls: []normalizedInstall{
{
@@ -320,13 +373,17 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b
from: "out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot-core2.oat",
to: "/apex/art_boot_images/javalib/arm/boot-core2.oat",
},
+ {
+ from: "out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot-extra1.oat",
+ to: "/apex/art_boot_images/javalib/arm/boot-extra1.oat",
+ },
},
licenseMetadataFile: expectedLicenseMetadataFile,
},
{
archType: android.X86_64,
- dexLocations: []string{"host/linux-x86/apex/com.android.art/javalib/core1.jar", "host/linux-x86/apex/com.android.art/javalib/core2.jar"},
- dexLocationsDeps: []string{"host/linux-x86/apex/com.android.art/javalib/core1.jar", "host/linux-x86/apex/com.android.art/javalib/core2.jar"},
+ dexLocations: []string{"host/linux-x86/apex/com.android.art/javalib/core1.jar", "host/linux-x86/apex/com.android.art/javalib/core2.jar", "host/linux-x86/system/framework/extra1.jar"},
+ dexLocationsDeps: []string{"host/linux-x86/apex/com.android.art/javalib/core1.jar", "host/linux-x86/apex/com.android.art/javalib/core2.jar", "host/linux-x86/system/framework/extra1.jar"},
imagePathOnHost: "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art",
imagePathOnDevice: "/apex/art_boot_images/javalib/x86_64/boot.art",
imagesDeps: []string{
@@ -336,6 +393,9 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b
"out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.art",
"out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat",
"out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.vdex",
+ "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.art",
+ "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.oat",
+ "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.vdex",
},
installs: []normalizedInstall{
{
@@ -352,6 +412,13 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b
from: "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat",
to: "/apex/art_boot_images/javalib/x86_64/boot-core2.oat",
},
+ {
+ from: "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.art",
+ to: "/apex/art_boot_images/javalib/x86_64/boot-extra1.art",
+ }, {
+ from: "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.oat",
+ to: "/apex/art_boot_images/javalib/x86_64/boot-extra1.oat",
+ },
},
vdexInstalls: []normalizedInstall{
{
@@ -362,6 +429,10 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b
from: "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.vdex",
to: "/apex/art_boot_images/javalib/x86_64/boot-core2.vdex",
},
+ {
+ from: "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.vdex",
+ to: "/apex/art_boot_images/javalib/x86_64/boot-extra1.vdex",
+ },
},
unstrippedInstalls: []normalizedInstall{
{
@@ -372,13 +443,17 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b
from: "out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat",
to: "/apex/art_boot_images/javalib/x86_64/boot-core2.oat",
},
+ {
+ from: "out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.oat",
+ to: "/apex/art_boot_images/javalib/x86_64/boot-extra1.oat",
+ },
},
licenseMetadataFile: expectedLicenseMetadataFile,
},
{
archType: android.X86,
- dexLocations: []string{"host/linux-x86/apex/com.android.art/javalib/core1.jar", "host/linux-x86/apex/com.android.art/javalib/core2.jar"},
- dexLocationsDeps: []string{"host/linux-x86/apex/com.android.art/javalib/core1.jar", "host/linux-x86/apex/com.android.art/javalib/core2.jar"},
+ dexLocations: []string{"host/linux-x86/apex/com.android.art/javalib/core1.jar", "host/linux-x86/apex/com.android.art/javalib/core2.jar", "host/linux-x86/system/framework/extra1.jar"},
+ dexLocationsDeps: []string{"host/linux-x86/apex/com.android.art/javalib/core1.jar", "host/linux-x86/apex/com.android.art/javalib/core2.jar", "host/linux-x86/system/framework/extra1.jar"},
imagePathOnHost: "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art",
imagePathOnDevice: "/apex/art_boot_images/javalib/x86/boot.art",
imagesDeps: []string{
@@ -388,6 +463,9 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b
"out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.art",
"out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat",
"out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex",
+ "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.art",
+ "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.oat",
+ "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.vdex",
},
installs: []normalizedInstall{
{
@@ -404,6 +482,13 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b
from: "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat",
to: "/apex/art_boot_images/javalib/x86/boot-core2.oat",
},
+ {
+ from: "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.art",
+ to: "/apex/art_boot_images/javalib/x86/boot-extra1.art",
+ }, {
+ from: "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.oat",
+ to: "/apex/art_boot_images/javalib/x86/boot-extra1.oat",
+ },
},
vdexInstalls: []normalizedInstall{
{
@@ -414,6 +499,10 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b
from: "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex",
to: "/apex/art_boot_images/javalib/x86/boot-core2.vdex",
},
+ {
+ from: "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.vdex",
+ to: "/apex/art_boot_images/javalib/x86/boot-extra1.vdex",
+ },
},
unstrippedInstalls: []normalizedInstall{
{
@@ -424,6 +513,10 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b
from: "out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat",
to: "/apex/art_boot_images/javalib/x86/boot-core2.oat",
},
+ {
+ from: "out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.oat",
+ to: "/apex/art_boot_images/javalib/x86/boot-extra1.oat",
+ },
},
licenseMetadataFile: expectedLicenseMetadataFile,
},
@@ -805,8 +898,8 @@ func checkFrameworkBootImageConfig(t *testing.T, result *android.TestResult, mut
},
},
profileInstalls: []normalizedInstall{
+ {from: "out/soong/.intermediates/default/java/dex_bootjars/android_common/boot/boot.prof", to: "/system/etc/boot-image.prof"},
{from: "out/soong/dexpreopt_arm64/dex_bootjars/boot.bprof", to: "/system/etc/boot-image.bprof"},
- {from: "out/soong/dexpreopt_arm64/dex_bootjars/boot.prof", to: "/system/etc/boot-image.prof"},
},
profileLicenseMetadataFile: expectedLicenseMetadataFile,
}
@@ -1136,7 +1229,6 @@ func nestedCheckBootImageConfig(t *testing.T, imageConfig *bootImageConfig, expe
android.AssertPathRelativeToTopEquals(t, "dir", expected.dir, imageConfig.dir)
android.AssertPathRelativeToTopEquals(t, "symbolsDir", expected.symbolsDir, imageConfig.symbolsDir)
android.AssertStringEquals(t, "installDir", expected.installDir, imageConfig.installDir)
- android.AssertStringEquals(t, "profileInstallPathInApex", expected.profileInstallPathInApex, imageConfig.profileInstallPathInApex)
android.AssertDeepEquals(t, "modules", expected.modules, imageConfig.modules)
android.AssertPathsRelativeToTopEquals(t, "dexPaths", expected.dexPaths, imageConfig.dexPaths.Paths())
android.AssertPathsRelativeToTopEquals(t, "dexPathsDeps", expected.dexPathsDeps, imageConfig.dexPathsDeps.Paths())
@@ -1195,10 +1287,10 @@ DEXPREOPT_BOOTCLASSPATH_DEX_FILES=out/soong/dexpreopt_arm64/dex_bootjars_input/c
DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS=/apex/com.android.art/javalib/core1.jar /apex/com.android.art/javalib/core2.jar /system/framework/framework.jar
DEXPREOPT_BOOT_JARS_MODULES=com.android.art:core1:com.android.art:core2:platform:framework
DEXPREOPT_GEN=out/host/linux-x86/bin/dexpreopt_gen
-DEXPREOPT_IMAGE_BUILT_INSTALLED_art_arm=out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art:/apex/art_boot_images/javalib/arm/boot.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat:/apex/art_boot_images/javalib/arm/boot.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.art:/apex/art_boot_images/javalib/arm/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat:/apex/art_boot_images/javalib/arm/boot-core2.oat
-DEXPREOPT_IMAGE_BUILT_INSTALLED_art_arm64=out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art:/apex/art_boot_images/javalib/arm64/boot.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.oat:/apex/art_boot_images/javalib/arm64/boot.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.art:/apex/art_boot_images/javalib/arm64/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat:/apex/art_boot_images/javalib/arm64/boot-core2.oat
-DEXPREOPT_IMAGE_BUILT_INSTALLED_art_host_x86=out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art:/apex/art_boot_images/javalib/x86/boot.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat:/apex/art_boot_images/javalib/x86/boot.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.art:/apex/art_boot_images/javalib/x86/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat:/apex/art_boot_images/javalib/x86/boot-core2.oat
-DEXPREOPT_IMAGE_BUILT_INSTALLED_art_host_x86_64=out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art:/apex/art_boot_images/javalib/x86_64/boot.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat:/apex/art_boot_images/javalib/x86_64/boot.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.art:/apex/art_boot_images/javalib/x86_64/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat:/apex/art_boot_images/javalib/x86_64/boot-core2.oat
+DEXPREOPT_IMAGE_BUILT_INSTALLED_art_arm=out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art:/apex/art_boot_images/javalib/arm/boot.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat:/apex/art_boot_images/javalib/arm/boot.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.art:/apex/art_boot_images/javalib/arm/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat:/apex/art_boot_images/javalib/arm/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-extra1.art:/apex/art_boot_images/javalib/arm/boot-extra1.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-extra1.oat:/apex/art_boot_images/javalib/arm/boot-extra1.oat
+DEXPREOPT_IMAGE_BUILT_INSTALLED_art_arm64=out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art:/apex/art_boot_images/javalib/arm64/boot.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.oat:/apex/art_boot_images/javalib/arm64/boot.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.art:/apex/art_boot_images/javalib/arm64/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat:/apex/art_boot_images/javalib/arm64/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-extra1.art:/apex/art_boot_images/javalib/arm64/boot-extra1.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-extra1.oat:/apex/art_boot_images/javalib/arm64/boot-extra1.oat
+DEXPREOPT_IMAGE_BUILT_INSTALLED_art_host_x86=out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art:/apex/art_boot_images/javalib/x86/boot.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat:/apex/art_boot_images/javalib/x86/boot.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.art:/apex/art_boot_images/javalib/x86/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat:/apex/art_boot_images/javalib/x86/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.art:/apex/art_boot_images/javalib/x86/boot-extra1.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.oat:/apex/art_boot_images/javalib/x86/boot-extra1.oat
+DEXPREOPT_IMAGE_BUILT_INSTALLED_art_host_x86_64=out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art:/apex/art_boot_images/javalib/x86_64/boot.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat:/apex/art_boot_images/javalib/x86_64/boot.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.art:/apex/art_boot_images/javalib/x86_64/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat:/apex/art_boot_images/javalib/x86_64/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.art:/apex/art_boot_images/javalib/x86_64/boot-extra1.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.oat:/apex/art_boot_images/javalib/x86_64/boot-extra1.oat
DEXPREOPT_IMAGE_BUILT_INSTALLED_boot_arm=out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot.art:/system/framework/arm/boot.art out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot.oat:/system/framework/arm/boot.oat out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot-core2.art:/system/framework/arm/boot-core2.art out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot-core2.oat:/system/framework/arm/boot-core2.oat out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot-framework.art:/system/framework/arm/boot-framework.art out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot-framework.oat:/system/framework/arm/boot-framework.oat
DEXPREOPT_IMAGE_BUILT_INSTALLED_boot_arm64=out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot.art:/system/framework/arm64/boot.art out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot.oat:/system/framework/arm64/boot.oat out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot-core2.art:/system/framework/arm64/boot-core2.art out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot-core2.oat:/system/framework/arm64/boot-core2.oat out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot-framework.art:/system/framework/arm64/boot-framework.art out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot-framework.oat:/system/framework/arm64/boot-framework.oat
DEXPREOPT_IMAGE_BUILT_INSTALLED_boot_host_x86=out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot.art:/system/framework/x86/boot.art out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot.oat:/system/framework/x86/boot.oat out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot-core2.art:/system/framework/x86/boot-core2.art out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot-core2.oat:/system/framework/x86/boot-core2.oat out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art:/system/framework/x86/boot-framework.art out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.oat:/system/framework/x86/boot-framework.oat
@@ -1207,10 +1299,10 @@ DEXPREOPT_IMAGE_BUILT_INSTALLED_mainline_arm=out/soong/dexpreopt_arm64/dex_mainl
DEXPREOPT_IMAGE_BUILT_INSTALLED_mainline_arm64=out/soong/dexpreopt_arm64/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.art:/system/framework/arm64/boot-framework-foo.art out/soong/dexpreopt_arm64/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.oat:/system/framework/arm64/boot-framework-foo.oat
DEXPREOPT_IMAGE_BUILT_INSTALLED_mainline_host_x86=out/soong/dexpreopt_arm64/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.art:/system/framework/x86/boot-framework-foo.art out/soong/dexpreopt_arm64/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.oat:/system/framework/x86/boot-framework-foo.oat
DEXPREOPT_IMAGE_BUILT_INSTALLED_mainline_host_x86_64=out/soong/dexpreopt_arm64/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.art:/system/framework/x86_64/boot-framework-foo.art out/soong/dexpreopt_arm64/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.oat:/system/framework/x86_64/boot-framework-foo.oat
-DEXPREOPT_IMAGE_DEPS_art_arm=out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex
-DEXPREOPT_IMAGE_DEPS_art_arm64=out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex
-DEXPREOPT_IMAGE_DEPS_art_host_x86=out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex
-DEXPREOPT_IMAGE_DEPS_art_host_x86_64=out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.vdex
+DEXPREOPT_IMAGE_DEPS_art_arm=out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-extra1.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-extra1.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-extra1.vdex
+DEXPREOPT_IMAGE_DEPS_art_arm64=out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-extra1.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-extra1.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-extra1.vdex
+DEXPREOPT_IMAGE_DEPS_art_host_x86=out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.vdex
+DEXPREOPT_IMAGE_DEPS_art_host_x86_64=out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.vdex out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.vdex
DEXPREOPT_IMAGE_DEPS_boot_arm=out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot.art out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot.oat out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot.vdex out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot-core2.art out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot-core2.oat out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot-core2.vdex out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot-framework.art out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot-framework.oat out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot-framework.vdex
DEXPREOPT_IMAGE_DEPS_boot_arm64=out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot.art out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot.oat out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot.vdex out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot-core2.art out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot-core2.oat out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot-core2.vdex out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot-framework.art out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot-framework.oat out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot-framework.vdex
DEXPREOPT_IMAGE_DEPS_boot_host_x86=out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot.art out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot.oat out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot.vdex out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot-core2.art out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot-core2.oat out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot-core2.vdex out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.oat out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.vdex
@@ -1223,14 +1315,14 @@ DEXPREOPT_IMAGE_LICENSE_METADATA_art_arm=%[1]s
DEXPREOPT_IMAGE_LICENSE_METADATA_art_arm64=%[1]s
DEXPREOPT_IMAGE_LICENSE_METADATA_art_host_x86=%[1]s
DEXPREOPT_IMAGE_LICENSE_METADATA_art_host_x86_64=%[1]s
-DEXPREOPT_IMAGE_LICENSE_METADATA_boot_arm=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
-DEXPREOPT_IMAGE_LICENSE_METADATA_boot_arm64=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
-DEXPREOPT_IMAGE_LICENSE_METADATA_boot_host_x86=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
-DEXPREOPT_IMAGE_LICENSE_METADATA_boot_host_x86_64=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
-DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_arm=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
-DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_arm64=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
-DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_host_x86=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
-DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_host_x86_64=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
+DEXPREOPT_IMAGE_LICENSE_METADATA_boot_arm=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic
+DEXPREOPT_IMAGE_LICENSE_METADATA_boot_arm64=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic
+DEXPREOPT_IMAGE_LICENSE_METADATA_boot_host_x86=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic
+DEXPREOPT_IMAGE_LICENSE_METADATA_boot_host_x86_64=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic
+DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_arm=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic
+DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_arm64=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic
+DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_host_x86=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic
+DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_host_x86_64=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic
DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICEart=/apex/art_boot_images/javalib/boot.art
DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICEboot=/system/framework/boot.art
DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICEmainline=/system/framework/boot.art:/system/framework/boot-framework-foo.art
@@ -1238,12 +1330,12 @@ DEXPREOPT_IMAGE_LOCATIONS_ON_HOSTart=out/soong/dexpreopt_arm64/dex_artjars/andro
DEXPREOPT_IMAGE_LOCATIONS_ON_HOSTboot=out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/boot.art
DEXPREOPT_IMAGE_LOCATIONS_ON_HOSTmainline=out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/boot.art:out/soong/dexpreopt_arm64/dex_mainlinejars/android/system/framework/boot-framework-foo.art
DEXPREOPT_IMAGE_NAMES=art boot mainline
-DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED=out/soong/dexpreopt_arm64/dex_bootjars/boot.bprof:/system/etc/boot-image.bprof out/soong/dexpreopt_arm64/dex_bootjars/boot.prof:/system/etc/boot-image.prof
-DEXPREOPT_IMAGE_PROFILE_LICENSE_METADATA=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
-DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_arm=out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot.oat:/apex/art_boot_images/javalib/arm/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot-core2.oat:/apex/art_boot_images/javalib/arm/boot-core2.oat
-DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_arm64=out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot.oat:/apex/art_boot_images/javalib/arm64/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot-core2.oat:/apex/art_boot_images/javalib/arm64/boot-core2.oat
-DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_host_x86=out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat:/apex/art_boot_images/javalib/x86/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat:/apex/art_boot_images/javalib/x86/boot-core2.oat
-DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_host_x86_64=out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat:/apex/art_boot_images/javalib/x86_64/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat:/apex/art_boot_images/javalib/x86_64/boot-core2.oat
+DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED=out/soong/.intermediates/default/java/dex_bootjars/android_common/boot/boot.prof:/system/etc/boot-image.prof out/soong/dexpreopt_arm64/dex_bootjars/boot.bprof:/system/etc/boot-image.bprof
+DEXPREOPT_IMAGE_PROFILE_LICENSE_METADATA=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic
+DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_arm=out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot.oat:/apex/art_boot_images/javalib/arm/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot-core2.oat:/apex/art_boot_images/javalib/arm/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot-extra1.oat:/apex/art_boot_images/javalib/arm/boot-extra1.oat
+DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_arm64=out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot.oat:/apex/art_boot_images/javalib/arm64/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot-core2.oat:/apex/art_boot_images/javalib/arm64/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot-extra1.oat:/apex/art_boot_images/javalib/arm64/boot-extra1.oat
+DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_host_x86=out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat:/apex/art_boot_images/javalib/x86/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat:/apex/art_boot_images/javalib/x86/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.oat:/apex/art_boot_images/javalib/x86/boot-extra1.oat
+DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_host_x86_64=out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat:/apex/art_boot_images/javalib/x86_64/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat:/apex/art_boot_images/javalib/x86_64/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.oat:/apex/art_boot_images/javalib/x86_64/boot-extra1.oat
DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_boot_arm=out/soong/dexpreopt_arm64/dex_bootjars_unstripped/android/system/framework/arm/boot.oat:/system/framework/arm/boot.oat out/soong/dexpreopt_arm64/dex_bootjars_unstripped/android/system/framework/arm/boot-core2.oat:/system/framework/arm/boot-core2.oat out/soong/dexpreopt_arm64/dex_bootjars_unstripped/android/system/framework/arm/boot-framework.oat:/system/framework/arm/boot-framework.oat
DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_boot_arm64=out/soong/dexpreopt_arm64/dex_bootjars_unstripped/android/system/framework/arm64/boot.oat:/system/framework/arm64/boot.oat out/soong/dexpreopt_arm64/dex_bootjars_unstripped/android/system/framework/arm64/boot-core2.oat:/system/framework/arm64/boot-core2.oat out/soong/dexpreopt_arm64/dex_bootjars_unstripped/android/system/framework/arm64/boot-framework.oat:/system/framework/arm64/boot-framework.oat
DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_boot_host_x86=out/soong/dexpreopt_arm64/dex_bootjars_unstripped/linux_glibc/system/framework/x86/boot.oat:/system/framework/x86/boot.oat out/soong/dexpreopt_arm64/dex_bootjars_unstripped/linux_glibc/system/framework/x86/boot-core2.oat:/system/framework/x86/boot-core2.oat out/soong/dexpreopt_arm64/dex_bootjars_unstripped/linux_glibc/system/framework/x86/boot-framework.oat:/system/framework/x86/boot-framework.oat
@@ -1252,10 +1344,10 @@ DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_mainline_arm=out/soong/dexpreopt_arm6
DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_mainline_arm64=out/soong/dexpreopt_arm64/dex_mainlinejars_unstripped/android/system/framework/arm64/boot-framework-foo.oat:/system/framework/arm64/boot-framework-foo.oat
DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_mainline_host_x86=out/soong/dexpreopt_arm64/dex_mainlinejars_unstripped/linux_glibc/system/framework/x86/boot-framework-foo.oat:/system/framework/x86/boot-framework-foo.oat
DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_mainline_host_x86_64=out/soong/dexpreopt_arm64/dex_mainlinejars_unstripped/linux_glibc/system/framework/x86_64/boot-framework-foo.oat:/system/framework/x86_64/boot-framework-foo.oat
-DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_arm=out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex:/apex/art_boot_images/javalib/arm/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex:/apex/art_boot_images/javalib/arm/boot-core2.vdex
-DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_arm64=out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex:/apex/art_boot_images/javalib/arm64/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex:/apex/art_boot_images/javalib/arm64/boot-core2.vdex
-DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_host_x86=out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.vdex:/apex/art_boot_images/javalib/x86/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex:/apex/art_boot_images/javalib/x86/boot-core2.vdex
-DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_host_x86_64=out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.vdex:/apex/art_boot_images/javalib/x86_64/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.vdex:/apex/art_boot_images/javalib/x86_64/boot-core2.vdex
+DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_arm=out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex:/apex/art_boot_images/javalib/arm/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex:/apex/art_boot_images/javalib/arm/boot-core2.vdex out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-extra1.vdex:/apex/art_boot_images/javalib/arm/boot-extra1.vdex
+DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_arm64=out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex:/apex/art_boot_images/javalib/arm64/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex:/apex/art_boot_images/javalib/arm64/boot-core2.vdex out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-extra1.vdex:/apex/art_boot_images/javalib/arm64/boot-extra1.vdex
+DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_host_x86=out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.vdex:/apex/art_boot_images/javalib/x86/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex:/apex/art_boot_images/javalib/x86/boot-core2.vdex out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.vdex:/apex/art_boot_images/javalib/x86/boot-extra1.vdex
+DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_host_x86_64=out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.vdex:/apex/art_boot_images/javalib/x86_64/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.vdex:/apex/art_boot_images/javalib/x86_64/boot-core2.vdex out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.vdex:/apex/art_boot_images/javalib/x86_64/boot-extra1.vdex
DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_boot_arm=out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot.vdex:/system/framework/arm/boot.vdex out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot-core2.vdex:/system/framework/arm/boot-core2.vdex out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot-framework.vdex:/system/framework/arm/boot-framework.vdex
DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_boot_arm64=out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot.vdex:/system/framework/arm64/boot.vdex out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot-core2.vdex:/system/framework/arm64/boot-core2.vdex out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot-framework.vdex:/system/framework/arm64/boot-framework.vdex
DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_boot_host_x86=out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot.vdex:/system/framework/x86/boot.vdex out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot-core2.vdex:/system/framework/x86/boot-core2.vdex out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.vdex:/system/framework/x86/boot-framework.vdex
diff --git a/java/droiddoc.go b/java/droiddoc.go
index dbe021d00..d4ead12c8 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -608,6 +608,11 @@ func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.Rule
FlagWithArg("-Xmaxerrs ", "10").
FlagWithArg("-Xmaxwarns ", "10").
Flag("-J--add-exports=jdk.javadoc/jdk.javadoc.internal.doclets.formats.html=ALL-UNNAMED").
+ Flag("-J--add-exports=jdk.javadoc/jdk.javadoc.internal.tool=ALL-UNNAMED").
+ Flag("-J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED").
+ Flag("-J--add-exports=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED").
+ Flag("-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED").
+ Flag("-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED").
Flag("-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED").
FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-$(cat "+buildNumberFile.String()+")").OrderOnly(buildNumberFile).
FlagWithArg("-hdf page.now ", `"$(date -d @$(cat `+ctx.Config().Getenv("BUILD_DATETIME_FILE")+`) "+%d %b %Y %k:%M")" `)
diff --git a/java/droidstubs.go b/java/droidstubs.go
index 8a521aabb..bb2388f96 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -525,8 +525,7 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi
cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
}
- cmd.Flag("--no-banner").
- Flag("--color").
+ cmd.Flag("--color").
Flag("--quiet").
Flag("--format=v2").
FlagWithArg("--repeat-errors-max ", "10").
@@ -535,6 +534,14 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi
// b/223382732
FlagWithArg("--hide ", "ChangedDefault")
+ // Force metalava to ignore classes on the classpath when an API file contains missing classes.
+ // See b/285140653 for more information.
+ cmd.FlagWithArg("--api-class-resolution ", "api")
+
+ // Force metalava to sort overloaded methods by their order in the source code.
+ // See b/285312164 for more information.
+ cmd.FlagWithArg("--api-overloaded-method-order ", "source")
+
return cmd
}
diff --git a/java/fuzz.go b/java/fuzz.go
index 2b9e22b8e..b3c2fd47c 100644
--- a/java/fuzz.go
+++ b/java/fuzz.go
@@ -30,15 +30,19 @@ import (
const (
hostString = "host"
targetString = "target"
+ deviceString = "device"
)
+// Any shared libs for these deps will also be packaged
+var artDeps = []string{"libdl_android"}
+
func init() {
RegisterJavaFuzzBuildComponents(android.InitRegistrationContext)
}
func RegisterJavaFuzzBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("java_fuzz", JavaFuzzFactory)
- ctx.RegisterSingletonType("java_fuzz_packaging", javaFuzzPackagingFactory)
+ ctx.RegisterParallelSingletonType("java_fuzz_packaging", javaFuzzPackagingFactory)
}
type JavaFuzzTest struct {
@@ -78,7 +82,18 @@ func JavaFuzzFactory() android.Module {
}
func (j *JavaFuzzTest) DepsMutator(ctx android.BottomUpMutatorContext) {
+ if j.Os().Class.String() == deviceString {
+ j.testProperties.Jni_libs = append(j.testProperties.Jni_libs, artDeps...)
+ }
+
if len(j.testProperties.Jni_libs) > 0 {
+ if j.fuzzPackagedModule.FuzzProperties.Fuzz_config == nil {
+ config := &fuzz.FuzzConfig{}
+ j.fuzzPackagedModule.FuzzProperties.Fuzz_config = config
+ }
+ // this will be used by the ingestion pipeline to determine the version
+ // of jazzer to add to the fuzzer package
+ j.fuzzPackagedModule.FuzzProperties.Fuzz_config.IsJni = proptools.BoolPtr(true)
for _, target := range ctx.MultiTargets() {
sharedLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
ctx.AddFarVariationDependencies(sharedLibVariations, jniLibTag, j.testProperties.Jni_libs...)
@@ -150,7 +165,9 @@ func (s *javaFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
}
hostOrTargetString := "target"
- if javaFuzzModule.Host() {
+ if javaFuzzModule.Target().HostCross {
+ hostOrTargetString = "host_cross"
+ } else if javaFuzzModule.Host() {
hostOrTargetString = "host"
}
@@ -175,11 +192,15 @@ func (s *javaFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
files = s.PackageArtifacts(ctx, module, javaFuzzModule.fuzzPackagedModule, archDir, builder)
// Add .jar
- files = append(files, fuzz.FileToZip{javaFuzzModule.implementationJarFile, ""})
+ if !javaFuzzModule.Host() {
+ files = append(files, fuzz.FileToZip{SourceFilePath: javaFuzzModule.implementationJarFile, DestinationPathPrefix: "classes"})
+ }
+
+ files = append(files, fuzz.FileToZip{SourceFilePath: javaFuzzModule.outputFile})
// Add jni .so files
for _, fPath := range javaFuzzModule.jniFilePaths {
- files = append(files, fuzz.FileToZip{fPath, ""})
+ files = append(files, fuzz.FileToZip{SourceFilePath: fPath})
}
archDirs[archOs], ok = s.BuildZipFile(ctx, module, javaFuzzModule.fuzzPackagedModule, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
diff --git a/java/fuzz_test.go b/java/fuzz_test.go
index dd1e96b3e..f29c91327 100644
--- a/java/fuzz_test.go
+++ b/java/fuzz_test.go
@@ -71,8 +71,8 @@ func TestJavaFuzz(t *testing.T) {
}
baz := result.ModuleForTests("baz", osCommonTarget).Rule("javac").Output.String()
- barOut := filepath.Join("out", "soong", ".intermediates", "bar", osCommonTarget, "javac", "bar.jar")
- bazOut := filepath.Join("out", "soong", ".intermediates", "baz", osCommonTarget, "javac", "baz.jar")
+ barOut := filepath.Join("out", "soong", ".intermediates", "bar", osCommonTarget, "javac-header", "bar.jar")
+ bazOut := filepath.Join("out", "soong", ".intermediates", "baz", osCommonTarget, "javac-header", "baz.jar")
android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], barOut)
android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], bazOut)
diff --git a/java/generated_java_library.go b/java/generated_java_library.go
new file mode 100644
index 000000000..f9baa85e4
--- /dev/null
+++ b/java/generated_java_library.go
@@ -0,0 +1,94 @@
+// Copyright 2023 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java
+
+import (
+ "android/soong/android"
+)
+
+type GeneratedJavaLibraryModule struct {
+ Library
+ callbacks GeneratedJavaLibraryCallbacks
+ moduleName string
+}
+
+type GeneratedJavaLibraryCallbacks interface {
+ // Called from inside DepsMutator, gives a chance to AddDependencies
+ DepsMutator(module *GeneratedJavaLibraryModule, ctx android.BottomUpMutatorContext)
+
+ // Called from inside GenerateAndroidBuildActions. Add the build rules to
+ // make the srcjar, and return the path to it.
+ GenerateSourceJarBuildActions(module *GeneratedJavaLibraryModule, ctx android.ModuleContext) android.Path
+}
+
+// GeneratedJavaLibraryModuleFactory provides a utility for modules that are generated
+// source code, including ones outside the java package to build jar files
+// from that generated source.
+//
+// To use GeneratedJavaLibraryModule, call GeneratedJavaLibraryModuleFactory with
+// a callback interface and a properties object to add to the module.
+//
+// These modules will have some properties blocked, and it will be an error if
+// modules attempt to set them. See the list of property names in GeneratedAndroidBuildActions
+// for the list of those properties.
+func GeneratedJavaLibraryModuleFactory(moduleName string, callbacks GeneratedJavaLibraryCallbacks, properties interface{}) android.Module {
+ module := &GeneratedJavaLibraryModule{
+ callbacks: callbacks,
+ moduleName: moduleName,
+ }
+ module.addHostAndDeviceProperties()
+ module.initModuleAndImport(module)
+ android.InitApexModule(module)
+ android.InitBazelModule(module)
+ InitJavaModule(module, android.HostAndDeviceSupported)
+ if properties != nil {
+ module.AddProperties(properties)
+ }
+ return module
+}
+
+func (module *GeneratedJavaLibraryModule) DepsMutator(ctx android.BottomUpMutatorContext) {
+ module.callbacks.DepsMutator(module, ctx)
+ module.Library.DepsMutator(ctx)
+}
+
+func checkPropertyEmpty(ctx android.ModuleContext, module *GeneratedJavaLibraryModule, name string, value []string) {
+ if len(value) != 0 {
+ ctx.PropertyErrorf(name, "%s not allowed on %s", name, module.moduleName)
+ }
+}
+
+func (module *GeneratedJavaLibraryModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ // These modules are all-generated, so disallow these properties to keep it simple.
+ // No additional sources
+ checkPropertyEmpty(ctx, module, "srcs", module.Library.properties.Srcs)
+ checkPropertyEmpty(ctx, module, "common_srcs", module.Library.properties.Common_srcs)
+ checkPropertyEmpty(ctx, module, "exclude_srcs", module.Library.properties.Exclude_srcs)
+ checkPropertyEmpty(ctx, module, "java_resource_dirs", module.Library.properties.Java_resource_dirs)
+ checkPropertyEmpty(ctx, module, "exclude_java_resource_dirs", module.Library.properties.Exclude_java_resource_dirs)
+ // No additional libraries. The generator should add anything necessary automatically
+ // by returning something from ____ (TODO: Additional libraries aren't needed now, so
+ // these are just blocked).
+ checkPropertyEmpty(ctx, module, "libs", module.Library.properties.Libs)
+ checkPropertyEmpty(ctx, module, "static_libs", module.Library.properties.Static_libs)
+ // Restrict these for no good reason other than to limit the surface area. If there's a
+ // good use case put them back.
+ checkPropertyEmpty(ctx, module, "plugins", module.Library.properties.Plugins)
+ checkPropertyEmpty(ctx, module, "exported_plugins", module.Library.properties.Exported_plugins)
+
+ srcJarPath := module.callbacks.GenerateSourceJarBuildActions(module, ctx)
+ module.Library.properties.Generated_srcjars = append(module.Library.properties.Generated_srcjars, srcJarPath)
+ module.Library.GenerateAndroidBuildActions(ctx)
+}
diff --git a/java/generated_java_library_test.go b/java/generated_java_library_test.go
new file mode 100644
index 000000000..7f52fd108
--- /dev/null
+++ b/java/generated_java_library_test.go
@@ -0,0 +1,66 @@
+// 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 (
+ "testing"
+
+ "android/soong/android"
+)
+
+func JavaGenLibTestFactory() android.Module {
+ callbacks := &JavaGenLibTestCallbacks{}
+ return GeneratedJavaLibraryModuleFactory("test_java_gen_lib", callbacks, &callbacks.properties)
+}
+
+type JavaGenLibTestProperties struct {
+ Foo string
+}
+
+type JavaGenLibTestCallbacks struct {
+ properties JavaGenLibTestProperties
+}
+
+func (callbacks *JavaGenLibTestCallbacks) DepsMutator(module *GeneratedJavaLibraryModule, ctx android.BottomUpMutatorContext) {
+}
+
+func (callbacks *JavaGenLibTestCallbacks) GenerateSourceJarBuildActions(module *GeneratedJavaLibraryModule, ctx android.ModuleContext) android.Path {
+ module.AddAconfigIntermediate(android.PathForOutput(ctx, "aconfig_cache_file"))
+ return android.PathForOutput(ctx, "blah.srcjar")
+}
+
+func testGenLib(t *testing.T, errorHandler android.FixtureErrorHandler, bp string) *android.TestResult {
+ return android.GroupFixturePreparers(
+ PrepareForIntegrationTestWithJava,
+ android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("test_java_gen_lib", JavaGenLibTestFactory)
+ }),
+ ).
+ ExtendWithErrorHandler(errorHandler).
+ RunTestWithBp(t, bp)
+}
+
+func TestGenLib(t *testing.T) {
+ bp := `
+ test_java_gen_lib {
+ name: "javagenlibtest",
+ foo: "bar", // Note: This won't parse if the property didn't get added
+ }
+ `
+ result := testGenLib(t, android.FixtureExpectsNoErrors, bp)
+
+ javagenlibtest := result.ModuleForTests("javagenlibtest", "android_common").Module().(*GeneratedJavaLibraryModule)
+ android.AssertPathsEndWith(t, "Generated_srcjars", []string{"/blah.srcjar"}, javagenlibtest.Library.properties.Generated_srcjars)
+}
diff --git a/java/hiddenapi.go b/java/hiddenapi.go
index d25096b15..4d08b8307 100644
--- a/java/hiddenapi.go
+++ b/java/hiddenapi.go
@@ -106,7 +106,7 @@ func (h *hiddenAPI) initHiddenAPI(ctx android.ModuleContext, dexJar OptionalDexJ
h.uncompressDexState = uncompressedDexState
// If hiddenapi processing is disabled treat this as inactive.
- if ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
+ if ctx.Config().DisableHiddenApiChecks() {
return
}
diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go
index c6176e67c..f31f5d1a8 100644
--- a/java/hiddenapi_modular.go
+++ b/java/hiddenapi_modular.go
@@ -236,9 +236,9 @@ func hiddenAPIComputeMonolithicStubLibModules(config android.Config) map[*Hidden
testStubModules = append(testStubModules, "sdk_test_current_android")
} else {
// Use stub modules built from source
- publicStubModules = append(publicStubModules, android.SdkPublic.JavaLibraryName(config))
- systemStubModules = append(systemStubModules, android.SdkSystem.JavaLibraryName(config))
- testStubModules = append(testStubModules, android.SdkTest.JavaLibraryName(config))
+ publicStubModules = append(publicStubModules, android.SdkPublic.DefaultJavaLibraryName())
+ systemStubModules = append(systemStubModules, android.SdkSystem.DefaultJavaLibraryName())
+ testStubModules = append(testStubModules, android.SdkTest.DefaultJavaLibraryName())
}
// We do not have prebuilts of the core platform api yet
corePlatformStubModules = append(corePlatformStubModules, "legacy.core.platform.api.stubs")
@@ -1236,7 +1236,6 @@ func buildRuleToGenerateRemovedDexSignatures(ctx android.ModuleContext, suffix s
rule := android.NewRuleBuilder(pctx, ctx)
rule.Command().
BuiltTool("metalava").
- Flag("--no-banner").
Inputs(removedTxtFiles).
FlagWithOutput("--dex-api ", output)
rule.Build("modular-hiddenapi-removed-dex-signatures"+suffix, "modular hiddenapi removed dex signatures"+suffix)
diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go
index 52934a327..8ec17971a 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -25,7 +25,7 @@ func init() {
}
func RegisterHiddenApiSingletonComponents(ctx android.RegistrationContext) {
- ctx.RegisterSingletonType("hiddenapi", hiddenAPISingletonFactory)
+ ctx.RegisterParallelSingletonType("hiddenapi", hiddenAPISingletonFactory)
}
var PrepareForTestWithHiddenApiBuildComponents = android.FixtureRegisterWithContext(RegisterHiddenApiSingletonComponents)
@@ -121,8 +121,8 @@ type hiddenAPISingleton struct {
// hiddenAPI singleton rules
func (h *hiddenAPISingleton) GenerateBuildActions(ctx android.SingletonContext) {
- // Don't run any hiddenapi rules if UNSAFE_DISABLE_HIDDENAPI_FLAGS=true
- if ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
+ // Don't run any hiddenapi rules if hiddenapi checks are disabled
+ if ctx.Config().DisableHiddenApiChecks() {
return
}
@@ -166,7 +166,7 @@ func isModuleInConfiguredList(ctx android.BaseModuleContext, module android.Modu
// Now match the apex part of the boot image configuration.
requiredApex := configuredBootJars.Apex(index)
- if requiredApex == "platform" || requiredApex == "system_ext" {
+ if android.IsConfiguredJarForPlatform(requiredApex) {
if len(apexInfo.InApexVariants) != 0 {
// A platform variant is required but this is for an apex so ignore it.
return false
diff --git a/java/java.go b/java/java.go
index 683e54682..f29f7383a 100644
--- a/java/java.go
+++ b/java/java.go
@@ -73,8 +73,8 @@ func registerJavaBuildComponents(ctx android.RegistrationContext) {
ctx.BottomUp("jacoco_deps", jacocoDepsMutator).Parallel()
})
- ctx.RegisterSingletonType("logtags", LogtagsSingleton)
- ctx.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory)
+ ctx.RegisterParallelSingletonType("logtags", LogtagsSingleton)
+ ctx.RegisterParallelSingletonType("kythe_java_extract", kytheExtractJavaFactory)
}
func RegisterJavaSdkMemberTypes() {
@@ -231,10 +231,10 @@ type JavaInfo struct {
HeaderJars android.Paths
// set of header jars for all transitive libs deps
- TransitiveLibsHeaderJars *android.DepSet
+ TransitiveLibsHeaderJars *android.DepSet[android.Path]
// set of header jars for all transitive static libs deps
- TransitiveStaticLibsHeaderJars *android.DepSet
+ TransitiveStaticLibsHeaderJars *android.DepSet[android.Path]
// ImplementationAndResourceJars is a list of jars that contain the implementations of classes
// in the module as well as any resources included in the module.
@@ -273,6 +273,15 @@ type JavaInfo struct {
// JacocoReportClassesFile is the path to a jar containing uninstrumented classes that will be
// instrumented by jacoco.
JacocoReportClassesFile android.Path
+
+ // set of aconfig flags for all transitive libs deps
+ // TODO(joeo): It would be nice if this were over in the aconfig package instead of here.
+ // In order to do that, generated_java_library would need a way doing
+ // collectTransitiveAconfigFiles with one of the callbacks, and having that automatically
+ // propagated. If we were to clean up more of the stuff on JavaInfo that's not part of
+ // core java rules (e.g. AidlIncludeDirs), then maybe adding more framework to do that would be
+ // worth it.
+ TransitiveAconfigFiles *android.DepSet[android.Path]
}
var JavaInfoProvider = blueprint.NewProvider(JavaInfo{})
@@ -456,7 +465,9 @@ func sdkDeps(ctx android.BottomUpMutatorContext, sdkContext android.SdkContext,
ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...)
ctx.AddVariationDependencies(nil, sdkLibTag, sdkDep.classpath...)
if d.effectiveOptimizeEnabled() && sdkDep.hasStandardLibs() {
- ctx.AddVariationDependencies(nil, proguardRaiseTag, config.LegacyCorePlatformBootclasspathLibraries...)
+ ctx.AddVariationDependencies(nil, proguardRaiseTag,
+ config.LegacyCorePlatformBootclasspathLibraries...,
+ )
}
if d.effectiveOptimizeEnabled() && sdkDep.hasFrameworkLibs() {
ctx.AddVariationDependencies(nil, proguardRaiseTag, config.FrameworkLibraries...)
@@ -672,6 +683,8 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.minSdkVersion = j.MinSdkVersion(ctx)
j.maxSdkVersion = j.MaxSdkVersion(ctx)
+ j.stem = proptools.StringDefault(j.overridableDeviceProperties.Stem, ctx.ModuleName())
+
apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
if !apexInfo.IsForPlatform() {
j.hideApexVariantFromMake = true
@@ -686,7 +699,7 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
j.classLoaderContexts = j.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
}
- j.compile(ctx, nil)
+ j.compile(ctx, nil, nil, nil)
// Collect the module directory for IDE info in java/jdeps.go.
j.modulePaths = append(j.modulePaths, ctx.ModuleDir())
@@ -724,6 +737,7 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
})
j.exportedProguardFlagFiles = android.FirstUniquePaths(j.exportedProguardFlagFiles)
+
}
func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -813,7 +827,10 @@ func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberCo
// If the min_sdk_version was set then add the canonical representation of the API level to the
// snapshot.
if j.deviceProperties.Min_sdk_version != nil {
- canonical := android.ReplaceFinalizedCodenames(ctx.SdkModuleContext().Config(), j.minSdkVersion.String())
+ canonical, err := android.ReplaceFinalizedCodenames(ctx.SdkModuleContext().Config(), j.minSdkVersion.String())
+ if err != nil {
+ ctx.ModuleErrorf("%s", err)
+ }
p.MinSdkVersion = proptools.StringPtr(canonical)
}
@@ -931,6 +948,10 @@ type TestOptions struct {
// Extra <option> tags to add to the auto generated test xml file. The "key"
// is optional in each of these.
Tradefed_options []tradefed.Option
+
+ // Extra <option> tags to add to the auto generated test xml file under the test runner, e.g., AndroidJunitTest.
+ // The "key" is optional in each of these.
+ Test_runner_options []tradefed.Option
}
type testProperties struct {
@@ -1213,6 +1234,7 @@ func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext,
TestSuites: j.testProperties.Test_suites,
Config: configs,
OptionsForAutogenerated: j.testProperties.Test_options.Tradefed_options,
+ TestRunnerOptions: j.testProperties.Test_options.Test_runner_options,
AutoGenConfig: j.testProperties.Auto_gen_config,
UnitTest: j.testProperties.Test_options.Unit_test,
DeviceTemplate: "${JavaTestConfigTemplate}",
@@ -1411,6 +1433,8 @@ func TestHostFactory() android.Module {
nil,
nil)
+ android.InitBazelModule(module)
+
InitJavaModuleMultiTargets(module, android.HostSupported)
return module
@@ -1454,6 +1478,8 @@ func (j *Binary) HostToolPath() android.OptionalPath {
}
func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ j.stem = proptools.StringDefault(j.overridableDeviceProperties.Stem, ctx.ModuleName())
+
if ctx.Arch().ArchType == android.Common {
// Compile the jar
if j.binaryProperties.Main_class != nil {
@@ -1610,13 +1636,6 @@ func (ap *JavaApiContribution) GenerateAndroidBuildActions(ctx android.ModuleCon
})
}
-type JavaApiLibraryDepsInfo struct {
- JavaInfo
- StubsSrcJar android.Path
-}
-
-var JavaApiLibraryDepsProvider = blueprint.NewProvider(JavaApiLibraryDepsInfo{})
-
type ApiLibrary struct {
android.ModuleBase
android.DefaultableModuleBase
@@ -1645,7 +1664,7 @@ type JavaApiLibraryProperties struct {
// list of api.txt files relative to this directory that contribute to the
// API surface.
// This is a list of relative paths
- Api_files []string
+ Api_files []string `android:"path"`
// List of flags to be passed to the javac compiler to generate jar file
Javacflags []string
@@ -1658,10 +1677,11 @@ type JavaApiLibraryProperties struct {
// merge zipped after metalava invocation
Static_libs []string
- // Java Api library to provide the full API surface text files and jar file.
- // If this property is set, the provided full API surface text files and
- // jar file are passed to metalava invocation.
- Dep_api_srcs *string
+ // Java Api library to provide the full API surface stub jar file.
+ // If this property is set, the stub jar of this module is created by
+ // extracting the compiled class files provided by the
+ // full_api_surface_stub module.
+ Full_api_surface_stub *string
}
func ApiLibraryFactory() android.Module {
@@ -1708,8 +1728,7 @@ func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
FlagWithArg("-encoding ", "UTF-8").
FlagWithInputList("--source-files ", srcs, " ")
- cmd.Flag("--no-banner").
- Flag("--color").
+ cmd.Flag("--color").
Flag("--quiet").
Flag("--format=v2").
Flag("--include-annotations").
@@ -1723,6 +1742,14 @@ func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
FlagWithArg("--hide ", "InvalidNullabilityOverride").
FlagWithArg("--hide ", "ChangedDefault")
+ // Force metalava to ignore classes on the classpath when an API file contains missing classes.
+ // See b/285140653 for more information.
+ cmd.FlagWithArg("--api-class-resolution ", "api")
+
+ // Force metalava to sort overloaded methods by their order in the source code.
+ // See b/285312164 for more information.
+ cmd.FlagWithArg("--api-overloaded-method-order ", "source")
+
return cmd
}
@@ -1740,35 +1767,37 @@ func (al *ApiLibrary) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBui
}
}
-// This method extracts the stub java files from the srcjar file provided from dep_api_srcs module
-// and replaces the java stubs generated by invoking metalava in this module.
+// This method extracts the stub class files from the stub jar file provided
+// from full_api_surface_stub module instead of compiling the srcjar generated from invoking metalava.
// This method is used because metalava can generate compilable from-text stubs only when
-// the codebase encompasses all classes listed in the input API text file, but a class can extend
+// the codebase encompasses all classes listed in the input API text file, and a class can extend
// a class that is not within the same API domain.
-func (al *ApiLibrary) extractApiSrcs(ctx android.ModuleContext, rule *android.RuleBuilder, stubsDir android.OptionalPath, depApiSrcsSrcJar android.Path) {
- generatedStubsList := android.PathForModuleOut(ctx, "metalava", "sources.txt")
+func (al *ApiLibrary) extractApiSrcs(ctx android.ModuleContext, rule *android.RuleBuilder, stubsDir android.OptionalPath, fullApiSurfaceStubJar android.Path) {
+ classFilesList := android.PathForModuleOut(ctx, "metalava", "classes.txt")
unzippedSrcJarDir := android.PathForModuleOut(ctx, "metalava", "unzipDir")
rule.Command().
BuiltTool("list_files").
Text(stubsDir.String()).
- FlagWithOutput("--out ", generatedStubsList).
+ FlagWithOutput("--out ", classFilesList).
FlagWithArg("--extensions ", ".java").
- FlagWithArg("--root ", unzippedSrcJarDir.String())
+ FlagWithArg("--root ", unzippedSrcJarDir.String()).
+ Flag("--classes")
rule.Command().
Text("unzip").
Flag("-q").
- Input(depApiSrcsSrcJar).
+ Input(fullApiSurfaceStubJar).
FlagWithArg("-d ", unzippedSrcJarDir.String())
rule.Command().
BuiltTool("soong_zip").
- Flag("-srcjar").
+ Flag("-jar").
Flag("-write_if_changed").
+ Flag("-ignore_missing_files").
FlagWithArg("-C ", unzippedSrcJarDir.String()).
- FlagWithInput("-l ", generatedStubsList).
- FlagWithOutput("-o ", al.stubsSrcJar)
+ FlagWithInput("-l ", classFilesList).
+ FlagWithOutput("-o ", al.stubsJarWithoutStaticLibs)
}
func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -1778,8 +1807,8 @@ func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
}
ctx.AddVariationDependencies(nil, libTag, al.properties.Libs...)
ctx.AddVariationDependencies(nil, staticLibTag, al.properties.Static_libs...)
- if al.properties.Dep_api_srcs != nil {
- ctx.AddVariationDependencies(nil, depApiSrcsTag, String(al.properties.Dep_api_srcs))
+ if al.properties.Full_api_surface_stub != nil {
+ ctx.AddVariationDependencies(nil, depApiSrcsTag, String(al.properties.Full_api_surface_stub))
}
}
@@ -1801,14 +1830,14 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
var srcFiles android.Paths
var classPaths android.Paths
var staticLibs android.Paths
- var depApiSrcsStubsSrcJar android.Path
+ var depApiSrcsStubsJar android.Path
ctx.VisitDirectDeps(func(dep android.Module) {
tag := ctx.OtherModuleDependencyTag(dep)
switch tag {
case javaApiContributionTag:
provider := ctx.OtherModuleProvider(dep, JavaApiImportProvider).(JavaApiImportInfo)
providerApiFile := provider.ApiFile
- if providerApiFile == nil {
+ if providerApiFile == nil && !ctx.Config().AllowMissingDependencies() {
ctx.ModuleErrorf("Error: %s has an empty api file.", dep.Name())
}
srcFiles = append(srcFiles, android.PathForSource(ctx, providerApiFile.String()))
@@ -1819,20 +1848,17 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
provider := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo)
staticLibs = append(staticLibs, provider.HeaderJars...)
case depApiSrcsTag:
- provider := ctx.OtherModuleProvider(dep, JavaApiLibraryDepsProvider).(JavaApiLibraryDepsInfo)
- classPaths = append(classPaths, provider.HeaderJars...)
- depApiSrcsStubsSrcJar = provider.StubsSrcJar
+ provider := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo)
+ depApiSrcsStubsJar = provider.HeaderJars[0]
}
})
// Add the api_files inputs
for _, api := range al.properties.Api_files {
- // Use MaybeExistentPathForSource since the api file might not exist during analysis.
- // This will be provided by the orchestrator in the combined execution.
- srcFiles = append(srcFiles, android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), api))
+ srcFiles = append(srcFiles, android.PathForModuleSrc(ctx, api))
}
- if srcFiles == nil {
+ if srcFiles == nil && !ctx.Config().AllowMissingDependencies() {
ctx.ModuleErrorf("Error: %s has an empty api file.", ctx.ModuleName())
}
@@ -1841,31 +1867,33 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
al.stubsFlags(ctx, cmd, stubsDir)
al.stubsSrcJar = android.PathForModuleOut(ctx, "metalava", ctx.ModuleName()+"-"+"stubs.srcjar")
+ al.stubsJarWithoutStaticLibs = android.PathForModuleOut(ctx, "metalava", "stubs.jar")
+ al.stubsJar = android.PathForModuleOut(ctx, ctx.ModuleName(), fmt.Sprintf("%s.jar", ctx.ModuleName()))
- if depApiSrcsStubsSrcJar != nil {
- al.extractApiSrcs(ctx, rule, stubsDir, depApiSrcsStubsSrcJar)
- } else {
- rule.Command().
- BuiltTool("soong_zip").
- Flag("-write_if_changed").
- Flag("-jar").
- FlagWithOutput("-o ", al.stubsSrcJar).
- FlagWithArg("-C ", stubsDir.String()).
- FlagWithArg("-D ", stubsDir.String())
+ if depApiSrcsStubsJar != nil {
+ al.extractApiSrcs(ctx, rule, stubsDir, depApiSrcsStubsJar)
}
+ rule.Command().
+ BuiltTool("soong_zip").
+ Flag("-write_if_changed").
+ Flag("-jar").
+ FlagWithOutput("-o ", al.stubsSrcJar).
+ FlagWithArg("-C ", stubsDir.String()).
+ FlagWithArg("-D ", stubsDir.String())
rule.Build("metalava", "metalava merged")
- al.stubsJarWithoutStaticLibs = android.PathForModuleOut(ctx, ctx.ModuleName(), "stubs.jar")
- al.stubsJar = android.PathForModuleOut(ctx, ctx.ModuleName(), fmt.Sprintf("%s.jar", ctx.ModuleName()))
+ if depApiSrcsStubsJar == nil {
+ var flags javaBuilderFlags
+ flags.javaVersion = getStubsJavaVersion()
+ flags.javacFlags = strings.Join(al.properties.Javacflags, " ")
+ flags.classpath = classpath(classPaths)
- var flags javaBuilderFlags
- flags.javaVersion = getStubsJavaVersion()
- flags.javacFlags = strings.Join(al.properties.Javacflags, " ")
- flags.classpath = classpath(classPaths)
+ annoSrcJar := android.PathForModuleOut(ctx, ctx.ModuleName(), "anno.srcjar")
- TransformJavaToClasses(ctx, al.stubsJarWithoutStaticLibs, 0, android.Paths{},
- android.Paths{al.stubsSrcJar}, flags, android.Paths{})
+ TransformJavaToClasses(ctx, al.stubsJarWithoutStaticLibs, 0, android.Paths{},
+ android.Paths{al.stubsSrcJar}, annoSrcJar, flags, android.Paths{})
+ }
builder := android.NewRuleBuilder(pctx, ctx)
builder.Command().
@@ -1896,13 +1924,7 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
ImplementationAndResourcesJars: android.PathsIfNonNil(al.stubsJar),
ImplementationJars: android.PathsIfNonNil(al.stubsJar),
AidlIncludeDirs: android.Paths{},
- })
-
- ctx.SetProvider(JavaApiLibraryDepsProvider, JavaApiLibraryDepsInfo{
- JavaInfo: JavaInfo{
- HeaderJars: android.PathsIfNonNil(al.stubsJar),
- },
- StubsSrcJar: al.stubsSrcJar,
+ // No aconfig libraries on api libraries
})
}
@@ -2224,6 +2246,7 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedClasspathFile),
ImplementationJars: android.PathsIfNonNil(j.combinedClasspathFile),
AidlIncludeDirs: j.exportAidlIncludeDirs,
+ // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
})
}
@@ -2603,6 +2626,7 @@ func DefaultsFactory() android.Module {
&appProperties{},
&appTestProperties{},
&overridableAppProperties{},
+ &hostTestProperties{},
&testProperties{},
&ImportProperties{},
&AARImportProperties{},
@@ -2643,7 +2667,7 @@ func (ks *kytheExtractJavaSingleton) GenerateBuildActions(ctx android.SingletonC
var Bool = proptools.Bool
var BoolDefault = proptools.BoolDefault
var String = proptools.String
-var inList = android.InList
+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,
@@ -2700,11 +2724,29 @@ type javaResourcesAttributes struct {
Resource_strip_prefix *string
}
+func (m *Library) javaResourcesGetSingleFilegroupStripPrefix(ctx android.TopDownMutatorContext) (string, bool) {
+ if otherM, ok := ctx.ModuleFromName(m.properties.Java_resources[0]); ok && len(m.properties.Java_resources) == 1 {
+ if fg, isFilegroup := otherM.(android.FileGroupPath); isFilegroup {
+ return filepath.Join(ctx.OtherModuleDir(otherM), fg.GetPath(ctx)), true
+ }
+ }
+ return "", false
+}
+
func (m *Library) convertJavaResourcesAttributes(ctx android.TopDownMutatorContext) *javaResourcesAttributes {
var resources bazel.LabelList
var resourceStripPrefix *string
+ if m.properties.Java_resources != nil && len(m.properties.Java_resource_dirs) > 0 {
+ ctx.ModuleErrorf("bp2build doesn't support both java_resources and java_resource_dirs being set on the same module.")
+ }
+
if m.properties.Java_resources != nil {
+ if prefix, ok := m.javaResourcesGetSingleFilegroupStripPrefix(ctx); ok {
+ resourceStripPrefix = proptools.StringPtr(prefix)
+ } else {
+ resourceStripPrefix = proptools.StringPtr(ctx.ModuleDir())
+ }
resources.Append(android.BazelLabelForModuleSrc(ctx, m.properties.Java_resources))
}
@@ -2739,11 +2781,12 @@ func (m *Library) convertJavaResourcesAttributes(ctx android.TopDownMutatorConte
type javaCommonAttributes struct {
*javaResourcesAttributes
*kotlinAttributes
- Srcs bazel.LabelListAttribute
- Plugins bazel.LabelListAttribute
- Javacopts bazel.StringListAttribute
- Sdk_version bazel.StringAttribute
- Java_version bazel.StringAttribute
+ Srcs bazel.LabelListAttribute
+ Plugins bazel.LabelListAttribute
+ Javacopts bazel.StringListAttribute
+ Sdk_version bazel.StringAttribute
+ Java_version bazel.StringAttribute
+ Errorprone_force_enable bazel.BoolAttribute
}
type javaDependencyLabels struct {
@@ -2776,6 +2819,10 @@ type bp2BuildJavaInfo struct {
hasKotlin bool
}
+func javaXsdTargetName(xsd android.XsdConfigBp2buildTargets) string {
+ return xsd.JavaBp2buildTargetName()
+}
+
// convertLibraryAttrsBp2Build returns a javaCommonAttributes struct with
// converted attributes shared across java_* modules and a bp2BuildJavaInfo struct
// which has other non-attribute information needed for bp2build conversion
@@ -2784,7 +2831,7 @@ type bp2BuildJavaInfo struct {
func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) (*javaCommonAttributes, *bp2BuildJavaInfo) {
var srcs bazel.LabelListAttribute
var deps bazel.LabelListAttribute
- var staticDeps bazel.LabelList
+ var staticDeps bazel.LabelListAttribute
archVariantProps := m.GetArchVariantProperties(ctx, &CommonProperties{})
for axis, configToProps := range archVariantProps {
@@ -2799,6 +2846,7 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext)
javaSrcPartition := "java"
protoSrcPartition := "proto"
+ xsdSrcPartition := "xsd"
logtagSrcPartition := "logtag"
aidlSrcPartition := "aidl"
kotlinPartition := "kotlin"
@@ -2807,6 +2855,7 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext)
logtagSrcPartition: bazel.LabelPartition{Extensions: []string{".logtags", ".logtag"}},
protoSrcPartition: android.ProtoSrcLabelPartition,
aidlSrcPartition: android.AidlSrcLabelPartition,
+ xsdSrcPartition: bazel.LabelPartition{LabelMapper: android.XsdLabelMapper(javaXsdTargetName)},
kotlinPartition: bazel.LabelPartition{Extensions: []string{".kt"}},
})
@@ -2814,6 +2863,8 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext)
kotlinSrcs := srcPartitions[kotlinPartition]
javaSrcs.Append(kotlinSrcs)
+ staticDeps.Append(srcPartitions[xsdSrcPartition])
+
if !srcPartitions[logtagSrcPartition].IsEmpty() {
logtagsLibName := m.Name() + "_logtags"
ctx.CreateBazelTargetModule(
@@ -2836,7 +2887,7 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext)
return android.IsConvertedToAidlLibrary(ctx, src.OriginalModuleName)
})
- apexAvailableTags := android.ApexAvailableTags(ctx.Module())
+ apexAvailableTags := android.ApexAvailableTagsWithoutTestApexes(ctx, ctx.Module())
if !aidlSrcs.IsEmpty() {
aidlLibName := m.Name() + "_aidl_library"
@@ -2867,29 +2918,38 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext)
},
)
- staticDeps.Add(&bazel.Label{Label: ":" + javaAidlLibName})
+ staticDeps.Append(bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + javaAidlLibName}))
}
- var javacopts []string
+ var javacopts bazel.StringListAttribute //[]string
+ plugins := bazel.MakeLabelListAttribute(
+ android.BazelLabelForModuleDeps(ctx, m.properties.Plugins),
+ )
if m.properties.Javacflags != nil {
- javacopts = append(javacopts, m.properties.Javacflags...)
+ javacopts = bazel.MakeStringListAttribute(m.properties.Javacflags)
}
epEnabled := m.properties.Errorprone.Enabled
- //TODO(b/227504307) add configuration that depends on RUN_ERROR_PRONE environment variable
- if Bool(epEnabled) {
- javacopts = append(javacopts, m.properties.Errorprone.Javacflags...)
+ epJavacflags := m.properties.Errorprone.Javacflags
+ var errorproneForceEnable bazel.BoolAttribute
+ if epEnabled == nil {
+ //TODO(b/227504307) add configuration that depends on RUN_ERROR_PRONE environment variable
+ } else if *epEnabled {
+ plugins.Append(bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, m.properties.Errorprone.Extra_check_modules)))
+ javacopts.Append(bazel.MakeStringListAttribute(epJavacflags))
+ errorproneForceEnable.Value = epEnabled
+ } else {
+ javacopts.Append(bazel.MakeStringListAttribute([]string{"-XepDisableAllChecks"}))
}
commonAttrs := &javaCommonAttributes{
Srcs: javaSrcs,
javaResourcesAttributes: m.convertJavaResourcesAttributes(ctx),
- Plugins: bazel.MakeLabelListAttribute(
- android.BazelLabelForModuleDeps(ctx, m.properties.Plugins),
- ),
- Javacopts: bazel.MakeStringListAttribute(javacopts),
- Java_version: bazel.StringAttribute{Value: m.properties.Java_version},
- Sdk_version: bazel.StringAttribute{Value: m.deviceProperties.Sdk_version},
+ Plugins: plugins,
+ Javacopts: javacopts,
+ Java_version: bazel.StringAttribute{Value: m.properties.Java_version},
+ Sdk_version: bazel.StringAttribute{Value: m.deviceProperties.Sdk_version},
+ Errorprone_force_enable: errorproneForceEnable,
}
for axis, configToProps := range archVariantProps {
@@ -2913,7 +2973,9 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext)
// by protoc are included directly in the resulting JAR. Thus upstream dependencies
// that depend on a java_library with proto sources can link directly to the protobuf API,
// and so this should be a static dependency.
- staticDeps.Add(protoDepLabel)
+ if protoDepLabel != nil {
+ staticDeps.Append(bazel.MakeSingleLabelListAttribute(*protoDepLabel))
+ }
depLabels := &javaDependencyLabels{}
depLabels.Deps = deps
@@ -2928,7 +2990,7 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext)
}
}
}
- depLabels.StaticDeps.Value.Append(staticDeps)
+ depLabels.StaticDeps.Append(staticDeps)
hasKotlin := !kotlinSrcs.IsEmpty()
commonAttrs.kotlinAttributes = &kotlinAttributes{
@@ -2962,14 +3024,14 @@ type kotlinAttributes struct {
func ktJvmLibraryBazelTargetModuleProperties() bazel.BazelTargetModuleProperties {
return bazel.BazelTargetModuleProperties{
Rule_class: "kt_jvm_library",
- Bzl_load_location: "//build/bazel/rules/kotlin:rules.bzl",
+ Bzl_load_location: "//build/bazel/rules/kotlin:kt_jvm_library.bzl",
}
}
func javaLibraryBazelTargetModuleProperties() bazel.BazelTargetModuleProperties {
return bazel.BazelTargetModuleProperties{
Rule_class: "java_library",
- Bzl_load_location: "//build/bazel/rules/java:rules.bzl",
+ Bzl_load_location: "//build/bazel/rules/java:library.bzl",
}
}
@@ -3052,24 +3114,15 @@ func javaBinaryHostBp2Build(ctx android.TopDownMutatorContext, m *Binary) {
// Attribute jvm_flags
var jvmFlags bazel.StringListAttribute
if m.binaryProperties.Jni_libs != nil {
- jniLibPackages := map[string]bool{}
- for _, jniLibLabel := range android.BazelLabelForModuleDeps(ctx, m.binaryProperties.Jni_libs).Includes {
- jniLibPackage := jniLibLabel.Label
- indexOfColon := strings.Index(jniLibLabel.Label, ":")
- if indexOfColon > 0 {
- // JNI lib from other package
- jniLibPackage = jniLibLabel.Label[2:indexOfColon]
- } else if indexOfColon == 0 {
- // JNI lib in the same package of java_binary
- packageOfCurrentModule := m.GetBazelLabel(ctx, m)
- jniLibPackage = packageOfCurrentModule[2:strings.Index(packageOfCurrentModule, ":")]
- }
- if _, inMap := jniLibPackages[jniLibPackage]; !inMap {
- jniLibPackages[jniLibPackage] = true
+ jniLibPackages := []string{}
+ for _, jniLib := range m.binaryProperties.Jni_libs {
+ if jniLibModule, exists := ctx.ModuleFromName(jniLib); exists {
+ otherDir := ctx.OtherModuleDir(jniLibModule)
+ jniLibPackages = append(jniLibPackages, filepath.Join(otherDir, jniLib))
}
}
jniLibPaths := []string{}
- for jniLibPackage, _ := range jniLibPackages {
+ for _, jniLibPackage := range jniLibPackages {
// See cs/f:.*/third_party/bazel/.*java_stub_template.txt for the use of RUNPATH
jniLibPaths = append(jniLibPaths, "$${RUNPATH}"+jniLibPackage)
}
@@ -3078,7 +3131,7 @@ func javaBinaryHostBp2Build(ctx android.TopDownMutatorContext, m *Binary) {
props := bazel.BazelTargetModuleProperties{
Rule_class: "java_binary",
- Bzl_load_location: "//build/bazel/rules/java:rules.bzl",
+ Bzl_load_location: "@rules_java//java:defs.bzl",
}
binAttrs := &javaBinaryHostAttributes{
Runtime_deps: runtimeDeps,
@@ -3092,23 +3145,92 @@ func javaBinaryHostBp2Build(ctx android.TopDownMutatorContext, m *Binary) {
return
}
- libName := m.Name() + "_lib"
+ libInfo := libraryCreationInfo{
+ deps: deps,
+ attrs: commonAttrs,
+ baseName: m.Name(),
+ hasKotlin: bp2BuildInfo.hasKotlin,
+ }
+ libName := createLibraryTarget(ctx, libInfo)
+ binAttrs.Runtime_deps.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + libName}})
+
+ // Create the BazelTargetModule.
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, binAttrs)
+}
+
+type javaTestHostAttributes struct {
+ *javaCommonAttributes
+ Srcs bazel.LabelListAttribute
+ Deps bazel.LabelListAttribute
+ Runtime_deps bazel.LabelListAttribute
+}
+
+// javaTestHostBp2Build is for java_test_host bp2build.
+func javaTestHostBp2Build(ctx android.TopDownMutatorContext, m *TestHost) {
+ commonAttrs, bp2BuildInfo := m.convertLibraryAttrsBp2Build(ctx)
+ depLabels := bp2BuildInfo.DepLabels
+
+ deps := depLabels.Deps
+ deps.Append(depLabels.StaticDeps)
+
+ var runtimeDeps bazel.LabelListAttribute
+ attrs := &javaTestHostAttributes{
+ Runtime_deps: runtimeDeps,
+ }
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "java_test",
+ Bzl_load_location: "//build/bazel/rules/java:test.bzl",
+ }
+
+ if commonAttrs.Srcs.IsEmpty() {
+ // if there are no sources, then the dependencies can only be used at runtime
+ attrs.Runtime_deps = deps
+ attrs.javaCommonAttributes = commonAttrs
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs)
+ return
+ }
+
+ libInfo := libraryCreationInfo{
+ deps: deps,
+ attrs: commonAttrs,
+ baseName: m.Name(),
+ hasKotlin: bp2BuildInfo.hasKotlin,
+ }
+ libName := createLibraryTarget(ctx, libInfo)
+
+ attrs.Srcs = commonAttrs.Srcs
+ attrs.Deps = deps
+ attrs.Runtime_deps.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + libName}})
+ // Create the BazelTargetModule.
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs)
+}
+
+// libraryCreationInfo encapsulates the info needed to create java_library target from
+// java_binary_host or java_test_host.
+type libraryCreationInfo struct {
+ deps bazel.LabelListAttribute
+ attrs *javaCommonAttributes
+ baseName string
+ hasKotlin bool
+}
+
+// helper function that creates java_library target from java_binary_host or java_test_host,
+// and returns the library target name,
+func createLibraryTarget(ctx android.TopDownMutatorContext, libInfo libraryCreationInfo) string {
+ libName := libInfo.baseName + "_lib"
var libProps bazel.BazelTargetModuleProperties
- if bp2BuildInfo.hasKotlin {
+ if libInfo.hasKotlin {
libProps = ktJvmLibraryBazelTargetModuleProperties()
} else {
libProps = javaLibraryBazelTargetModuleProperties()
}
libAttrs := &javaLibraryAttributes{
- Deps: deps,
- javaCommonAttributes: commonAttrs,
+ Deps: libInfo.deps,
+ javaCommonAttributes: libInfo.attrs,
}
ctx.CreateBazelTargetModule(libProps, android.CommonAttributes{Name: libName}, libAttrs)
- binAttrs.Runtime_deps.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + libName}})
-
- // Create the BazelTargetModule.
- ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, binAttrs)
+ return libName
}
type bazelJavaImportAttributes struct {
@@ -3134,7 +3256,7 @@ func (i *Import) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
}
props := bazel.BazelTargetModuleProperties{
Rule_class: "java_import",
- Bzl_load_location: "//build/bazel/rules/java:rules.bzl",
+ Bzl_load_location: "//build/bazel/rules/java:import.bzl",
}
name := android.RemoveOptionalPrebuiltPrefix(i.Name())
@@ -3191,7 +3313,8 @@ func (i *Import) ProcessBazelQueryResponse(ctx android.ModuleContext) {
HeaderJars: android.PathsIfNonNil(i.combinedClasspathFile),
ImplementationAndResourcesJars: android.PathsIfNonNil(i.combinedClasspathFile),
ImplementationJars: android.PathsIfNonNil(i.combinedClasspathFile),
- //TODO(b/240308299) include AIDL information from Bazel
+ // TODO(b/240308299) include AIDL information from Bazel
+ // TODO: aconfig files?
})
i.maybeInstall(ctx, jarName, outputFile)
diff --git a/java/java_test.go b/java/java_test.go
index 2a4913ecd..dd9867704 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -2208,7 +2208,7 @@ func TestJavaApiLibraryStaticLibsLink(t *testing.T) {
}
}
-func TestJavaApiLibraryDepApiSrcs(t *testing.T) {
+func TestJavaApiLibraryFullApiSurfaceStub(t *testing.T) {
provider_bp_a := `
java_api_contribution {
name: "foo1",
@@ -2234,7 +2234,7 @@ func TestJavaApiLibraryDepApiSrcs(t *testing.T) {
name: "bar1",
api_surface: "public",
api_contributions: ["foo1"],
- dep_api_srcs: "lib1",
+ full_api_surface_stub: "lib1",
}
`,
map[string][]byte{
@@ -2247,9 +2247,30 @@ func TestJavaApiLibraryDepApiSrcs(t *testing.T) {
manifest := m.Output("metalava.sbox.textproto")
sboxProto := android.RuleBuilderSboxProtoForTests(t, manifest)
manifestCommand := sboxProto.Commands[0].GetCommand()
+ android.AssertStringDoesContain(t, "Command expected to contain full_api_surface_stub output jar", manifestCommand, "lib1.jar")
+}
+
+func TestJavaApiLibraryFilegroupInput(t *testing.T) {
+ ctx, _ := testJavaWithFS(t, `
+ filegroup {
+ name: "default_current.txt",
+ srcs: ["current.txt"],
+ }
- android.AssertStringDoesContain(t, "Command expected to contain module srcjar file", manifestCommand, "bar1-stubs.srcjar")
- android.AssertStringDoesContain(t, "Command expected to contain output files list text file flag", manifestCommand, "--out __SBOX_SANDBOX_DIR__/out/sources.txt")
+ java_api_library {
+ name: "foo",
+ api_files: [":default_current.txt"],
+ }
+ `,
+ map[string][]byte{
+ "current.txt": nil,
+ })
+
+ m := ctx.ModuleForTests("foo", "android_common")
+ outputs := fmt.Sprint(m.AllOutputs())
+ if !strings.Contains(outputs, "foo/foo.jar") {
+ t.Errorf("Module output does not contain expected jar %s", "foo/foo.jar")
+ }
}
func TestTradefedOptions(t *testing.T) {
@@ -2275,3 +2296,77 @@ java_test_host {
t.Errorf("Expected args[\"extraConfigs\"] to equal %q, was %q", expected, args["extraConfigs"])
}
}
+
+func TestTestRunnerOptions(t *testing.T) {
+ result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, `
+java_test_host {
+ name: "foo",
+ test_options: {
+ test_runner_options: [
+ {
+ name: "test-timeout",
+ value: "10m"
+ }
+ ]
+ }
+}
+`)
+
+ buildOS := result.Config.BuildOS.String()
+ args := result.ModuleForTests("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 {
+ t.Errorf("Expected args[\"extraTestRunnerConfigs\"] to equal %q, was %q", expected, args["extraTestRunnerConfigs"])
+ }
+}
+
+func TestJavaExcludeStaticLib(t *testing.T) {
+ ctx, _ := testJava(t, `
+ java_library {
+ name: "bar",
+ }
+ java_library {
+ name: "foo",
+ }
+ java_library {
+ name: "baz",
+ static_libs: [
+ "foo",
+ "bar",
+ ],
+ exclude_static_libs: [
+ "bar",
+ ],
+ }
+ `)
+
+ // "bar" not included as dependency of "baz"
+ CheckModuleDependencies(t, ctx, "baz", "android_common", []string{
+ `core-lambda-stubs`,
+ `ext`,
+ `foo`,
+ `framework`,
+ `stable-core-platform-api-stubs-system-modules`,
+ `stable.core.platform.api.stubs`,
+ })
+}
+
+func TestJavaLibraryWithResourcesStem(t *testing.T) {
+ ctx, _ := testJavaWithFS(t, `
+ java_library {
+ name: "foo",
+ java_resource_dirs: ["test-jar"],
+ stem: "test",
+ }
+ `,
+ map[string][]byte{
+ "test-jar/test/resource.txt": nil,
+ })
+
+ m := ctx.ModuleForTests("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")
+ }
+}
diff --git a/java/jdeps.go b/java/jdeps.go
index a52b86708..4c8c11c5d 100644
--- a/java/jdeps.go
+++ b/java/jdeps.go
@@ -26,7 +26,7 @@ import (
// called. Dependency info file is generated in $OUT/module_bp_java_depend.json.
func init() {
- android.RegisterSingletonType("jdeps_generator", jDepsGeneratorSingleton)
+ android.RegisterParallelSingletonType("jdeps_generator", jDepsGeneratorSingleton)
}
func jDepsGeneratorSingleton() android.Singleton {
diff --git a/java/kotlin.go b/java/kotlin.go
index 9bff5ea01..3637e2e71 100644
--- a/java/kotlin.go
+++ b/java/kotlin.go
@@ -30,7 +30,7 @@ var kotlinc = pctx.AndroidRemoteStaticRule("kotlinc", android.RemoteRuleSupports
blueprint.RuleParams{
Command: `rm -rf "$classesDir" "$headerClassesDir" "$srcJarDir" "$kotlinBuildFile" "$emptyDir" && ` +
`mkdir -p "$classesDir" "$headerClassesDir" "$srcJarDir" "$emptyDir" && ` +
- `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
+ `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" -f "*.kt" $srcJars && ` +
`${config.GenKotlinBuildFileCmd} --classpath "$classpath" --name "$name"` +
` --out_dir "$classesDir" --srcs "$out.rsp" --srcs "$srcJarDir/list"` +
` $commonSrcFilesArg --out "$kotlinBuildFile" && ` +
@@ -42,7 +42,7 @@ var kotlinc = pctx.AndroidRemoteStaticRule("kotlinc", android.RemoteRuleSupports
` -P plugin:org.jetbrains.kotlin.jvm.abi:outputDir=$headerClassesDir && ` +
`${config.SoongZipCmd} -jar -o $out -C $classesDir -D $classesDir -write_if_changed && ` +
`${config.SoongZipCmd} -jar -o $headerJar -C $headerClassesDir -D $headerClassesDir -write_if_changed && ` +
- `rm -rf "$srcJarDir"`,
+ `rm -rf "$srcJarDir" "$classesDir" "$headerClassesDir"`,
CommandDeps: []string{
"${config.KotlincCmd}",
"${config.KotlinCompilerJar}",
diff --git a/java/lint.go b/java/lint.go
index 40ef48416..f84f1c065 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -117,18 +117,18 @@ type LintDepSetsIntf interface {
}
type LintDepSets struct {
- HTML, Text, XML *android.DepSet
+ HTML, Text, XML *android.DepSet[android.Path]
}
type LintDepSetsBuilder struct {
- HTML, Text, XML *android.DepSetBuilder
+ HTML, Text, XML *android.DepSetBuilder[android.Path]
}
func NewLintDepSetBuilder() LintDepSetsBuilder {
return LintDepSetsBuilder{
- HTML: android.NewDepSetBuilder(android.POSTORDER),
- Text: android.NewDepSetBuilder(android.POSTORDER),
- XML: android.NewDepSetBuilder(android.POSTORDER),
+ HTML: android.NewDepSetBuilder[android.Path](android.POSTORDER),
+ Text: android.NewDepSetBuilder[android.Path](android.POSTORDER),
+ XML: android.NewDepSetBuilder[android.Path](android.POSTORDER),
}
}
@@ -553,9 +553,9 @@ func (l *linter) lint(ctx android.ModuleContext) {
}
func BuildModuleLintReportZips(ctx android.ModuleContext, depSets LintDepSets) android.Paths {
- htmlList := depSets.HTML.ToSortedList()
- textList := depSets.Text.ToSortedList()
- xmlList := depSets.XML.ToSortedList()
+ htmlList := android.SortedUniquePaths(depSets.HTML.ToList())
+ textList := android.SortedUniquePaths(depSets.Text.ToList())
+ xmlList := android.SortedUniquePaths(depSets.XML.ToList())
if len(htmlList) == 0 && len(textList) == 0 && len(xmlList) == 0 {
return nil
@@ -705,7 +705,7 @@ func (l *lintSingleton) MakeVars(ctx android.MakeVarsContext) {
var _ android.SingletonMakeVarsProvider = (*lintSingleton)(nil)
func init() {
- android.RegisterSingletonType("lint",
+ android.RegisterParallelSingletonType("lint",
func() android.Singleton { return &lintSingleton{} })
registerLintBuildComponents(android.InitRegistrationContext)
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index 07fb92cfe..ade739552 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -26,7 +26,7 @@ func init() {
}
func registerPlatformBootclasspathBuildComponents(ctx android.RegistrationContext) {
- ctx.RegisterSingletonModuleType("platform_bootclasspath", platformBootclasspathFactory)
+ ctx.RegisterParallelSingletonModuleType("platform_bootclasspath", platformBootclasspathFactory)
}
// The tags used for the dependencies between the platform bootclasspath and any configured boot
@@ -113,7 +113,7 @@ func (b *platformBootclasspathModule) DepsMutator(ctx android.BottomUpMutatorCon
}
func (b *platformBootclasspathModule) hiddenAPIDepsMutator(ctx android.BottomUpMutatorContext) {
- if ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
+ if ctx.Config().DisableHiddenApiChecks() {
return
}
@@ -123,15 +123,15 @@ func (b *platformBootclasspathModule) hiddenAPIDepsMutator(ctx android.BottomUpM
}
func (b *platformBootclasspathModule) BootclasspathDepsMutator(ctx android.BottomUpMutatorContext) {
- // Add dependencies on all the modules configured in the "art" boot image.
- artImageConfig := genBootImageConfigs(ctx)[artBootImageName]
- addDependenciesOntoBootImageModules(ctx, artImageConfig.modules, platformBootclasspathArtBootJarDepTag)
+ // Add dependencies on all the ART jars.
+ global := dexpreopt.GetGlobalConfig(ctx)
+ addDependenciesOntoBootImageModules(ctx, global.ArtApexJars, platformBootclasspathArtBootJarDepTag)
- // Add dependencies on all the non-updatable module configured in the "boot" boot image. That does
- // not include modules configured in the "art" boot image.
+ // Add dependencies on all the non-updatable jars, which are on the platform or in non-updatable
+ // APEXes.
addDependenciesOntoBootImageModules(ctx, b.platformJars(ctx), platformBootclasspathBootJarDepTag)
- // Add dependencies on all the apex jars.
+ // Add dependencies on all the updatable jars, except the ART jars.
apexJars := dexpreopt.GetGlobalConfig(ctx).ApexBootJars
addDependenciesOntoBootImageModules(ctx, apexJars, platformBootclasspathApexBootJarDepTag)
@@ -186,7 +186,6 @@ func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.Mo
bootDexJarByModule := b.generateHiddenAPIBuildActions(ctx, b.configuredModules, b.fragments)
buildRuleForBootJarsPackageCheck(ctx, bootDexJarByModule)
- b.generateBootImageBuildActions(ctx)
b.copyApexBootJarsForAppsDexpreopt(ctx, apexModules)
}
@@ -218,7 +217,8 @@ func (b *platformBootclasspathModule) configuredJars(ctx android.ModuleContext)
}
func (b *platformBootclasspathModule) platformJars(ctx android.PathContext) android.ConfiguredJarList {
- return defaultBootImageConfig(ctx).modules.RemoveList(artBootImageConfig(ctx).modules)
+ global := dexpreopt.GetGlobalConfig(ctx)
+ return global.BootJars.RemoveList(global.ArtApexJars)
}
// checkPlatformModules ensures that the non-updatable modules supplied are not part of an
@@ -275,10 +275,10 @@ func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.
bootDexJarByModule := extractBootDexJarsFromModules(ctx, modules)
- // Don't run any hiddenapi rules if UNSAFE_DISABLE_HIDDENAPI_FLAGS=true. This is a performance
+ // Don't run any hiddenapi rules if hidden api checks are disabled. This is a performance
// optimization that can be used to reduce the incremental build time but as its name suggests it
// can be unsafe to use, e.g. when the changes affect anything that goes on the bootclasspath.
- if ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
+ if ctx.Config().DisableHiddenApiChecks() {
paths := android.OutputPaths{b.hiddenAPIFlagsCSV, b.hiddenAPIIndexCSV, b.hiddenAPIMetadataCSV}
for _, path := range paths {
ctx.Build(pctx, android.BuildParams{
@@ -399,78 +399,9 @@ func (b *platformBootclasspathModule) generateHiddenApiMakeVars(ctx android.Make
ctx.Strict("INTERNAL_PLATFORM_HIDDENAPI_FLAGS", b.hiddenAPIFlagsCSV.String())
}
-// generateBootImageBuildActions generates ninja rules related to the boot image creation.
-func (b *platformBootclasspathModule) generateBootImageBuildActions(ctx android.ModuleContext) {
- // Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars
- // GenerateSingletonBuildActions method as it cannot create it for itself.
- dexpreopt.GetGlobalSoongConfig(ctx)
-
- global := dexpreopt.GetGlobalConfig(ctx)
- if !shouldBuildBootImages(ctx.Config(), global) {
- return
- }
-
- frameworkBootImageConfig := defaultBootImageConfig(ctx)
- bootFrameworkProfileRule(ctx, frameworkBootImageConfig)
- b.generateBootImage(ctx, frameworkBootImageName)
- b.generateBootImage(ctx, mainlineBootImageName)
- dumpOatRules(ctx, frameworkBootImageConfig)
-}
-
-func (b *platformBootclasspathModule) generateBootImage(ctx android.ModuleContext, imageName string) {
- imageConfig := genBootImageConfigs(ctx)[imageName]
-
- modules := b.getModulesForImage(ctx, imageConfig)
-
- // Copy module dex jars to their predefined locations.
- bootDexJarsByModule := extractEncodedDexJarsFromModules(ctx, modules)
- copyBootJarsToPredefinedLocations(ctx, bootDexJarsByModule, imageConfig.dexPathsByModule)
-
- // Build a profile for the image config and then use that to build the boot image.
- profile := bootImageProfileRule(ctx, imageConfig)
-
- // If dexpreopt of boot image jars should be skipped, generate only a profile.
- global := dexpreopt.GetGlobalConfig(ctx)
- if global.DisablePreoptBootImages {
- return
- }
-
- // Build boot image files for the android variants.
- androidBootImageFiles := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile)
-
- // Zip the android variant boot image files up.
- buildBootImageZipInPredefinedLocation(ctx, imageConfig, androidBootImageFiles.byArch)
-
- // Build boot image files for the host variants. There are use directly by ART host side tests.
- buildBootImageVariantsForBuildOs(ctx, imageConfig, profile)
-}
-
// Copy apex module dex jars to their predefined locations. They will be used for dexpreopt for apps.
func (b *platformBootclasspathModule) copyApexBootJarsForAppsDexpreopt(ctx android.ModuleContext, apexModules []android.Module) {
config := GetApexBootConfig(ctx)
apexBootDexJarsByModule := extractEncodedDexJarsFromModules(ctx, apexModules)
copyBootJarsToPredefinedLocations(ctx, apexBootDexJarsByModule, config.dexPathsByModule)
}
-
-func (b *platformBootclasspathModule) getModulesForImage(ctx android.ModuleContext, imageConfig *bootImageConfig) []android.Module {
- modules := make([]android.Module, 0, imageConfig.modules.Len())
- for i := 0; i < imageConfig.modules.Len(); i++ {
- found := false
- for _, module := range b.configuredModules {
- name := android.RemoveOptionalPrebuiltPrefix(module.Name())
- if name == imageConfig.modules.Jar(i) {
- modules = append(modules, module)
- found = true
- break
- }
- }
- if !found && !ctx.Config().AllowMissingDependencies() {
- ctx.ModuleErrorf(
- "Boot image '%s' module '%s' not added as a dependency of platform_bootclasspath",
- imageConfig.name,
- imageConfig.modules.Jar(i))
- return []android.Module{}
- }
- }
- return modules
-}
diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go
index d41729150..124827523 100644
--- a/java/platform_compat_config.go
+++ b/java/platform_compat_config.go
@@ -19,7 +19,10 @@ import (
"path/filepath"
"android/soong/android"
+ "android/soong/bazel"
+
"github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
)
func init() {
@@ -36,7 +39,7 @@ var CompatConfigSdkMemberType = &compatConfigMemberType{
}
func registerPlatformCompatConfigBuildComponents(ctx android.RegistrationContext) {
- ctx.RegisterSingletonType("platform_compat_config_singleton", platformCompatConfigSingletonFactory)
+ ctx.RegisterParallelSingletonType("platform_compat_config_singleton", platformCompatConfigSingletonFactory)
ctx.RegisterModuleType("platform_compat_config", PlatformCompatConfigFactory)
ctx.RegisterModuleType("prebuilt_platform_compat_config", prebuiltCompatConfigFactory)
ctx.RegisterModuleType("global_compat_config", globalCompatConfigFactory)
@@ -54,6 +57,7 @@ type platformCompatConfigProperties struct {
type platformCompatConfig struct {
android.ModuleBase
+ android.BazelModuleBase
properties platformCompatConfigProperties
installDirPath android.InstallPath
@@ -122,10 +126,29 @@ func (p *platformCompatConfig) AndroidMkEntries() []android.AndroidMkEntries {
}}
}
+type bazelPlatformCompatConfigAttributes struct {
+ Src bazel.LabelAttribute
+}
+
+func (p *platformCompatConfig) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "platform_compat_config",
+ Bzl_load_location: "//build/bazel/rules/java:platform_compat_config.bzl",
+ }
+ attr := &bazelPlatformCompatConfigAttributes{
+ Src: *bazel.MakeLabelAttribute(
+ android.BazelLabelForModuleSrcSingle(ctx, proptools.String(p.properties.Src)).Label),
+ }
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{
+ Name: p.Name(),
+ }, attr)
+}
+
func PlatformCompatConfigFactory() android.Module {
module := &platformCompatConfig{}
module.AddProperties(&module.properties)
android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
+ android.InitBazelModule(module)
return module
}
diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go
index 206d99527..044802e4d 100644
--- a/java/prebuilt_apis.go
+++ b/java/prebuilt_apis.go
@@ -104,20 +104,51 @@ func prebuiltApiModuleName(mctx android.LoadHookContext, module, scope, version
return fmt.Sprintf("%s_%s_%s_%s", mctx.ModuleName(), scope, version, module)
}
+func hasBazelPrebuilt(module string) bool {
+ return module == "android" || module == "core-for-system-modules"
+}
+
+func bazelPrebuiltApiModuleName(module, scope, version string) string {
+ bazelModule := module
+ switch module {
+ case "android":
+ bazelModule = "android_jar"
+ case "core-for-system-modules":
+ bazelModule = "core_jar"
+ }
+ bazelVersion := version
+ if version == "current" {
+ bazelVersion = strconv.Itoa(android.FutureApiLevelInt)
+ }
+ bazelScope := scope
+ switch scope {
+ case "module-lib":
+ bazelScope = "module"
+ case "system-server":
+ bazelScope = "system_server"
+ }
+ return fmt.Sprintf("//prebuilts/sdk:%s_%s_%s", bazelScope, bazelVersion, bazelModule)
+}
+
func createImport(mctx android.LoadHookContext, module, scope, version, path, sdkVersion string, compileDex bool) {
props := struct {
- Name *string
- Jars []string
- Sdk_version *string
- Installable *bool
- Compile_dex *bool
- }{}
- props.Name = proptools.StringPtr(prebuiltApiModuleName(mctx, module, scope, version))
- props.Jars = append(props.Jars, path)
- props.Sdk_version = proptools.StringPtr(sdkVersion)
- props.Installable = proptools.BoolPtr(false)
- props.Compile_dex = proptools.BoolPtr(compileDex)
-
+ Name *string
+ Jars []string
+ Sdk_version *string
+ Installable *bool
+ Compile_dex *bool
+ Bazel_module android.BazelModuleProperties
+ }{
+ Name: proptools.StringPtr(prebuiltApiModuleName(mctx, module, scope, version)),
+ Jars: []string{path},
+ Sdk_version: proptools.StringPtr(sdkVersion),
+ Installable: proptools.BoolPtr(false),
+ Compile_dex: proptools.BoolPtr(compileDex),
+ }
+ if hasBazelPrebuilt(module) {
+ props.Bazel_module = android.BazelModuleProperties{
+ Label: proptools.StringPtr(bazelPrebuiltApiModuleName(module, scope, version))}
+ }
mctx.CreateModule(ImportFactory, &props)
}
@@ -135,6 +166,19 @@ func createApiModule(mctx android.LoadHookContext, name string, path string) {
mctx.CreateModule(genrule.GenRuleFactory, &genruleProps)
}
+func createLatestApiModuleExtensionVersionFile(mctx android.LoadHookContext, name string, version string) {
+ genruleProps := struct {
+ Name *string
+ Srcs []string
+ Out []string
+ Cmd *string
+ }{}
+ genruleProps.Name = proptools.StringPtr(name)
+ genruleProps.Out = []string{name}
+ genruleProps.Cmd = proptools.StringPtr("echo " + version + " > $(out)")
+ mctx.CreateModule(genrule.GenRuleFactory, &genruleProps)
+}
+
func createEmptyFile(mctx android.LoadHookContext, name string) {
props := struct {
Name *string
@@ -233,9 +277,10 @@ func prebuiltApiFiles(mctx android.LoadHookContext, p *prebuiltApis) {
type latestApiInfo struct {
module, scope, path string
version int
+ isExtensionApiFile bool
}
- getLatest := func(files []string) map[string]latestApiInfo {
+ getLatest := func(files []string, isExtensionApiFile bool) map[string]latestApiInfo {
m := make(map[string]latestApiInfo)
for _, f := range files {
module, version, scope := parseFinalizedPrebuiltPath(mctx, f)
@@ -245,16 +290,16 @@ func prebuiltApiFiles(mctx android.LoadHookContext, p *prebuiltApis) {
key := module + "." + scope
info, exists := m[key]
if !exists || version > info.version {
- m[key] = latestApiInfo{module, scope, f, version}
+ m[key] = latestApiInfo{module, scope, f, version, isExtensionApiFile}
}
}
return m
}
- latest := getLatest(apiLevelFiles)
+ latest := getLatest(apiLevelFiles, false)
if p.properties.Extensions_dir != nil {
extensionApiFiles := globExtensionDirs(mctx, p, "api/*.txt")
- for k, v := range getLatest(extensionApiFiles) {
+ for k, v := range getLatest(extensionApiFiles, true) {
if _, exists := latest[k]; !exists {
mctx.ModuleErrorf("Module %v finalized for extension %d but never during an API level; likely error", v.module, v.version)
}
@@ -267,6 +312,12 @@ func prebuiltApiFiles(mctx android.LoadHookContext, p *prebuiltApis) {
for _, k := range android.SortedKeys(latest) {
info := latest[k]
name := PrebuiltApiModuleName(info.module, info.scope, "latest")
+ latestExtensionVersionModuleName := PrebuiltApiModuleName(info.module, info.scope, "latest.extension_version")
+ if info.isExtensionApiFile {
+ createLatestApiModuleExtensionVersionFile(mctx, latestExtensionVersionModuleName, strconv.Itoa(info.version))
+ } else {
+ createLatestApiModuleExtensionVersionFile(mctx, latestExtensionVersionModuleName, "-1")
+ }
createApiModule(mctx, name, info.path)
}
diff --git a/java/resourceshrinker.go b/java/resourceshrinker.go
index 6d5960157..bf1b04d94 100644
--- a/java/resourceshrinker.go
+++ b/java/resourceshrinker.go
@@ -22,7 +22,8 @@ import (
var shrinkResources = pctx.AndroidStaticRule("shrinkResources",
blueprint.RuleParams{
- Command: `${config.ResourceShrinkerCmd} --output $out --input $in --raw_resources $raw_resources`,
+ // Note that we suppress stdout to avoid successful log confirmations.
+ Command: `${config.ResourceShrinkerCmd} --output $out --input $in --raw_resources $raw_resources >/dev/null`,
CommandDeps: []string{"${config.ResourceShrinkerCmd}"},
}, "raw_resources")
diff --git a/java/robolectric.go b/java/robolectric.go
index 008b8b1c9..0041af429 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -144,29 +144,37 @@ func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext)
roboTestConfig := android.PathForModuleGen(ctx, "robolectric").
Join(ctx, "com/android/tools/test_config.properties")
+ var ok bool
+ var instrumentedApp *AndroidApp
+
// TODO: this inserts paths to built files into the test, it should really be inserting the contents.
instrumented := ctx.GetDirectDepsWithTag(instrumentationForTag)
- if len(instrumented) != 1 {
+ if len(instrumented) == 1 {
+ instrumentedApp, ok = instrumented[0].(*AndroidApp)
+ if !ok {
+ ctx.PropertyErrorf("instrumentation_for", "dependency must be an android_app")
+ }
+ } else if !ctx.Config().AllowMissingDependencies() {
panic(fmt.Errorf("expected exactly 1 instrumented dependency, got %d", len(instrumented)))
}
- instrumentedApp, ok := instrumented[0].(*AndroidApp)
- if !ok {
- ctx.PropertyErrorf("instrumentation_for", "dependency must be an android_app")
- }
-
- r.manifest = instrumentedApp.mergedManifestFile
- r.resourceApk = instrumentedApp.outputFile
+ if instrumentedApp != nil {
+ r.manifest = instrumentedApp.mergedManifestFile
+ r.resourceApk = instrumentedApp.outputFile
- generateRoboTestConfig(ctx, roboTestConfig, instrumentedApp)
- r.extraResources = android.Paths{roboTestConfig}
+ generateRoboTestConfig(ctx, roboTestConfig, instrumentedApp)
+ r.extraResources = android.Paths{roboTestConfig}
+ }
r.Library.GenerateAndroidBuildActions(ctx)
roboSrcJar := android.PathForModuleGen(ctx, "robolectric", ctx.ModuleName()+".srcjar")
- r.generateRoboSrcJar(ctx, roboSrcJar, instrumentedApp)
- r.roboSrcJar = roboSrcJar
+
+ if instrumentedApp != nil {
+ r.generateRoboSrcJar(ctx, roboSrcJar, instrumentedApp)
+ r.roboSrcJar = roboSrcJar
+ }
roboTestConfigJar := android.PathForModuleOut(ctx, "robolectric_samedir", "samedir_config.jar")
generateSameDirRoboTestConfigJar(ctx, roboTestConfigJar)
@@ -177,7 +185,10 @@ func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext)
// once the Make test runner is removed.
roboTestConfigJar,
r.outputFile,
- instrumentedApp.implementationAndResourcesJar,
+ }
+
+ if instrumentedApp != nil {
+ combinedJarJars = append(combinedJarJars, instrumentedApp.implementationAndResourcesJar)
}
handleLibDeps := func(dep android.Module) {
@@ -213,21 +224,28 @@ func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext)
r.tests = append(r.tests, s)
}
- r.data = append(r.data, r.manifest, r.resourceApk)
-
- runtimes := ctx.GetDirectDepWithTag("robolectric-android-all-prebuilts", roboRuntimesTag)
-
installPath := android.PathForModuleInstall(ctx, r.BaseModuleName())
+ var installDeps android.Paths
- installedResourceApk := ctx.InstallFile(installPath, ctx.ModuleName()+".apk", r.resourceApk)
- installedManifest := ctx.InstallFile(installPath, ctx.ModuleName()+"-AndroidManifest.xml", r.manifest)
- installedConfig := ctx.InstallFile(installPath, ctx.ModuleName()+".config", r.testConfig)
+ if r.manifest != nil {
+ r.data = append(r.data, r.manifest)
+ installedManifest := ctx.InstallFile(installPath, ctx.ModuleName()+"-AndroidManifest.xml", r.manifest)
+ installDeps = append(installDeps, installedManifest)
+ }
- var installDeps android.Paths
+ if r.resourceApk != nil {
+ r.data = append(r.data, r.resourceApk)
+ installedResourceApk := ctx.InstallFile(installPath, ctx.ModuleName()+".apk", r.resourceApk)
+ installDeps = append(installDeps, installedResourceApk)
+ }
+
+ runtimes := ctx.GetDirectDepWithTag("robolectric-android-all-prebuilts", roboRuntimesTag)
for _, runtime := range runtimes.(*robolectricRuntimes).runtimes {
installDeps = append(installDeps, runtime)
}
- installDeps = append(installDeps, installedResourceApk, installedManifest, installedConfig)
+
+ installedConfig := ctx.InstallFile(installPath, ctx.ModuleName()+".config", r.testConfig)
+ installDeps = append(installDeps, installedConfig)
for _, data := range android.PathsForModuleSrc(ctx, r.testProperties.Data) {
installedData := ctx.InstallFile(installPath, data.Rel(), data)
@@ -281,7 +299,7 @@ func generateSameDirRoboTestConfigJar(ctx android.ModuleContext, outputFile andr
func (r *robolectricTest) generateRoboSrcJar(ctx android.ModuleContext, outputFile android.WritablePath,
instrumentedApp *AndroidApp) {
- srcJarArgs := copyOf(instrumentedApp.srcJarArgs)
+ srcJarArgs := android.CopyOf(instrumentedApp.srcJarArgs)
srcJarDeps := append(android.Paths(nil), instrumentedApp.srcJarDeps...)
for _, m := range ctx.GetDirectDepsWithTag(roboCoverageLibsTag) {
@@ -340,7 +358,9 @@ func (r *robolectricTest) writeTestRunner(w io.Writer, module, name string, test
fmt.Fprintln(w, "LOCAL_MODULE :=", name)
android.AndroidMkEmitAssignList(w, "LOCAL_JAVA_LIBRARIES", []string{module}, r.libs)
fmt.Fprintln(w, "LOCAL_TEST_PACKAGE :=", String(r.robolectricProperties.Instrumentation_for))
- fmt.Fprintln(w, "LOCAL_INSTRUMENT_SRCJARS :=", r.roboSrcJar.String())
+ if r.roboSrcJar != nil {
+ fmt.Fprintln(w, "LOCAL_INSTRUMENT_SRCJARS :=", r.roboSrcJar.String())
+ }
android.AndroidMkEmitAssignList(w, "LOCAL_ROBOTEST_FILES", tests)
if t := r.robolectricProperties.Test_options.Timeout; t != nil {
fmt.Fprintln(w, "LOCAL_ROBOTEST_TIMEOUT :=", *t)
diff --git a/java/sdk.go b/java/sdk.go
index 8b4918add..7c702c405 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -28,7 +28,7 @@ import (
func init() {
android.RegisterPreSingletonType("sdk_versions", sdkPreSingletonFactory)
- android.RegisterSingletonType("sdk", sdkSingletonFactory)
+ android.RegisterParallelSingletonType("sdk", sdkSingletonFactory)
android.RegisterMakeVarsProvider(pctx, sdkMakeVars)
}
@@ -148,10 +148,10 @@ func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext android.SdkContext)
toModule := func(module string, aidl android.Path) sdkDep {
// Select the kind of system modules needed for the sdk version.
systemModulesKind := systemModuleKind(sdkVersion.Kind, android.FutureApiLevel)
- systemModules := android.JavaApiLibraryName(ctx.Config(), fmt.Sprintf("core-%s-stubs-system-modules", systemModulesKind))
+ systemModules := fmt.Sprintf("core-%s-stubs-system-modules", systemModulesKind)
return sdkDep{
useModule: true,
- bootclasspath: []string{module, android.JavaApiLibraryName(ctx.Config(), config.DefaultLambdaStubsLibrary)},
+ bootclasspath: []string{module, config.DefaultLambdaStubsLibrary},
systemModules: systemModules,
java9Classpath: []string{module},
frameworkResModule: "framework-res",
@@ -193,20 +193,20 @@ func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext android.SdkContext)
noFrameworksLibs: true,
}
case android.SdkPublic, android.SdkSystem, android.SdkTest:
- return toModule(sdkVersion.Kind.JavaLibraryName(ctx.Config()), sdkFrameworkAidlPath(ctx))
+ return toModule(sdkVersion.Kind.DefaultJavaLibraryName(), sdkFrameworkAidlPath(ctx))
case android.SdkCore:
return sdkDep{
useModule: true,
- bootclasspath: []string{android.SdkCore.JavaLibraryName(ctx.Config()), android.JavaApiLibraryName(ctx.Config(), config.DefaultLambdaStubsLibrary)},
- systemModules: android.JavaApiLibraryName(ctx.Config(), "core-public-stubs-system-modules"),
+ bootclasspath: []string{android.SdkCore.DefaultJavaLibraryName(), config.DefaultLambdaStubsLibrary},
+ systemModules: "core-public-stubs-system-modules",
noFrameworksLibs: true,
}
case android.SdkModule:
// TODO(146757305): provide .apk and .aidl that have more APIs for modules
- return toModule(sdkVersion.Kind.JavaLibraryName(ctx.Config()), nonUpdatableFrameworkAidlPath(ctx))
+ return toModule(sdkVersion.Kind.DefaultJavaLibraryName(), nonUpdatableFrameworkAidlPath(ctx))
case android.SdkSystemServer:
// TODO(146757305): provide .apk and .aidl that have more APIs for modules
- return toModule(sdkVersion.Kind.JavaLibraryName(ctx.Config()), sdkFrameworkAidlPath(ctx))
+ return toModule(sdkVersion.Kind.DefaultJavaLibraryName(), sdkFrameworkAidlPath(ctx))
default:
panic(fmt.Errorf("invalid sdk %q", sdkVersion.Raw))
}
@@ -269,9 +269,9 @@ func (sdkSingleton) GenerateBuildActions(ctx android.SingletonContext) {
// Create framework.aidl by extracting anything that implements android.os.Parcelable from the SDK stubs modules.
func createSdkFrameworkAidl(ctx android.SingletonContext) {
stubsModules := []string{
- android.SdkPublic.JavaLibraryName(ctx.Config()),
- android.SdkTest.JavaLibraryName(ctx.Config()),
- android.SdkSystem.JavaLibraryName(ctx.Config()),
+ android.SdkPublic.DefaultJavaLibraryName(),
+ android.SdkTest.DefaultJavaLibraryName(),
+ android.SdkSystem.DefaultJavaLibraryName(),
}
combinedAidl := sdkFrameworkAidlPath(ctx)
@@ -286,7 +286,7 @@ func createSdkFrameworkAidl(ctx android.SingletonContext) {
// Creates a version of framework.aidl for the non-updatable part of the platform.
func createNonUpdatableFrameworkAidl(ctx android.SingletonContext) {
- stubsModules := []string{android.SdkModule.JavaLibraryName(ctx.Config())}
+ stubsModules := []string{android.SdkModule.DefaultJavaLibraryName()}
combinedAidl := nonUpdatableFrameworkAidlPath(ctx)
tempPath := tempPathForRestat(ctx, combinedAidl)
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 103f1ace7..dbb2f0247 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -24,6 +24,8 @@ import (
"strings"
"sync"
+ "android/soong/ui/metrics/bp2build_metrics_proto"
+
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -156,6 +158,9 @@ type apiScope struct {
// Whether the api scope can be treated as unstable, and should skip compat checks.
unstable bool
+
+ // Represents the SDK kind of this scope.
+ kind android.SdkKind
}
// Initialize a scope, creating and adding appropriate dependency tags
@@ -229,6 +234,14 @@ func (scope *apiScope) stubsLibraryModuleNameSuffix() string {
return ".stubs" + scope.moduleSuffix
}
+func (scope *apiScope) apiLibraryModuleName(baseName string) string {
+ return scope.stubsLibraryModuleName(baseName) + ".from-text"
+}
+
+func (scope *apiScope) sourceStubLibraryModuleName(baseName string) string {
+ return scope.stubsLibraryModuleName(baseName) + ".from-source"
+}
+
func (scope *apiScope) stubsLibraryModuleName(baseName string) string {
return baseName + scope.stubsLibraryModuleNameSuffix()
}
@@ -289,6 +302,7 @@ var (
return &module.sdkLibraryProperties.Public
},
sdkVersion: "current",
+ kind: android.SdkPublic,
})
apiScopeSystem = initApiScope(&apiScope{
name: "system",
@@ -301,6 +315,7 @@ var (
moduleSuffix: ".system",
sdkVersion: "system_current",
annotation: "android.annotation.SystemApi(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS)",
+ kind: android.SdkSystem,
})
apiScopeTest = initApiScope(&apiScope{
name: "test",
@@ -314,6 +329,7 @@ var (
sdkVersion: "test_current",
annotation: "android.annotation.TestApi",
unstable: true,
+ kind: android.SdkTest,
})
apiScopeModuleLib = initApiScope(&apiScope{
name: "module-lib",
@@ -331,6 +347,7 @@ var (
moduleSuffix: ".module_lib",
sdkVersion: "module_current",
annotation: "android.annotation.SystemApi(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES)",
+ kind: android.SdkModule,
})
apiScopeSystemServer = initApiScope(&apiScope{
name: "system-server",
@@ -361,6 +378,7 @@ var (
// com.android.* classes are okay in this interface"
"--hide", "InternalClasses",
},
+ kind: android.SdkSystemServer,
})
allApiScopes = apiScopes{
apiScopePublic,
@@ -842,6 +860,20 @@ func (c *commonToSdkLibraryAndImport) stubsSourceModuleName(apiScope *apiScope)
return c.namingScheme.stubsSourceModuleName(apiScope, baseName)
}
+// Name of the java_api_library module that generates the from-text stubs source
+// and compiles to a jar file.
+func (c *commonToSdkLibraryAndImport) apiLibraryModuleName(apiScope *apiScope) string {
+ baseName := c.module.BaseModuleName()
+ return c.namingScheme.apiLibraryModuleName(apiScope, baseName)
+}
+
+// Name of the java_library module that compiles the stubs
+// generated from source Java files.
+func (c *commonToSdkLibraryAndImport) sourceStubLibraryModuleName(apiScope *apiScope) string {
+ baseName := c.module.BaseModuleName()
+ return c.namingScheme.sourceStubLibraryModuleName(apiScope, baseName)
+}
+
// The component names for different outputs of the java_sdk_library.
//
// They are similar to the names used for the child modules it creates
@@ -1268,8 +1300,7 @@ func (module *SdkLibrary) ComponentDepsMutator(ctx android.BottomUpMutatorContex
for _, apiScope := range module.getGeneratedApiScopes(ctx) {
// Add dependencies to the stubs library
stubModuleName := module.stubsLibraryModuleName(apiScope)
- // Use JavaApiLibraryName function to be redirected to stubs generated from .txt if applicable
- stubModuleName = android.JavaApiLibraryName(ctx.Config(), stubModuleName)
+
ctx.AddVariationDependencies(nil, apiScope.stubsTag, stubModuleName)
// Add a dependency on the stubs source in order to access both stubs source and api information.
@@ -1477,6 +1508,11 @@ func (module *SdkLibrary) latestIncompatibilitiesModuleName(apiScope *apiScope)
return latestPrebuiltApiModuleName(module.distStem()+"-incompatibilities", apiScope)
}
+func (module *SdkLibrary) contributesToApiSurface(c android.Config) bool {
+ _, exists := c.GetApiLibraries()[module.Name()]
+ return exists
+}
+
func childModuleVisibility(childVisibility []string) []string {
if childVisibility == nil {
// No child visibility set. The child will use the visibility of the sdk_library.
@@ -1556,7 +1592,7 @@ func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext
}
}{}
- props.Name = proptools.StringPtr(module.stubsLibraryModuleName(apiScope))
+ props.Name = proptools.StringPtr(module.sourceStubLibraryModuleName(apiScope))
props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_library_visibility)
// sources are generated from the droiddoc
props.Srcs = []string{":" + module.stubsSourceModuleName(apiScope)}
@@ -1578,21 +1614,6 @@ func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext
// interop with older developer tools that don't support 1.9.
props.Java_version = proptools.StringPtr("1.8")
- // The imports need to be compiled to dex if the java_sdk_library requests it.
- compileDex := module.dexProperties.Compile_dex
- if module.stubLibrariesCompiledForDex() {
- compileDex = proptools.BoolPtr(true)
- }
- props.Compile_dex = compileDex
-
- // Dist the class jar artifact for sdk builds.
- if !Bool(module.sdkLibraryProperties.No_dist) {
- props.Dist.Targets = []string{"sdk", "win_sdk"}
- props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.jar", module.distStem()))
- props.Dist.Dir = proptools.StringPtr(module.apiDistPath(apiScope))
- props.Dist.Tag = proptools.StringPtr(".jar")
- }
-
mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}
@@ -1678,7 +1699,6 @@ func (module *SdkLibrary) createStubsSourcesAndApi(mctx android.DefaultableHookC
"MissingPermission",
"SdkConstant",
"Todo",
- "Typo",
"UnavailableSymbol",
}
droidstubsArgs = append(droidstubsArgs, android.JoinWithPrefix(disabledWarnings, "--hide "))
@@ -1758,6 +1778,93 @@ func (module *SdkLibrary) createStubsSourcesAndApi(mctx android.DefaultableHookC
mctx.CreateModule(DroidstubsFactory, &props).(*Droidstubs).CallHookIfAvailable(mctx)
}
+func (module *SdkLibrary) createApiLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) {
+ props := struct {
+ Name *string
+ Visibility []string
+ Api_contributions []string
+ Libs []string
+ Static_libs []string
+ Full_api_surface_stub *string
+ }{}
+
+ props.Name = proptools.StringPtr(module.apiLibraryModuleName(apiScope))
+ props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_library_visibility)
+
+ apiContributions := []string{}
+
+ // Api surfaces are not independent of each other, but have subset relationships,
+ // and so does the api files. To generate from-text stubs for api surfaces other than public,
+ // all subset api domains' api_contriubtions must be added as well.
+ scope := apiScope
+ for scope != nil {
+ apiContributions = append(apiContributions, module.stubsSourceModuleName(scope)+".api.contribution")
+ scope = scope.extends
+ }
+
+ props.Api_contributions = apiContributions
+ props.Libs = module.properties.Libs
+ props.Libs = append(props.Libs, module.sdkLibraryProperties.Stub_only_libs...)
+ props.Libs = append(props.Libs, "stub-annotations")
+ props.Static_libs = module.sdkLibraryProperties.Stub_only_static_libs
+ props.Full_api_surface_stub = proptools.StringPtr(apiScope.kind.DefaultJavaLibraryName() + ".from-text")
+
+ // android_module_lib_stubs_current.from-text only comprises api contributions from art, conscrypt and i18n.
+ // Thus, replace with android_module_lib_stubs_current_full.from-text, which comprises every api domains.
+ if apiScope.kind == android.SdkModule {
+ props.Full_api_surface_stub = proptools.StringPtr(apiScope.kind.DefaultJavaLibraryName() + "_full.from-text")
+ }
+
+ mctx.CreateModule(ApiLibraryFactory, &props)
+}
+
+func (module *SdkLibrary) createTopLevelStubsLibrary(
+ mctx android.DefaultableHookContext, apiScope *apiScope, contributesToApiSurface bool) {
+ props := struct {
+ Name *string
+ Visibility []string
+ Sdk_version *string
+ Static_libs []string
+ System_modules *string
+ Dist struct {
+ Targets []string
+ Dest *string
+ Dir *string
+ Tag *string
+ }
+ Compile_dex *bool
+ }{}
+ props.Name = proptools.StringPtr(module.stubsLibraryModuleName(apiScope))
+ props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_library_visibility)
+ sdkVersion := module.sdkVersionForStubsLibrary(mctx, apiScope)
+ props.Sdk_version = proptools.StringPtr(sdkVersion)
+
+ // Add the stub compiling java_library/java_api_library as static lib based on build config
+ staticLib := module.sourceStubLibraryModuleName(apiScope)
+ if mctx.Config().BuildFromTextStub() && contributesToApiSurface {
+ staticLib = module.apiLibraryModuleName(apiScope)
+ }
+ props.Static_libs = append(props.Static_libs, staticLib)
+ props.System_modules = module.deviceProperties.System_modules
+
+ // Dist the class jar artifact for sdk builds.
+ if !Bool(module.sdkLibraryProperties.No_dist) {
+ props.Dist.Targets = []string{"sdk", "win_sdk"}
+ props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.jar", module.distStem()))
+ props.Dist.Dir = proptools.StringPtr(module.apiDistPath(apiScope))
+ props.Dist.Tag = proptools.StringPtr(".jar")
+ }
+
+ // The imports need to be compiled to dex if the java_sdk_library requests it.
+ compileDex := module.dexProperties.Compile_dex
+ if module.stubLibrariesCompiledForDex() {
+ compileDex = proptools.BoolPtr(true)
+ }
+ props.Compile_dex = compileDex
+
+ mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
+}
+
func (module *SdkLibrary) compareAgainstLatestApi(apiScope *apiScope) bool {
return !(apiScope.unstable || module.sdkLibraryProperties.Unsafe_ignore_missing_latest_api)
}
@@ -1954,6 +2061,13 @@ func (module *SdkLibrary) CreateInternalModules(mctx android.DefaultableHookCont
module.createStubsSourcesAndApi(mctx, scope, module.stubsSourceModuleName(scope), scope.droidstubsArgs)
module.createStubsLibrary(mctx, scope)
+
+ contributesToApiSurface := module.contributesToApiSurface(mctx.Config())
+ if contributesToApiSurface {
+ module.createApiLibrary(mctx, scope)
+ }
+
+ module.createTopLevelStubsLibrary(mctx, scope, contributesToApiSurface)
}
if module.requiresRuntimeImplementationLibrary() {
@@ -2006,6 +2120,10 @@ type sdkLibraryComponentNamingScheme interface {
stubsLibraryModuleName(scope *apiScope, baseName string) string
stubsSourceModuleName(scope *apiScope, baseName string) string
+
+ apiLibraryModuleName(scope *apiScope, baseName string) string
+
+ sourceStubLibraryModuleName(scope *apiScope, baseName string) string
}
type defaultNamingScheme struct {
@@ -2019,9 +2137,19 @@ func (s *defaultNamingScheme) stubsSourceModuleName(scope *apiScope, baseName st
return scope.stubsSourceModuleName(baseName)
}
+func (s *defaultNamingScheme) apiLibraryModuleName(scope *apiScope, baseName string) string {
+ return scope.apiLibraryModuleName(baseName)
+}
+
+func (s *defaultNamingScheme) sourceStubLibraryModuleName(scope *apiScope, baseName string) string {
+ return scope.sourceStubLibraryModuleName(baseName)
+}
+
var _ sdkLibraryComponentNamingScheme = (*defaultNamingScheme)(nil)
func moduleStubLinkType(name string) (stub bool, ret sdkLinkType) {
+ name = strings.TrimSuffix(name, ".from-source")
+
// This suffix-based approach is fragile and could potentially mis-trigger.
// TODO(b/155164730): Clean this up when modules no longer reference sdk_lib stubs directly.
if strings.HasSuffix(name, apiScopePublic.stubsLibraryModuleNameSuffix()) {
@@ -2040,6 +2168,9 @@ func moduleStubLinkType(name string) (stub bool, ret sdkLinkType) {
if strings.HasSuffix(name, apiScopeTest.stubsLibraryModuleNameSuffix()) {
return true, javaSystem
}
+ if strings.HasSuffix(name, apiScopeSystemServer.stubsLibraryModuleNameSuffix()) {
+ return true, javaSystemServer
+ }
return false, javaPlatform
}
@@ -2102,6 +2233,7 @@ type bazelSdkLibraryAttributes struct {
// java_sdk_library bp2build converter
func (module *SdkLibrary) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
if ctx.ModuleType() != "java_sdk_library" {
+ ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_TYPE_UNSUPPORTED, "")
return
}
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index 1d0c13d4b..c22b9809b 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -35,6 +35,9 @@ func TestJavaSdkLibrary(t *testing.T) {
"29": {"foo"},
"30": {"bar", "barney", "baz", "betty", "foo", "fred", "quuz", "wilma"},
}),
+ android.FixtureModifyConfig(func(config android.Config) {
+ config.SetApiLibraries([]string{"foo"})
+ }),
).RunTestWithBp(t, `
droiddoc_exported_dir {
name: "droiddoc-templates-sdk",
@@ -121,6 +124,7 @@ func TestJavaSdkLibrary(t *testing.T) {
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", "")
@@ -407,10 +411,9 @@ func TestJavaSdkLibrary_StubOrImplOnlyLibs(t *testing.T) {
android.AssertStringListContainsEquals(t, "bad combined inputs for "+sdklib, combineJarInputs, depPath, combined)
}
for _, expectation := range expectations {
- verify("sdklib", expectation.lib, expectation.on_impl_classpath, expectation.in_impl_combined)
verify("sdklib.impl", expectation.lib, expectation.on_impl_classpath, expectation.in_impl_combined)
- stubName := apiScopePublic.stubsLibraryModuleName("sdklib")
+ stubName := apiScopePublic.sourceStubLibraryModuleName("sdklib")
verify(stubName, expectation.lib, expectation.on_stub_classpath, expectation.in_stub_combined)
}
}
@@ -1412,3 +1415,62 @@ func TestJavaSdkLibrary_StubOnlyLibs_PassedToDroidstubs(t *testing.T) {
fooStubsSources := result.ModuleForTests("foo.stubs.source", "android_common").Module().(*Droidstubs)
android.AssertStringListContains(t, "foo stubs should depend on bar-lib", fooStubsSources.Javadoc.properties.Libs, "bar-lib")
}
+
+func TestJavaSdkLibrary_ApiLibrary(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ PrepareForTestWithJavaSdkLibraryFiles,
+ FixtureWithLastReleaseApis("foo"),
+ android.FixtureModifyConfig(func(config android.Config) {
+ config.SetApiLibraries([]string{"foo"})
+ }),
+ ).RunTestWithBp(t, `
+ java_sdk_library {
+ name: "foo",
+ srcs: ["a.java", "b.java"],
+ api_packages: ["foo"],
+ system: {
+ enabled: true,
+ },
+ module_lib: {
+ enabled: true,
+ },
+ test: {
+ enabled: true,
+ },
+ }
+ `)
+
+ testCases := []struct {
+ scope *apiScope
+ apiContributions []string
+ fullApiSurfaceStub string
+ }{
+ {
+ scope: apiScopePublic,
+ apiContributions: []string{"foo.stubs.source.api.contribution"},
+ fullApiSurfaceStub: "android_stubs_current.from-text",
+ },
+ {
+ scope: apiScopeSystem,
+ apiContributions: []string{"foo.stubs.source.system.api.contribution", "foo.stubs.source.api.contribution"},
+ fullApiSurfaceStub: "android_system_stubs_current.from-text",
+ },
+ {
+ scope: apiScopeTest,
+ apiContributions: []string{"foo.stubs.source.test.api.contribution", "foo.stubs.source.system.api.contribution", "foo.stubs.source.api.contribution"},
+ fullApiSurfaceStub: "android_test_stubs_current.from-text",
+ },
+ {
+ scope: apiScopeModuleLib,
+ apiContributions: []string{"foo.stubs.source.module_lib.api.contribution", "foo.stubs.source.system.api.contribution", "foo.stubs.source.api.contribution"},
+ fullApiSurfaceStub: "android_module_lib_stubs_current_full.from-text",
+ },
+ }
+
+ for _, c := range testCases {
+ m := result.ModuleForTests(c.scope.apiLibraryModuleName("foo"), "android_common").Module().(*ApiLibrary)
+ android.AssertArrayString(t, "Module expected to contain api contributions", c.apiContributions, m.properties.Api_contributions)
+ android.AssertStringEquals(t, "Module expected to contain full api surface api library", c.fullApiSurfaceStub, *m.properties.Full_api_surface_stub)
+ }
+}
diff --git a/java/testing.go b/java/testing.go
index 6671bf0c7..3a238d76f 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -71,7 +71,12 @@ var prepareForTestWithFrameworkDeps = android.GroupFixturePreparers(
// Needed for framework
defaultJavaDir + "/framework/aidl": nil,
// Needed for various deps defined in GatherRequiredDepsForTest()
- defaultJavaDir + "/a.java": nil,
+ defaultJavaDir + "/a.java": nil,
+ defaultJavaDir + "/api/current.txt": nil,
+ defaultJavaDir + "/api/system-current.txt": nil,
+ defaultJavaDir + "/api/test-current.txt": nil,
+ defaultJavaDir + "/api/module-lib-current.txt": nil,
+ defaultJavaDir + "/api/system-server-current.txt": nil,
// Needed for R8 rules on apps
"build/make/core/proguard.flags": nil,
@@ -395,16 +400,20 @@ func gatherRequiredDepsForTest() string {
}
extraApiLibraryModules := map[string]string{
- "android_stubs_current.from-text": "api/current.txt",
- "android_system_stubs_current.from-text": "api/system-current.txt",
- "android_test_stubs_current.from-text": "api/test-current.txt",
- "android_module_lib_stubs_current.from-text": "api/module-lib-current.txt",
- "android_module_lib_stubs_current_full.from-text": "api/module-lib-current.txt",
- "android_system_server_stubs_current.from-text": "api/system-server-current.txt",
- "core.current.stubs.from-text": "api/current.txt",
- "legacy.core.platform.api.stubs.from-text": "api/current.txt",
- "stable.core.platform.api.stubs.from-text": "api/current.txt",
- "core-lambda-stubs.from-text": "api/current.txt",
+ "android_stubs_current.from-text": "api/current.txt",
+ "android_system_stubs_current.from-text": "api/system-current.txt",
+ "android_test_stubs_current.from-text": "api/test-current.txt",
+ "android_module_lib_stubs_current.from-text": "api/module-lib-current.txt",
+ "android_module_lib_stubs_current_full.from-text": "api/module-lib-current.txt",
+ "android_system_server_stubs_current.from-text": "api/system-server-current.txt",
+ "core.current.stubs.from-text": "api/current.txt",
+ "legacy.core.platform.api.stubs.from-text": "api/current.txt",
+ "stable.core.platform.api.stubs.from-text": "api/current.txt",
+ "core-lambda-stubs.from-text": "api/current.txt",
+ "android-non-updatable.stubs.from-text": "api/current.txt",
+ "android-non-updatable.stubs.system.from-text": "api/system-current.txt",
+ "android-non-updatable.stubs.test.from-text": "api/test-current.txt",
+ "android-non-updatable.stubs.module_lib.from-text": "api/module-lib-current.txt",
}
for libName, apiFile := range extraApiLibraryModules {