summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/aar.go210
-rw-r--r--java/aar_test.go98
-rw-r--r--java/android_manifest_test.go5
-rw-r--r--java/androidmk.go43
-rw-r--r--java/androidmk_test.go168
-rw-r--r--[-rwxr-xr-x]java/app.go262
-rw-r--r--java/app_import.go25
-rw-r--r--java/app_import_test.go6
-rw-r--r--java/app_set.go35
-rw-r--r--java/app_test.go258
-rw-r--r--java/base.go159
-rw-r--r--java/boot_jars.go4
-rw-r--r--java/bootclasspath.go5
-rw-r--r--java/bootclasspath_fragment.go33
-rw-r--r--java/builder.go2
-rw-r--r--java/classpath_fragment.go10
-rw-r--r--java/code_metadata_test.go1
-rw-r--r--java/config/config.go34
-rw-r--r--java/config/droidstubs.go8
-rw-r--r--java/config/error_prone.go21
-rw-r--r--java/device_host_converter_test.go10
-rw-r--r--java/dex.go18
-rw-r--r--java/dexpreopt.go30
-rw-r--r--java/dexpreopt_bootjars.go4
-rw-r--r--java/droiddoc.go20
-rw-r--r--java/droidstubs.go350
-rw-r--r--java/droidstubs_test.go38
-rw-r--r--java/fuzz.go4
-rw-r--r--java/gen.go41
-rw-r--r--java/generated_java_library.go6
-rw-r--r--java/generated_java_library_test.go4
-rw-r--r--java/hiddenapi_modular.go12
-rw-r--r--java/hiddenapi_singleton.go4
-rw-r--r--java/hiddenapi_singleton_test.go27
-rw-r--r--java/jacoco.go2
-rw-r--r--java/java.go256
-rw-r--r--java/java_test.go357
-rw-r--r--java/jdeps.go2
-rw-r--r--java/lint.go4
-rw-r--r--java/platform_bootclasspath.go25
-rw-r--r--java/platform_bootclasspath_test.go2
-rw-r--r--java/platform_compat_config.go13
-rw-r--r--java/prebuilt_apis.go52
-rw-r--r--java/robolectric.go24
-rw-r--r--java/rro.go5
-rw-r--r--java/rro_test.go48
-rw-r--r--java/sdk.go21
-rw-r--r--java/sdk_library.go316
-rw-r--r--java/sdk_library_test.go106
-rw-r--r--java/system_modules.go1
-rw-r--r--java/systemserver_classpath_fragment.go3
-rw-r--r--java/testing.go32
52 files changed, 2133 insertions, 1091 deletions
diff --git a/java/aar.go b/java/aar.go
index b3239ba93..07392f6e5 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -104,6 +104,9 @@ type aaptProperties struct {
// Filter only specified product and ignore other products
Filter_product *string `blueprint:"mutated"`
+
+ // Names of aconfig_declarations modules that specify aconfig flags that the module depends on.
+ Flags_packages []string
}
type aapt struct {
@@ -161,7 +164,9 @@ func propagateRROEnforcementMutator(ctx android.TopDownMutatorContext) {
}
func (a *aapt) useResourceProcessorBusyBox(ctx android.BaseModuleContext) bool {
- return BoolDefault(a.aaptProperties.Use_resource_processor, ctx.Config().UseResourceProcessorByDefault())
+ return BoolDefault(a.aaptProperties.Use_resource_processor, ctx.Config().UseResourceProcessorByDefault()) &&
+ // TODO(b/331641946): remove this when ResourceProcessorBusyBox supports generating shared libraries.
+ !slices.Contains(a.aaptProperties.Aaptflags, "--shared-lib")
}
func (a *aapt) filterProduct() string {
@@ -348,14 +353,16 @@ type aaptBuildActionOptions struct {
classLoaderContexts dexpreopt.ClassLoaderContextMap
excludedLibs []string
enforceDefaultTargetSdkVersion bool
+ forceNonFinalResourceIDs bool
extraLinkFlags []string
aconfigTextFiles android.Paths
+ usesLibrary *usesLibrary
}
func (a *aapt) buildActions(ctx android.ModuleContext, opts aaptBuildActionOptions) {
staticResourcesNodesDepSet, sharedResourcesNodesDepSet, staticRRODirsDepSet, staticManifestsDepSet, sharedExportPackages, libFlags :=
- aaptLibs(ctx, opts.sdkContext, opts.classLoaderContexts)
+ aaptLibs(ctx, opts.sdkContext, opts.classLoaderContexts, opts.usesLibrary)
// Exclude any libraries from the supplied list.
opts.classLoaderContexts = opts.classLoaderContexts.ExcludeLibs(opts.excludedLibs)
@@ -383,11 +390,6 @@ func (a *aapt) buildActions(ctx android.ModuleContext, opts aaptBuildActionOptio
// Add additional manifest files to transitive manifests.
additionalManifests := android.PathsForModuleSrc(ctx, a.aaptProperties.Additional_manifests)
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) {
@@ -416,6 +418,9 @@ func (a *aapt) buildActions(ctx android.ModuleContext, opts aaptBuildActionOptio
if a.isLibrary {
linkFlags = append(linkFlags, "--static-lib")
}
+ if opts.forceNonFinalResourceIDs {
+ linkFlags = append(linkFlags, "--non-final-ids")
+ }
linkFlags = append(linkFlags, "--no-static-lib-packages")
if a.isLibrary && a.useResourceProcessorBusyBox(ctx) {
@@ -455,6 +460,11 @@ func (a *aapt) buildActions(ctx android.ModuleContext, opts aaptBuildActionOptio
// 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 _, sharedDep := range sharedDeps {
+ if sharedDep.usedResourceProcessor {
+ transitiveRJars = append(transitiveRJars, sharedDep.rJar)
+ }
+ }
for _, staticDep := range staticDeps {
linkDeps = append(linkDeps, staticDep.resPackage)
linkFlags = append(linkFlags, "-I "+staticDep.resPackage.String())
@@ -462,11 +472,6 @@ func (a *aapt) buildActions(ctx android.ModuleContext, opts aaptBuildActionOptio
transitiveRJars = append(transitiveRJars, staticDep.rJar)
}
}
- for _, sharedDep := range sharedDeps {
- if sharedDep.usedResourceProcessor {
- transitiveRJars = append(transitiveRJars, sharedDep.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.
@@ -541,7 +546,8 @@ func (a *aapt) buildActions(ctx android.ModuleContext, opts aaptBuildActionOptio
if a.useResourceProcessorBusyBox(ctx) {
rJar := android.PathForModuleOut(ctx, "busybox/R.jar")
- resourceProcessorBusyBoxGenerateBinaryR(ctx, rTxt, a.mergedManifestFile, rJar, staticDeps, a.isLibrary, a.aaptProperties.Aaptflags)
+ resourceProcessorBusyBoxGenerateBinaryR(ctx, rTxt, a.mergedManifestFile, rJar, staticDeps, a.isLibrary, a.aaptProperties.Aaptflags,
+ opts.forceNonFinalResourceIDs)
aapt2ExtractExtraPackages(ctx, extraPackages, rJar)
transitiveRJars = append(transitiveRJars, rJar)
a.rJar = rJar
@@ -556,6 +562,10 @@ func (a *aapt) buildActions(ctx android.ModuleContext, opts aaptBuildActionOptio
transitiveAaptResourcePackagesFile := android.PathForModuleOut(ctx, "transitive-res-packages")
android.WriteFileRule(ctx, transitiveAaptResourcePackagesFile, strings.Join(transitiveAaptResourcePackages, "\n"))
+ // Reverse the list of R.jar files so that the current module comes first, and direct dependencies come before
+ // transitive dependencies.
+ transitiveRJars = android.ReversePaths(transitiveRJars)
+
a.aaptSrcJar = srcJar
a.transitiveAaptRJars = transitiveRJars
a.transitiveAaptResourcePackagesFile = transitiveAaptResourcePackagesFile
@@ -601,7 +611,8 @@ var resourceProcessorBusyBox = pctx.AndroidStaticRule("resourceProcessorBusyBox"
// 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, aaptFlags []string) {
+ rJar android.WritablePath, transitiveDeps transitiveAarDeps, isLibrary bool, aaptFlags []string,
+ forceNonFinalIds bool) {
var args []string
var deps android.Paths
@@ -611,6 +622,9 @@ func resourceProcessorBusyBoxGenerateBinaryR(ctx android.ModuleContext, rTxt, ma
// to ResourceProcessorBusyBox so that it can regenerate R.class files with the final resource IDs for each
// package.
args, deps = transitiveDeps.resourceProcessorDeps()
+ if forceNonFinalIds {
+ args = append(args, "--finalFields=false")
+ }
} 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
@@ -693,7 +707,8 @@ func (t transitiveAarDeps) assets() android.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) (
+func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext,
+ classLoaderContexts dexpreopt.ClassLoaderContextMap, usesLibrary *usesLibrary) (
staticResourcesNodes, sharedResourcesNodes *android.DepSet[*resourcesNode], staticRRODirs *android.DepSet[rroDir],
staticManifests *android.DepSet[android.Path], sharedLibs android.Paths, flags []string) {
@@ -743,6 +758,9 @@ func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext, classLoa
}
addCLCFromDep(ctx, module, classLoaderContexts)
+ if usesLibrary != nil {
+ addMissingOptionalUsesLibsFromDep(ctx, module, usesLibrary)
+ }
})
// AAPT2 overlays are in lowest to highest priority order, the topological order will be reversed later.
@@ -750,7 +768,8 @@ func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext, classLoa
// 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.
+ // dependency has to be listed last. This is also inconsistent with the way manifests from the same
+ // transitive dependencies are merged.
staticResourcesNodes = android.NewDepSet(android.TOPOLOGICAL, nil,
android.ReverseSliceInPlace(staticResourcesNodeDepSets))
sharedResourcesNodes = android.NewDepSet(android.TOPOLOGICAL, nil,
@@ -794,12 +813,16 @@ func (a *AndroidLibrary) OutputFiles(tag string) (android.Paths, error) {
var _ AndroidLibraryDependency = (*AndroidLibrary)(nil)
func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
+ a.usesLibrary.deps(ctx, false)
a.Module.deps(ctx)
sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
if sdkDep.hasFrameworkLibs() {
a.aapt.deps(ctx, sdkDep)
}
- a.usesLibrary.deps(ctx, false)
+
+ for _, aconfig_declaration := range a.aaptProperties.Flags_packages {
+ ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
+ }
}
func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -813,13 +836,15 @@ func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
sdkContext: android.SdkContext(a),
classLoaderContexts: a.classLoaderContexts,
enforceDefaultTargetSdkVersion: false,
+ aconfigTextFiles: getAconfigFilePaths(ctx),
+ usesLibrary: &a.usesLibrary,
},
)
apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
a.hideApexVariantFromMake = !apexInfo.IsForPlatform()
- a.stem = proptools.StringDefault(a.overridableDeviceProperties.Stem, ctx.ModuleName())
+ a.stem = proptools.StringDefault(a.overridableProperties.Stem, ctx.ModuleName())
ctx.CheckbuildFile(a.aapt.proguardOptionsFile)
ctx.CheckbuildFile(a.aapt.exportPackage)
@@ -906,7 +931,8 @@ func AndroidLibraryFactory() android.Module {
module.Module.addHostAndDeviceProperties()
module.AddProperties(
&module.aaptProperties,
- &module.androidLibraryProperties)
+ &module.androidLibraryProperties,
+ &module.sourceProperties)
module.androidLibraryProperties.BuildAAR = true
module.Module.linter.library = true
@@ -945,6 +971,9 @@ type AARImportProperties struct {
// will be passed transitively through android_libraries to an android_app.
//TODO(b/241138093) evaluate whether we can have this flag default to true for Bazel conversion
Extract_jni *bool
+
+ // If set, overrides the manifest extracted from the AAR with the provided path.
+ Manifest *string `android:"path"`
}
type AARImport struct {
@@ -960,12 +989,14 @@ type AARImport struct {
properties AARImportProperties
- classpathFile android.WritablePath
+ headerJarFile android.WritablePath
+ implementationJarFile android.WritablePath
+ implementationAndResourcesJarFile android.WritablePath
proguardFlags android.WritablePath
exportPackage android.WritablePath
transitiveAaptResourcePackagesFile android.Path
extraAaptPackagesFile android.WritablePath
- manifest android.WritablePath
+ manifest android.Path
assetsPackage android.WritablePath
rTxt android.WritablePath
rJar android.WritablePath
@@ -981,8 +1012,8 @@ type AARImport struct {
sdkVersion android.SdkSpec
minSdkVersion android.ApiLevel
- // Single aconfig "cache file" merged from this module and all dependencies.
- mergedAconfigFiles map[string]android.Paths
+ usesLibrary
+ classLoaderContexts dexpreopt.ClassLoaderContextMap
}
var _ android.OutputFileProducer = (*AARImport)(nil)
@@ -993,7 +1024,7 @@ func (a *AARImport) OutputFiles(tag string) (android.Paths, error) {
case ".aar":
return []android.Path{a.aarPath}, nil
case "":
- return []android.Path{a.classpathFile}, nil
+ return []android.Path{a.implementationAndResourcesJarFile}, nil
default:
return nil, fmt.Errorf("unsupported module reference tag %q", tag)
}
@@ -1076,6 +1107,8 @@ func (a *AARImport) DepsMutator(ctx android.BottomUpMutatorContext) {
ctx.AddVariationDependencies(nil, libTag, a.properties.Libs...)
ctx.AddVariationDependencies(nil, staticLibTag, a.properties.Static_libs...)
+
+ a.usesLibrary.deps(ctx, false)
}
type JniPackageInfo struct {
@@ -1133,28 +1166,43 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
TransformJetifier(ctx, a.aarPath.(android.WritablePath), inputFile)
}
+ jarName := ctx.ModuleName() + ".jar"
extractedAARDir := android.PathForModuleOut(ctx, "aar")
- a.classpathFile = extractedAARDir.Join(ctx, "classes-combined.jar")
- a.manifest = extractedAARDir.Join(ctx, "AndroidManifest.xml")
+ classpathFile := extractedAARDir.Join(ctx, jarName)
+
+ extractedManifest := extractedAARDir.Join(ctx, "AndroidManifest.xml")
+ providedManifest := android.OptionalPathForModuleSrc(ctx, a.properties.Manifest)
+ if providedManifest.Valid() {
+ a.manifest = providedManifest.Path()
+ } else {
+ a.manifest = extractedManifest
+ }
+
a.rTxt = extractedAARDir.Join(ctx, "R.txt")
a.assetsPackage = android.PathForModuleOut(ctx, "assets.zip")
a.proguardFlags = extractedAARDir.Join(ctx, "proguard.txt")
+ transitiveProguardFlags, transitiveUnconditionalExportedFlags := collectDepProguardSpecInfo(ctx)
android.SetProvider(ctx, ProguardSpecInfoProvider, ProguardSpecInfo{
ProguardFlagsFiles: android.NewDepSet[android.Path](
android.POSTORDER,
android.Paths{a.proguardFlags},
+ transitiveProguardFlags,
+ ),
+ UnconditionallyExportedProguardFlags: android.NewDepSet[android.Path](
+ android.POSTORDER,
nil,
+ transitiveUnconditionalExportedFlags,
),
})
ctx.Build(pctx, android.BuildParams{
Rule: unzipAAR,
Input: a.aarPath,
- Outputs: android.WritablePaths{a.classpathFile, a.proguardFlags, a.manifest, a.assetsPackage, a.rTxt},
+ Outputs: android.WritablePaths{classpathFile, a.proguardFlags, extractedManifest, a.assetsPackage, a.rTxt},
Description: "unzip AAR",
Args: map[string]string{
"outDir": extractedAARDir.String(),
- "combinedClassesJar": a.classpathFile.String(),
+ "combinedClassesJar": classpathFile.String(),
"assetsPackage": a.assetsPackage.String(),
},
})
@@ -1184,7 +1232,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
linkDeps = append(linkDeps, a.manifest)
staticResourcesNodesDepSet, sharedResourcesNodesDepSet, staticRRODirsDepSet, staticManifestsDepSet, sharedLibs, libFlags :=
- aaptLibs(ctx, android.SdkContext(a), nil)
+ aaptLibs(ctx, android.SdkContext(a), nil, nil)
_ = sharedResourcesNodesDepSet
_ = staticRRODirsDepSet
@@ -1209,7 +1257,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil, nil)
a.rJar = android.PathForModuleOut(ctx, "busybox/R.jar")
- resourceProcessorBusyBoxGenerateBinaryR(ctx, a.rTxt, a.manifest, a.rJar, nil, true, nil)
+ resourceProcessorBusyBoxGenerateBinaryR(ctx, a.rTxt, a.manifest, a.rJar, nil, true, nil, false)
aapt2ExtractExtraPackages(ctx, a.extraAaptPackagesFile, a.rJar)
@@ -1227,13 +1275,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
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
+ manifestDepSetBuilder.Transitive(staticManifestsDepSet)
a.manifestsDepSet = manifestDepSetBuilder.Build()
transitiveAaptResourcePackages := staticDeps.resPackages().Strings()
@@ -1245,12 +1287,74 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.transitiveAaptResourcePackagesFile = transitiveAaptResourcePackagesFile
a.collectTransitiveHeaderJars(ctx)
+
+ a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
+
+ var staticJars android.Paths
+ var staticHeaderJars android.Paths
+ var staticResourceJars android.Paths
+ ctx.VisitDirectDeps(func(module android.Module) {
+ if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
+ tag := ctx.OtherModuleDependencyTag(module)
+ switch tag {
+ case staticLibTag:
+ staticJars = append(staticJars, dep.ImplementationJars...)
+ staticHeaderJars = append(staticHeaderJars, dep.HeaderJars...)
+ staticResourceJars = append(staticResourceJars, dep.ResourceJars...)
+ }
+ }
+ addCLCFromDep(ctx, module, a.classLoaderContexts)
+ addMissingOptionalUsesLibsFromDep(ctx, module, &a.usesLibrary)
+ })
+
+ var implementationJarFile android.OutputPath
+ if len(staticJars) > 0 {
+ combineJars := append(android.Paths{classpathFile}, staticJars...)
+ implementationJarFile = android.PathForModuleOut(ctx, "combined", jarName).OutputPath
+ TransformJarsToJar(ctx, implementationJarFile, "combine", combineJars, android.OptionalPath{}, false, nil, nil)
+ } else {
+ implementationJarFile = classpathFile
+ }
+
+ var resourceJarFile android.Path
+ if len(staticResourceJars) > 1 {
+ combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName)
+ TransformJarsToJar(ctx, combinedJar, "for resources", staticResourceJars, android.OptionalPath{},
+ false, nil, nil)
+ resourceJarFile = combinedJar
+ } else if len(staticResourceJars) == 1 {
+ resourceJarFile = staticResourceJars[0]
+ }
+
+ // merge implementation jar with resources if necessary
+ implementationAndResourcesJar := implementationJarFile
+ if resourceJarFile != nil {
+ jars := android.Paths{resourceJarFile, implementationAndResourcesJar}
+ combinedJar := android.PathForModuleOut(ctx, "withres", jarName).OutputPath
+ TransformJarsToJar(ctx, combinedJar, "for resources", jars, android.OptionalPath{},
+ false, nil, nil)
+ implementationAndResourcesJar = combinedJar
+ }
+
+ a.implementationJarFile = implementationJarFile
+ // Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
+ a.implementationAndResourcesJarFile = implementationAndResourcesJar.WithoutRel()
+
+ if len(staticHeaderJars) > 0 {
+ combineJars := append(android.Paths{classpathFile}, staticHeaderJars...)
+ a.headerJarFile = android.PathForModuleOut(ctx, "turbine-combined", jarName)
+ TransformJarsToJar(ctx, a.headerJarFile, "combine header jars", combineJars, android.OptionalPath{}, false, nil, nil)
+ } else {
+ a.headerJarFile = classpathFile
+ }
+
android.SetProvider(ctx, JavaInfoProvider, JavaInfo{
- HeaderJars: android.PathsIfNonNil(a.classpathFile),
+ HeaderJars: android.PathsIfNonNil(a.headerJarFile),
+ ResourceJars: android.PathsIfNonNil(resourceJarFile),
TransitiveLibsHeaderJars: a.transitiveLibsHeaderJars,
TransitiveStaticLibsHeaderJars: a.transitiveStaticLibsHeaderJars,
- ImplementationAndResourcesJars: android.PathsIfNonNil(a.classpathFile),
- ImplementationJars: android.PathsIfNonNil(a.classpathFile),
+ ImplementationAndResourcesJars: android.PathsIfNonNil(a.implementationAndResourcesJarFile),
+ ImplementationJars: android.PathsIfNonNil(a.implementationJarFile),
StubsLinkType: Implementation,
// TransitiveAconfigFiles: // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
})
@@ -1279,19 +1383,18 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
android.SetProvider(ctx, JniPackageProvider, JniPackageInfo{
JniPackages: a.jniPackages,
})
- android.CollectDependencyAconfigFiles(ctx, &a.mergedAconfigFiles)
}
func (a *AARImport) HeaderJars() android.Paths {
- return android.Paths{a.classpathFile}
+ return android.Paths{a.headerJarFile}
}
func (a *AARImport) ImplementationAndResourcesJars() android.Paths {
- return android.Paths{a.classpathFile}
+ return android.Paths{a.implementationAndResourcesJarFile}
}
-func (a *AARImport) DexJarBuildPath(ctx android.ModuleErrorfContext) android.Path {
- return nil
+func (a *AARImport) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
+ return OptionalDexJarPath{}
}
func (a *AARImport) DexJarInstallPath() android.Path {
@@ -1299,9 +1402,11 @@ func (a *AARImport) DexJarInstallPath() android.Path {
}
func (a *AARImport) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
- return nil
+ return a.classLoaderContexts
}
+var _ UsesLibraryDependency = (*AARImport)(nil)
+
var _ android.ApexModule = (*AARImport)(nil)
// Implements android.ApexModule
@@ -1310,13 +1415,19 @@ func (a *AARImport) DepIsInSameApex(ctx android.BaseModuleContext, dep android.M
}
// Implements android.ApexModule
-func (g *AARImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
+func (a *AARImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
sdkVersion android.ApiLevel) error {
return nil
}
var _ android.PrebuiltInterface = (*AARImport)(nil)
+func (a *AARImport) UsesLibrary() *usesLibrary {
+ return &a.usesLibrary
+}
+
+var _ ModuleWithUsesLibrary = (*AARImport)(nil)
+
// android_library_import imports an `.aar` file into the build graph as if it was built with android_library.
//
// This module is not suitable for installing on a device, but can be used as a `static_libs` dependency of
@@ -1324,7 +1435,10 @@ var _ android.PrebuiltInterface = (*AARImport)(nil)
func AARImportFactory() android.Module {
module := &AARImport{}
- module.AddProperties(&module.properties)
+ module.AddProperties(
+ &module.properties,
+ &module.usesLibrary.usesLibraryProperties,
+ )
android.InitPrebuiltModule(module, &module.properties.Aars)
android.InitApexModule(module)
diff --git a/java/aar_test.go b/java/aar_test.go
index 4d4e5d025..18efd2067 100644
--- a/java/aar_test.go
+++ b/java/aar_test.go
@@ -15,8 +15,9 @@
package java
import (
- "android/soong/android"
"testing"
+
+ "android/soong/android"
)
func TestAarImportProducesJniPackages(t *testing.T) {
@@ -81,3 +82,98 @@ func TestAarImportProducesJniPackages(t *testing.T) {
})
}
}
+
+func TestLibraryFlagsPackages(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ ).RunTestWithBp(t, `
+ android_library {
+ name: "foo",
+ srcs: ["a.java"],
+ sdk_version: "current",
+ flags_packages: [
+ "bar",
+ "baz",
+ ],
+ }
+ aconfig_declarations {
+ name: "bar",
+ package: "com.example.package.bar",
+ container: "com.android.foo",
+ srcs: [
+ "bar.aconfig",
+ ],
+ }
+ aconfig_declarations {
+ name: "baz",
+ package: "com.example.package.baz",
+ container: "com.android.foo",
+ srcs: [
+ "baz.aconfig",
+ ],
+ }
+ `)
+
+ foo := result.ModuleForTests("foo", "android_common")
+
+ // android_library module depends on aconfig_declarations listed in flags_packages
+ android.AssertBoolEquals(t, "foo expected to depend on bar", true,
+ CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "bar"))
+
+ android.AssertBoolEquals(t, "foo expected to depend on baz", true,
+ CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "baz"))
+
+ aapt2LinkRule := foo.Rule("android/soong/java.aapt2Link")
+ linkInFlags := aapt2LinkRule.Args["inFlags"]
+ android.AssertStringDoesContain(t,
+ "aapt2 link command expected to pass feature flags arguments",
+ linkInFlags,
+ "--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt",
+ )
+}
+
+func TestAndroidLibraryOutputFilesRel(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ ).RunTestWithBp(t, `
+ android_library {
+ name: "foo",
+ srcs: ["a.java"],
+ java_resources: ["foo.txt"],
+ }
+
+ android_library_import {
+ name: "bar",
+ aars: ["bar_prebuilt.aar"],
+
+ }
+
+ android_library_import {
+ name: "baz",
+ aars: ["baz_prebuilt.aar"],
+ static_libs: ["foo", "bar"],
+ }
+ `)
+
+ foo := result.ModuleForTests("foo", "android_common")
+ bar := result.ModuleForTests("bar", "android_common")
+ baz := result.ModuleForTests("baz", "android_common")
+
+ fooOutputPath := android.OutputFileForModule(android.PathContext(nil), foo.Module(), "")
+ barOutputPath := android.OutputFileForModule(android.PathContext(nil), bar.Module(), "")
+ bazOutputPath := android.OutputFileForModule(android.PathContext(nil), baz.Module(), "")
+
+ android.AssertPathRelativeToTopEquals(t, "foo output path",
+ "out/soong/.intermediates/foo/android_common/withres/foo.jar", fooOutputPath)
+ android.AssertPathRelativeToTopEquals(t, "bar output path",
+ "out/soong/.intermediates/bar/android_common/aar/bar.jar", barOutputPath)
+ android.AssertPathRelativeToTopEquals(t, "baz output path",
+ "out/soong/.intermediates/baz/android_common/withres/baz.jar", bazOutputPath)
+
+ android.AssertStringEquals(t, "foo relative output path",
+ "foo.jar", fooOutputPath.Rel())
+ android.AssertStringEquals(t, "bar relative output path",
+ "bar.jar", barOutputPath.Rel())
+ android.AssertStringEquals(t, "baz relative output path",
+ "baz.jar", bazOutputPath.Rel())
+}
diff --git a/java/android_manifest_test.go b/java/android_manifest_test.go
index 5909b1e6a..7c9188462 100644
--- a/java/android_manifest_test.go
+++ b/java/android_manifest_test.go
@@ -92,10 +92,9 @@ func TestManifestMerger(t *testing.T) {
"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/transitive_import_dep/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.
-
+ "out/soong/.intermediates/direct_import_dep/android_common/aar/AndroidManifest.xml",
},
manifestMergerRule.Implicits)
}
diff --git a/java/androidmk.go b/java/androidmk.go
index 498962f88..a1bc90494 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -17,7 +17,6 @@ package java
import (
"fmt"
"io"
- "strings"
"android/soong/android"
@@ -92,11 +91,7 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries {
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
if len(library.logtagsSrcs) > 0 {
- var logtags []string
- for _, l := range library.logtagsSrcs {
- logtags = append(logtags, l.Rel())
- }
- entries.AddStrings("LOCAL_LOGTAGS_FILES", logtags...)
+ entries.AddStrings("LOCAL_SOONG_LOGTAGS_FILES", library.logtagsSrcs.Strings()...)
}
if library.installFile == nil {
@@ -128,7 +123,6 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries {
if library.dexpreopter.configPath != nil {
entries.SetPath("LOCAL_SOONG_DEXPREOPT_CONFIG", library.dexpreopter.configPath)
}
- android.SetAconfigFileMkEntries(&library.ModuleBase, entries, library.mergedAconfigFiles)
},
},
})
@@ -211,7 +205,7 @@ func (prebuilt *Import) AndroidMkEntries() []android.AndroidMkEntries {
return []android.AndroidMkEntries{android.AndroidMkEntries{
Class: "JAVA_LIBRARIES",
OverrideName: prebuilt.BaseModuleName(),
- OutputFile: android.OptionalPathForPath(prebuilt.combinedClasspathFile),
+ OutputFile: android.OptionalPathForPath(prebuilt.combinedImplementationFile),
Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
@@ -219,8 +213,8 @@ func (prebuilt *Import) AndroidMkEntries() []android.AndroidMkEntries {
if prebuilt.dexJarFile.IsSet() {
entries.SetPath("LOCAL_SOONG_DEX_JAR", prebuilt.dexJarFile.Path())
}
- entries.SetPath("LOCAL_SOONG_HEADER_JAR", prebuilt.combinedClasspathFile)
- entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.combinedClasspathFile)
+ entries.SetPath("LOCAL_SOONG_HEADER_JAR", prebuilt.combinedHeaderFile)
+ entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.combinedImplementationFile)
entries.SetString("LOCAL_SDK_VERSION", prebuilt.sdkVersion.String())
entries.SetString("LOCAL_MODULE_STEM", prebuilt.Stem())
// TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
@@ -262,13 +256,13 @@ func (prebuilt *AARImport) AndroidMkEntries() []android.AndroidMkEntries {
}
return []android.AndroidMkEntries{android.AndroidMkEntries{
Class: "JAVA_LIBRARIES",
- OutputFile: android.OptionalPathForPath(prebuilt.classpathFile),
+ OutputFile: android.OptionalPathForPath(prebuilt.implementationJarFile),
Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
- entries.SetPath("LOCAL_SOONG_HEADER_JAR", prebuilt.classpathFile)
- entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.classpathFile)
+ entries.SetPath("LOCAL_SOONG_HEADER_JAR", prebuilt.headerJarFile)
+ entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.implementationJarFile)
entries.SetPath("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE", prebuilt.exportPackage)
entries.SetPath("LOCAL_SOONG_TRANSITIVE_RES_PACKAGES", prebuilt.transitiveAaptResourcePackagesFile)
entries.SetPath("LOCAL_SOONG_EXPORT_PROGUARD_FLAGS", prebuilt.proguardFlags)
@@ -302,7 +296,6 @@ func (binary *Binary) AndroidMkEntries() []android.AndroidMkEntries {
if len(binary.dexpreopter.builtInstalled) > 0 {
entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", binary.dexpreopter.builtInstalled)
}
- android.SetAconfigFileMkEntries(&binary.ModuleBase, entries, binary.mergedAconfigFiles)
},
},
ExtraFooters: []android.AndroidMkExtraFootersFunc{
@@ -420,22 +413,11 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
jniSymbols := app.JNISymbolsInstalls(app.installPathForJNISymbols.String())
entries.SetString("LOCAL_SOONG_JNI_LIBS_SYMBOLS", jniSymbols.String())
} else {
+ var names []string
for _, jniLib := range app.jniLibs {
- entries.AddStrings("LOCAL_SOONG_JNI_LIBS_"+jniLib.target.Arch.ArchType.String(), jniLib.name)
- var partitionTag string
-
- // Mimic the creation of partition_tag in build/make,
- // which defaults to an empty string when the partition is system.
- // Otherwise, capitalize with a leading _
- if jniLib.partition == "system" {
- partitionTag = ""
- } else {
- split := strings.Split(jniLib.partition, "/")
- partitionTag = "_" + strings.ToUpper(split[len(split)-1])
- }
- entries.AddStrings("LOCAL_SOONG_JNI_LIBS_PARTITION_"+jniLib.target.Arch.ArchType.String(),
- jniLib.name+":"+partitionTag)
+ names = append(names, jniLib.name)
}
+ entries.AddStrings("LOCAL_REQUIRED_MODULES", names...)
}
if len(app.jniCoverageOutputs) > 0 {
@@ -454,9 +436,7 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
entries.SetOptionalPaths("LOCAL_SOONG_LINT_REPORTS", app.linter.reports)
- if app.Name() != "framework-res" {
- android.SetAconfigFileMkEntries(&app.ModuleBase, entries, app.mergedAconfigFiles)
- }
+ entries.AddStrings("LOCAL_SOONG_LOGTAGS_FILES", app.logtagsSrcs.Strings()...)
},
},
ExtraFooters: []android.AndroidMkExtraFootersFunc{
@@ -533,7 +513,6 @@ func (a *AndroidLibrary) AndroidMkEntries() []android.AndroidMkEntries {
entries.SetPath("LOCAL_FULL_MANIFEST_FILE", a.mergedManifestFile)
entries.SetPath("LOCAL_SOONG_EXPORT_PROGUARD_FLAGS", a.combinedExportedProguardFlagsFile)
entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", true)
- android.SetAconfigFileMkEntries(&a.ModuleBase, entries, a.mergedAconfigFiles)
})
return entriesList
diff --git a/java/androidmk_test.go b/java/androidmk_test.go
index 1232cd1ee..243a2791e 100644
--- a/java/androidmk_test.go
+++ b/java/androidmk_test.go
@@ -20,8 +20,6 @@ import (
"android/soong/android"
"android/soong/cc"
-
- "github.com/google/blueprint/proptools"
)
func TestRequired(t *testing.T) {
@@ -161,8 +159,8 @@ func TestJavaSdkLibrary_RequireXmlPermissionFile(t *testing.T) {
moduleName string
expected []string
}{
- {"foo-shared_library", []string{"foo-shared_library.xml"}},
- {"foo-no_shared_library", nil},
+ {"foo-shared_library", []string{"foo-shared_library.impl", "foo-shared_library.xml"}},
+ {"foo-no_shared_library", []string{"foo-no_shared_library.impl"}},
}
for _, tc := range testCases {
mod := result.ModuleForTests(tc.moduleName, "android_common").Module()
@@ -256,148 +254,50 @@ func TestGetOverriddenPackages(t *testing.T) {
}
}
-func TestJniPartition(t *testing.T) {
- bp := `
- cc_library {
- name: "libjni_system",
- system_shared_libs: [],
- sdk_version: "current",
- stl: "none",
- }
-
- cc_library {
- name: "libjni_system_ext",
- system_shared_libs: [],
- sdk_version: "current",
- stl: "none",
- system_ext_specific: true,
- }
-
- cc_library {
- name: "libjni_odm",
- system_shared_libs: [],
- sdk_version: "current",
- stl: "none",
- device_specific: true,
- }
-
- cc_library {
- name: "libjni_product",
- system_shared_libs: [],
- sdk_version: "current",
- stl: "none",
- product_specific: true,
- }
-
- cc_library {
- name: "libjni_vendor",
- system_shared_libs: [],
- sdk_version: "current",
- stl: "none",
- soc_specific: true,
- }
-
- android_app {
- name: "test_app_system_jni_system",
- privileged: true,
- platform_apis: true,
- certificate: "platform",
- jni_libs: ["libjni_system"],
- }
-
+func TestJniAsRequiredDeps(t *testing.T) {
+ ctx := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ cc.PrepareForTestWithCcDefaultModules,
+ android.PrepareForTestWithAndroidMk,
+ ).RunTestWithBp(t, `
android_app {
- name: "test_app_system_jni_system_ext",
- privileged: true,
+ name: "app",
+ jni_libs: ["libjni"],
platform_apis: true,
- certificate: "platform",
- jni_libs: ["libjni_system_ext"],
}
android_app {
- name: "test_app_system_ext_jni_system",
- privileged: true,
+ name: "app_embedded",
+ jni_libs: ["libjni"],
platform_apis: true,
- certificate: "platform",
- jni_libs: ["libjni_system"],
- system_ext_specific: true
- }
-
- android_app {
- name: "test_app_system_ext_jni_system_ext",
- sdk_version: "core_platform",
- jni_libs: ["libjni_system_ext"],
- system_ext_specific: true
+ use_embedded_native_libs: true,
}
- android_app {
- name: "test_app_product_jni_product",
- sdk_version: "core_platform",
- jni_libs: ["libjni_product"],
- product_specific: true
- }
-
- android_app {
- name: "test_app_vendor_jni_odm",
- sdk_version: "core_platform",
- jni_libs: ["libjni_odm"],
- soc_specific: true
+ cc_library {
+ name: "libjni",
+ system_shared_libs: [],
+ stl: "none",
}
+ `)
- android_app {
- name: "test_app_odm_jni_vendor",
- sdk_version: "core_platform",
- jni_libs: ["libjni_vendor"],
- device_specific: true
- }
- android_app {
- name: "test_app_system_jni_multiple",
- privileged: true,
- platform_apis: true,
- certificate: "platform",
- jni_libs: ["libjni_system", "libjni_system_ext"],
- }
- android_app {
- name: "test_app_vendor_jni_multiple",
- sdk_version: "core_platform",
- jni_libs: ["libjni_odm", "libjni_vendor"],
- soc_specific: true
- }
- `
- arch := "arm64"
- ctx := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- cc.PrepareForTestWithCcDefaultModules,
- android.PrepareForTestWithAndroidMk,
- android.FixtureModifyConfig(func(config android.Config) {
- config.TestProductVariables.DeviceArch = proptools.StringPtr(arch)
- }),
- ).
- RunTestWithBp(t, bp)
- testCases := []struct {
- name string
- partitionNames []string
- partitionTags []string
+ testcases := []struct {
+ name string
+ expected []string
}{
- {"test_app_system_jni_system", []string{"libjni_system"}, []string{""}},
- {"test_app_system_jni_system_ext", []string{"libjni_system_ext"}, []string{"_SYSTEM_EXT"}},
- {"test_app_system_ext_jni_system", []string{"libjni_system"}, []string{""}},
- {"test_app_system_ext_jni_system_ext", []string{"libjni_system_ext"}, []string{"_SYSTEM_EXT"}},
- {"test_app_product_jni_product", []string{"libjni_product"}, []string{"_PRODUCT"}},
- {"test_app_vendor_jni_odm", []string{"libjni_odm"}, []string{"_ODM"}},
- {"test_app_odm_jni_vendor", []string{"libjni_vendor"}, []string{"_VENDOR"}},
- {"test_app_system_jni_multiple", []string{"libjni_system", "libjni_system_ext"}, []string{"", "_SYSTEM_EXT"}},
- {"test_app_vendor_jni_multiple", []string{"libjni_odm", "libjni_vendor"}, []string{"_ODM", "_VENDOR"}},
+ {
+ name: "app",
+ expected: []string{"libjni"},
+ },
+ {
+ name: "app_embedded",
+ expected: nil,
+ },
}
- for _, test := range testCases {
- t.Run(test.name, func(t *testing.T) {
- mod := ctx.ModuleForTests(test.name, "android_common").Module()
- entry := android.AndroidMkEntriesForTest(t, ctx.TestContext, mod)[0]
- for i := range test.partitionNames {
- actual := entry.EntryMap["LOCAL_SOONG_JNI_LIBS_PARTITION_"+arch][i]
- expected := test.partitionNames[i] + ":" + test.partitionTags[i]
- android.AssertStringEquals(t, "Expected and actual differ", expected, actual)
- }
- })
+ for _, tc := range testcases {
+ mod := ctx.ModuleForTests(tc.name, "android_common").Module()
+ entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, mod)[0]
+ required := entries.EntryMap["LOCAL_REQUIRED_MODULES"]
+ android.AssertDeepEquals(t, "unexpected required deps", tc.expected, required)
}
}
diff --git a/java/app.go b/java/app.go
index 9736ffd23..d2f2d0be1 100755..100644
--- a/java/app.go
+++ b/java/app.go
@@ -169,9 +169,6 @@ type overridableAppProperties struct {
// binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
// from PRODUCT_PACKAGES.
Overrides []string
-
- // Names of aconfig_declarations modules that specify aconfig flags that the app depends on.
- Flags_packages []string
}
type AndroidApp struct {
@@ -252,13 +249,13 @@ func (c Certificate) AndroidMkString() string {
}
func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
- a.Module.deps(ctx)
-
if String(a.appProperties.Stl) == "c++_shared" && !a.SdkVersion(ctx).Specified() {
ctx.PropertyErrorf("stl", "sdk_version must be set in order to use c++_shared")
}
sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
+ a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs())
+ a.Module.deps(ctx)
if sdkDep.hasFrameworkLibs() {
a.aapt.deps(ctx, sdkDep)
}
@@ -277,19 +274,41 @@ func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
variation := append(jniTarget.Variations(),
blueprint.Variation{Mutator: "link", Variation: "shared"})
- // If the app builds against an Android SDK use the SDK variant of JNI dependencies
- // unless jni_uses_platform_apis is set.
- // Don't require the SDK variant for apps that are shipped on vendor, etc., as they already
- // have stable APIs through the VNDK.
- if (usesSDK && !a.RequiresStableAPIs(ctx) &&
- !Bool(a.appProperties.Jni_uses_platform_apis)) ||
- Bool(a.appProperties.Jni_uses_sdk_apis) {
+ // Test whether to use the SDK variant or the non-SDK variant of JNI dependencies.
+ // Many factors are considered here.
+ // 1. Basically, the selection follows whether the app has sdk_version set or not.
+ jniUsesSdkVariant := usesSDK
+ // 2. However, jni_uses_platform_apis and jni_uses_sdk_apis can override it
+ if Bool(a.appProperties.Jni_uses_sdk_apis) {
+ jniUsesSdkVariant = true
+ }
+ if Bool(a.appProperties.Jni_uses_platform_apis) {
+ jniUsesSdkVariant = false
+ }
+ // 3. Then the use of SDK variant is again prohibited for the following cases:
+ // 3.1. the app is shipped on unbundled partitions like vendor. Since the entire
+ // partition (not only the app) is considered unbudled, there's no need to use the
+ // SDK variant.
+ // 3.2. the app doesn't support embedding the JNI libs
+ if a.RequiresStableAPIs(ctx) || !a.shouldEmbedJnis(ctx) {
+ jniUsesSdkVariant = false
+ }
+ if jniUsesSdkVariant {
variation = append(variation, blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
}
- ctx.AddFarVariationDependencies(variation, jniLibTag, a.appProperties.Jni_libs...)
- }
- a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs())
+ // Use the installable dep tag when the JNIs are not embedded
+ var tag dependencyTag
+ if a.shouldEmbedJnis(ctx) {
+ tag = jniLibTag
+ } else {
+ tag = jniInstallTag
+ }
+ ctx.AddFarVariationDependencies(variation, tag, a.appProperties.Jni_libs...)
+ }
+ for _, aconfig_declaration := range a.aaptProperties.Flags_packages {
+ ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
+ }
}
func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
@@ -317,10 +336,6 @@ func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutato
`must be names of android_app_certificate modules in the form ":module"`)
}
}
-
- for _, aconfig_declaration := range a.overridableAppProperties.Flags_packages {
- ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
- }
}
func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -332,31 +347,25 @@ func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleCon
a.aapt.manifestValues.applicationId = *applicationId
}
a.generateAndroidBuildActions(ctx)
+ android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
+ TestOnly: true,
+ })
+
}
func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.checkAppSdkVersions(ctx)
+ a.checkEmbedJnis(ctx)
a.generateAndroidBuildActions(ctx)
a.generateJavaUsedByApex(ctx)
}
-func (a *AndroidApp) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
- defaultMinSdkVersion := a.Module.MinSdkVersion(ctx)
- if proptools.Bool(a.appProperties.Updatable) {
- overrideApiLevel := android.MinSdkVersionFromValue(ctx, ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride())
- if !overrideApiLevel.IsNone() && overrideApiLevel.CompareTo(defaultMinSdkVersion) > 0 {
- return overrideApiLevel
- }
- }
- return defaultMinSdkVersion
-}
-
func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
if a.Updatable() {
if !a.SdkVersion(ctx).Stable() {
ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.SdkVersion(ctx))
}
- if String(a.deviceProperties.Min_sdk_version) == "" {
+ if String(a.overridableProperties.Min_sdk_version) == "" {
ctx.PropertyErrorf("updatable", "updatable apps must set min_sdk_version.")
}
@@ -380,6 +389,17 @@ func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
a.checkSdkVersions(ctx)
}
+// Ensures that use_embedded_native_libs are set for apk-in-apex
+func (a *AndroidApp) checkEmbedJnis(ctx android.BaseModuleContext) {
+ apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
+ apkInApex := !apexInfo.IsForPlatform()
+ hasJnis := len(a.appProperties.Jni_libs) > 0
+
+ if apkInApex && hasJnis && !Bool(a.appProperties.Use_embedded_native_libs) {
+ ctx.ModuleErrorf("APK in APEX should have use_embedded_native_libs: true")
+ }
+}
+
// If an updatable APK sets min_sdk_version, min_sdk_vesion of JNI libs should match with it.
// This check is enforced for "updatable" APKs (including APK-in-APEX).
func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
@@ -435,9 +455,9 @@ func (a *AndroidApp) shouldUncompressDex(ctx android.ModuleContext) bool {
}
func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool {
- apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
return ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) ||
- !apexInfo.IsForPlatform() || a.appProperties.AlwaysPackageNativeLibs
+ Bool(a.appProperties.Updatable) ||
+ a.appProperties.AlwaysPackageNativeLibs
}
func generateAaptRenamePackageFlags(packageName string, renameResourcesPackage bool) []string {
@@ -457,6 +477,21 @@ func (a *AndroidApp) renameResourcesPackage() bool {
return proptools.BoolDefault(a.overridableAppProperties.Rename_resources_package, true)
}
+func getAconfigFilePaths(ctx android.ModuleContext) (aconfigTextFilePaths android.Paths) {
+ ctx.VisitDirectDepsWithTag(aconfigDeclarationTag, func(dep android.Module) {
+ if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
+ aconfigTextFilePaths = append(aconfigTextFilePaths, provider.IntermediateDumpOutputPath)
+ } else {
+ ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+
+ "flags_packages property, but %s is not aconfig_declarations module type",
+ dep.Name(),
+ )
+ }
+ })
+
+ return aconfigTextFilePaths
+}
+
func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
usePlatformAPI := proptools.Bool(a.Module.deviceProperties.Platform_apis)
if ctx.Module().(android.SdkContext).SdkVersion(ctx).Kind == android.SdkModule {
@@ -507,26 +542,18 @@ func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
a.aapt.defaultManifestVersion = android.DefaultUpdatableModuleVersion
}
- var aconfigTextFilePaths android.Paths
- ctx.VisitDirectDepsWithTag(aconfigDeclarationTag, func(dep android.Module) {
- if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
- aconfigTextFilePaths = append(aconfigTextFilePaths, provider.IntermediateDumpOutputPath)
- } else {
- ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+
- "flags_packages property, but %s is not aconfig_declarations module type",
- dep.Name(),
- )
- }
- })
-
+ // Use non final ids if we are doing optimized shrinking and are using R8.
+ nonFinalIds := a.dexProperties.optimizedResourceShrinkingEnabled(ctx) && a.dexer.effectiveOptimizeEnabled()
a.aapt.buildActions(ctx,
aaptBuildActionOptions{
sdkContext: android.SdkContext(a),
classLoaderContexts: a.classLoaderContexts,
excludedLibs: a.usesLibraryProperties.Exclude_uses_libs,
enforceDefaultTargetSdkVersion: a.enforceDefaultTargetSdkVersion(),
+ forceNonFinalResourceIDs: nonFinalIds,
extraLinkFlags: aaptLinkFlags,
- aconfigTextFiles: aconfigTextFilePaths,
+ aconfigTextFiles: getAconfigFilePaths(ctx),
+ usesLibrary: &a.usesLibrary,
},
)
@@ -547,7 +574,13 @@ func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) {
staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles)
a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, staticLibProguardFlagFiles...)
- a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, a.proguardOptionsFile)
+ if !(a.dexProperties.optimizedResourceShrinkingEnabled(ctx)) {
+ // When using the optimized shrinking the R8 enqueuer will traverse the xml files that become
+ // live for code references and (transitively) mark these as live.
+ // In this case we explicitly don't wan't the aapt2 generated keep files (which would keep the now
+ // dead code alive)
+ a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, a.proguardOptionsFile)
+ }
}
func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath {
@@ -580,7 +613,7 @@ func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, a
var packageResources = a.exportPackage
if ctx.ModuleName() != "framework-res" {
- if Bool(a.dexProperties.Optimize.Shrink_resources) {
+ if a.dexProperties.resourceShrinkingEnabled(ctx) {
protoFile := android.PathForModuleOut(ctx, packageResources.Base()+".proto.apk")
aapt2Convert(ctx, protoFile, packageResources, "proto")
a.dexer.resourcesInput = android.OptionalPathForPath(protoFile)
@@ -603,7 +636,7 @@ func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, a
}
a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars)
- if Bool(a.dexProperties.Optimize.Shrink_resources) {
+ if a.dexProperties.resourceShrinkingEnabled(ctx) {
binaryResources := android.PathForModuleOut(ctx, packageResources.Base()+".binary.out.apk")
aapt2Convert(ctx, binaryResources, a.dexer.resourcesOutput.Path(), "binary")
packageResources = binaryResources
@@ -755,7 +788,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
// 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())
+ a.stem = proptools.StringDefault(a.overridableProperties.Stem, ctx.ModuleName())
// Check if the install APK name needs to be overridden.
// Both android_app and override_android_app module are expected to possess
@@ -763,7 +796,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
// 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()))
+ proptools.StringDefault(a.overridableProperties.Stem, a.Name()))
if ctx.ModuleName() == "framework-res" {
// framework-res.apk is installed as system/framework/framework-res.apk
@@ -802,18 +835,10 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
// The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
a.usesLibrary.freezeEnforceUsesLibraries()
- // Add implicit SDK libraries to <uses-library> list.
- requiredUsesLibs, optionalUsesLibs := a.classLoaderContexts.UsesLibs()
- for _, usesLib := range requiredUsesLibs {
- a.usesLibrary.addLib(usesLib, false)
- }
- for _, usesLib := range optionalUsesLibs {
- a.usesLibrary.addLib(usesLib, true)
- }
-
// Check that the <uses-library> list is coherent with the manifest.
if a.usesLibrary.enforceUsesLibraries() {
- manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(ctx, a.mergedManifestFile)
+ manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(
+ ctx, a.mergedManifestFile, &a.classLoaderContexts)
apkDeps = append(apkDeps, manifestCheckFile)
}
@@ -826,7 +851,9 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
dexJarFile, packageResources := a.dexBuildActions(ctx)
- jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), !Bool(a.appProperties.Jni_uses_platform_apis))
+ // No need to check the SDK version of the JNI deps unless we embed them
+ checkNativeSdkVersion := a.shouldEmbedJnis(ctx) && !Bool(a.appProperties.Jni_uses_platform_apis)
+ jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), checkNativeSdkVersion)
jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx)
if ctx.Failed() {
@@ -908,10 +935,33 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
installed := ctx.InstallFile(a.installDir, extra.Base(), extra)
extraInstalledPaths = append(extraInstalledPaths, installed)
}
+ // If we don't embed jni libs, make sure that those are installed along with the
+ // app, and also place symlinks to the installed paths under the lib/<arch>
+ // directory of the app installation directory. ex:
+ // /system/app/MyApp/lib/arm64/libfoo.so -> /system/lib64/libfoo.so
+ if !a.embeddedJniLibs {
+ for _, jniLib := range jniLibs {
+ archStr := jniLib.target.Arch.ArchType.String()
+ symlinkDir := a.installDir.Join(ctx, "lib", archStr)
+ for _, installedLib := range jniLib.installPaths {
+ // install the symlink itself
+ symlinkName := installedLib.Base()
+ symlinkTarget := android.InstallPathToOnDevicePath(ctx, installedLib)
+ ctx.InstallAbsoluteSymlink(symlinkDir, symlinkName, symlinkTarget)
+ }
+ }
+ }
ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...)
}
a.buildAppDependencyInfo(ctx)
+
+ providePrebuiltInfo(ctx,
+ prebuiltInfoProps{
+ baseModuleName: a.BaseModuleName(),
+ isPrebuilt: false,
+ },
+ )
}
type appDepsInterface interface {
@@ -988,6 +1038,7 @@ func collectJniDeps(ctx android.ModuleContext,
coverageFile: dep.CoverageOutputFile(),
unstrippedFile: dep.UnstrippedOutputFile(),
partition: dep.Partition(),
+ installPaths: dep.FilesToInstall(),
})
} else if ctx.Config().AllowMissingDependencies() {
ctx.AddMissingDependencies([]string{otherName})
@@ -1175,7 +1226,8 @@ func AndroidAppFactory() android.Module {
module.AddProperties(
&module.aaptProperties,
&module.appProperties,
- &module.overridableAppProperties)
+ &module.overridableAppProperties,
+ &module.Library.sourceProperties)
module.usesLibrary.enforce = true
@@ -1232,6 +1284,11 @@ func AndroidAppFactory() android.Module {
Manifest: proptools.StringPtr(":" + rroManifestName),
Resource_dirs: a.aaptProperties.Resource_dirs,
}
+ if !Bool(a.aaptProperties.Aapt_include_all_resources) {
+ for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
+ rroProperties.Aaptflags = append(rroProperties.Aaptflags, "-c", aaptConfig)
+ }
+ }
ctx.CreateModule(RuntimeResourceOverlayFactory, &rroProperties)
})
@@ -1316,6 +1373,19 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs)
a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
android.SetProvider(ctx, testing.TestModuleProviderKey, testing.TestModuleProviderData{})
+ android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
+ InstalledFiles: a.data,
+ OutputFile: a.OutputFile(),
+ TestConfig: a.testConfig,
+ HostRequiredModuleNames: a.HostRequiredModuleNames(),
+ TestSuites: a.testProperties.Test_suites,
+ IsHost: false,
+ })
+ android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
+ TestOnly: true,
+ TopLevelTarget: true,
+ })
+
}
func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path {
@@ -1494,7 +1564,7 @@ func (i *OverrideAndroidApp) GenerateAndroidBuildActions(_ android.ModuleContext
func OverrideAndroidAppModuleFactory() android.Module {
m := &OverrideAndroidApp{}
m.AddProperties(
- &OverridableDeviceProperties{},
+ &OverridableProperties{},
&overridableAppProperties{},
)
@@ -1508,9 +1578,13 @@ type OverrideAndroidTest struct {
android.OverrideModuleBase
}
-func (i *OverrideAndroidTest) GenerateAndroidBuildActions(_ android.ModuleContext) {
+func (i *OverrideAndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// All the overrides happen in the base module.
// TODO(jungjw): Check the base module type.
+ android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
+ TestOnly: true,
+ TopLevelTarget: true,
+ })
}
// override_android_test is used to create an android_app module based on another android_test by overriding
@@ -1558,6 +1632,9 @@ type UsesLibraryProperties struct {
// provide the android.test.base statically and use jarjar to rename them so they do not collide
// with the classes provided by the android.test.base library.
Exclude_uses_libs []string
+
+ // The module names of optional uses-library libraries that are missing from the source tree.
+ Missing_optional_uses_libs []string `blueprint:"mutated"`
}
// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the
@@ -1574,20 +1651,11 @@ type usesLibrary struct {
shouldDisableDexpreopt bool
}
-func (u *usesLibrary) addLib(lib string, optional bool) {
- if !android.InList(lib, u.usesLibraryProperties.Uses_libs) && !android.InList(lib, u.usesLibraryProperties.Optional_uses_libs) {
- if optional {
- u.usesLibraryProperties.Optional_uses_libs = append(u.usesLibraryProperties.Optional_uses_libs, lib)
- } else {
- u.usesLibraryProperties.Uses_libs = append(u.usesLibraryProperties.Uses_libs, lib)
- }
- }
-}
-
func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps bool) {
if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() {
ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs...)
- ctx.AddVariationDependencies(nil, usesLibOptTag, u.presentOptionalUsesLibs(ctx)...)
+ presentOptionalUsesLibs := u.presentOptionalUsesLibs(ctx)
+ ctx.AddVariationDependencies(nil, usesLibOptTag, presentOptionalUsesLibs...)
// Only add these extra dependencies if the module is an app that depends on framework
// libs. This avoids creating a cyclic dependency:
// e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res.
@@ -1598,6 +1666,8 @@ func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps boo
ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...)
ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...)
}
+ _, diff, _ := android.ListSetDifference(u.usesLibraryProperties.Optional_uses_libs, presentOptionalUsesLibs)
+ u.usesLibraryProperties.Missing_optional_uses_libs = diff
} else {
ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.usesLibraryProperties.Uses_libs...)
ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.presentOptionalUsesLibs(ctx)...)
@@ -1616,15 +1686,6 @@ func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []s
return optionalUsesLibs
}
-// Helper function to replace string in a list.
-func replaceInList(list []string, oldstr, newstr string) {
- for i, str := range list {
- if str == oldstr {
- list[i] = newstr
- }
- }
-}
-
// Returns a map of module names of shared library dependencies to the paths to their dex jars on
// host and on device.
func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext) dexpreopt.ClassLoaderContextMap {
@@ -1666,11 +1727,6 @@ func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext
libName := dep
if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil {
libName = *ulib.ProvidesUsesLib()
- // Replace module name with library name in `uses_libs`/`optional_uses_libs` in
- // order to pass verify_uses_libraries check (which compares these properties
- // against library names written in the manifest).
- replaceInList(u.usesLibraryProperties.Uses_libs, dep, libName)
- replaceInList(u.usesLibraryProperties.Optional_uses_libs, dep, libName)
}
clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional,
lib.DexJarBuildPath(ctx).PathOrNil(), lib.DexJarInstallPath(),
@@ -1704,7 +1760,7 @@ func (u *usesLibrary) freezeEnforceUsesLibraries() {
// an APK with the manifest embedded in it (manifest_check will know which one it is by the file
// extension: APKs are supposed to end with '.apk').
func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile android.Path,
- outputFile android.WritablePath) android.Path {
+ outputFile android.WritablePath, classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
statusFile := dexpreopt.UsesLibrariesStatusFile(ctx)
@@ -1732,27 +1788,37 @@ func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile a
cmd.Flag("--enforce-uses-libraries-relax")
}
- for _, lib := range u.usesLibraryProperties.Uses_libs {
+ requiredUsesLibs, optionalUsesLibs := classLoaderContexts.UsesLibs()
+ for _, lib := range requiredUsesLibs {
cmd.FlagWithArg("--uses-library ", lib)
}
-
- for _, lib := range u.usesLibraryProperties.Optional_uses_libs {
+ for _, lib := range optionalUsesLibs {
cmd.FlagWithArg("--optional-uses-library ", lib)
}
+ // Also add missing optional uses libs, as the manifest check expects them.
+ // Note that what we add here are the module names of those missing libs, not library names, while
+ // the manifest check actually expects library names. However, the case where a library is missing
+ // and the module name != the library name is too rare for us to handle.
+ for _, lib := range u.usesLibraryProperties.Missing_optional_uses_libs {
+ cmd.FlagWithArg("--missing-optional-uses-library ", lib)
+ }
+
rule.Build("verify_uses_libraries", "verify <uses-library>")
return outputFile
}
// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against
// the build system and returns the path to a copy of the manifest.
-func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path) android.Path {
+func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path,
+ classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
- return u.verifyUsesLibraries(ctx, manifest, outputFile)
+ return u.verifyUsesLibraries(ctx, manifest, outputFile, classLoaderContexts)
}
// 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) {
- u.verifyUsesLibraries(ctx, apk, nil) // for APKs manifest_check does not write output file
+func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path,
+ classLoaderContexts *dexpreopt.ClassLoaderContextMap) {
+ u.verifyUsesLibraries(ctx, apk, nil, classLoaderContexts) // for APKs manifest_check does not write output file
}
diff --git a/java/app_import.go b/java/app_import.go
index dc84fc26d..dc8470da7 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -87,9 +87,6 @@ type AndroidAppImport struct {
hideApexVariantFromMake bool
provenanceMetaDataFile android.OutputPath
-
- // Single aconfig "cache file" merged from this module and all dependencies.
- mergedAconfigFiles map[string]android.Paths
}
type AndroidAppImportProperties struct {
@@ -150,6 +147,11 @@ type AndroidAppImportProperties struct {
// If unspecified, follows the naming convention that the source module of
// the prebuilt is Name() without "prebuilt_" prefix
Source_module_name *string
+
+ // Path to the .prebuilt_info file of the prebuilt app.
+ // In case of mainline modules, the .prebuilt_info file contains the build_id that was used
+ // to generate the prebuilt.
+ Prebuilt_info *string `android:"path"`
}
func (a *AndroidAppImport) IsInstallable() bool {
@@ -350,7 +352,7 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext
}
if a.usesLibrary.enforceUsesLibraries() {
- a.usesLibrary.verifyUsesLibrariesAPK(ctx, srcApk)
+ a.usesLibrary.verifyUsesLibrariesAPK(ctx, srcApk, &a.dexpreopter.classLoaderContexts)
}
a.dexpreopter.dexpreopt(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), jnisUncompressed)
@@ -411,7 +413,14 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext
artifactPath := android.PathForModuleSrc(ctx, *a.properties.Apk)
a.provenanceMetaDataFile = provenance.GenerateArtifactProvenanceMetaData(ctx, artifactPath, a.installPath)
}
- android.CollectDependencyAconfigFiles(ctx, &a.mergedAconfigFiles)
+
+ providePrebuiltInfo(ctx,
+ prebuiltInfoProps{
+ baseModuleName: a.BaseModuleName(),
+ isPrebuilt: true,
+ prebuiltInfo: a.properties.Prebuilt_info,
+ },
+ )
// TODO: androidmk converter jni libs
}
@@ -598,6 +607,12 @@ func createArchDpiVariantGroupType(archNames []string, dpiNames []string) reflec
return return_struct
}
+func (a *AndroidAppImport) UsesLibrary() *usesLibrary {
+ return &a.usesLibrary
+}
+
+var _ ModuleWithUsesLibrary = (*AndroidAppImport)(nil)
+
// android_app_import imports a prebuilt apk with additional processing specified in the module.
// DPI-specific apk source files can be specified using dpi_variants. Example:
//
diff --git a/java/app_import_test.go b/java/app_import_test.go
index 5de50e794..496fc1308 100644
--- a/java/app_import_test.go
+++ b/java/app_import_test.go
@@ -509,7 +509,7 @@ func TestAndroidAppImport_ArchVariants(t *testing.T) {
variant := ctx.ModuleForTests("foo", "android_common")
if test.expected == "" {
- if variant.Module().Enabled() {
+ if variant.Module().Enabled(android.PanickingConfigAndErrorContext(ctx)) {
t.Error("module should have been disabled, but wasn't")
}
rule := variant.MaybeRule("genProvenanceMetaData")
@@ -586,7 +586,7 @@ func TestAndroidAppImport_SoongConfigVariables(t *testing.T) {
variant := ctx.ModuleForTests("foo", "android_common")
if test.expected == "" {
- if variant.Module().Enabled() {
+ if variant.Module().Enabled(android.PanickingConfigAndErrorContext(ctx)) {
t.Error("module should have been disabled, but wasn't")
}
rule := variant.MaybeRule("genProvenanceMetaData")
@@ -629,7 +629,7 @@ func TestAndroidAppImport_overridesDisabledAndroidApp(t *testing.T) {
if !a.prebuilt.UsePrebuilt() {
t.Errorf("prebuilt foo module is not active")
}
- if !a.Enabled() {
+ if !a.Enabled(android.PanickingConfigAndErrorContext(ctx)) {
t.Errorf("prebuilt foo module is disabled")
}
}
diff --git a/java/app_set.go b/java/app_set.go
index d2d3b06ba..33d3adec2 100644
--- a/java/app_set.go
+++ b/java/app_set.go
@@ -48,6 +48,11 @@ type AndroidAppSetProperties struct {
// Names of modules to be overridden. Listed modules can only be other apps
// (in Make or Soong).
Overrides []string
+
+ // Path to the .prebuilt_info file of the prebuilt app.
+ // In case of mainline modules, the .prebuilt_info file contains the build_id that was used
+ // to generate the prebuilt.
+ Prebuilt_info *string `android:"path"`
}
type AndroidAppSet struct {
@@ -117,6 +122,27 @@ func SupportedAbis(ctx android.ModuleContext, excludeNativeBridgeAbis bool) []st
return result
}
+type prebuiltInfoProps struct {
+ baseModuleName string
+ isPrebuilt bool
+ prebuiltInfo *string
+}
+
+// Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file
+// with information about whether source or prebuilt of an apex was used during the build.
+func providePrebuiltInfo(ctx android.ModuleContext, p prebuiltInfoProps) {
+ info := android.PrebuiltInfo{
+ Name: p.baseModuleName,
+ Is_prebuilt: p.isPrebuilt,
+ }
+ // If Prebuilt_info information is available in the soong module definition, add it to prebuilt_info.json.
+ if p.prebuiltInfo != nil {
+ prebuiltInfoFile := android.PathForModuleSrc(ctx, *p.prebuiltInfo)
+ info.Prebuilt_info_file_path = prebuiltInfoFile.String()
+ }
+ android.SetProvider(ctx, android.PrebuiltInfoProvider, info)
+}
+
func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
as.packedOutput = android.PathForModuleOut(ctx, ctx.ModuleName()+".zip")
as.primaryOutput = android.PathForModuleOut(ctx, as.BaseModuleName()+".apk")
@@ -157,6 +183,15 @@ func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext)
installDir = android.PathForModuleInstall(ctx, "app", as.BaseModuleName())
}
ctx.InstallFileWithExtraFilesZip(installDir, as.BaseModuleName()+".apk", as.primaryOutput, as.packedOutput)
+
+ providePrebuiltInfo(ctx,
+ prebuiltInfoProps{
+ baseModuleName: as.BaseModuleName(),
+ isPrebuilt: true,
+ prebuiltInfo: as.properties.Prebuilt_info,
+ },
+ )
+
}
func (as *AndroidAppSet) InstallBypassMake() bool { return true }
diff --git a/java/app_test.go b/java/app_test.go
index 28bea0a2b..804949435 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -829,12 +829,12 @@ func TestAndroidResourceProcessor(t *testing.T) {
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
"out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
"out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.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",
+ "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
},
directResources: nil,
@@ -849,12 +849,12 @@ func TestAndroidResourceProcessor(t *testing.T) {
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",
+ "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.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",
+ "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar",
},
transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"},
@@ -928,13 +928,13 @@ func TestAndroidResourceProcessor(t *testing.T) {
"out/soong/.intermediates/app/android_common/busybox/R.jar",
"out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
"out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
},
appCombined: []string{
"out/soong/.intermediates/app/android_common/javac/app.jar",
"out/soong/.intermediates/app/android_common/busybox/R.jar",
"out/soong/.intermediates/direct/android_common/combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
},
directResources: nil,
@@ -948,17 +948,17 @@ func TestAndroidResourceProcessor(t *testing.T) {
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/busybox/R.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar",
+ "out/soong/.intermediates/transitive_import/android_common/busybox/R.jar",
"out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.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",
+ "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar",
},
transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"},
@@ -981,9 +981,9 @@ func TestAndroidResourceProcessor(t *testing.T) {
sharedSrcJars: nil,
sharedClasspath: []string{
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
+ "out/soong/.intermediates/shared/android_common/busybox/R.jar",
"out/soong/.intermediates/shared_transitive_static/android_common/busybox/R.jar",
"out/soong/.intermediates/shared_transitive_shared/android_common/busybox/R.jar",
- "out/soong/.intermediates/shared/android_common/busybox/R.jar",
"out/soong/.intermediates/shared_transitive_shared/android_common/turbine-combined/shared_transitive_shared.jar",
"out/soong/.intermediates/shared_transitive_static/android_common/turbine-combined/shared_transitive_static.jar",
},
@@ -1034,13 +1034,13 @@ func TestAndroidResourceProcessor(t *testing.T) {
"out/soong/.intermediates/app/android_common/busybox/R.jar",
"out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
"out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
},
appCombined: []string{
"out/soong/.intermediates/app/android_common/javac/app.jar",
"out/soong/.intermediates/app/android_common/busybox/R.jar",
"out/soong/.intermediates/direct/android_common/combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
},
dontVerifyDirect: true,
@@ -1075,12 +1075,12 @@ func TestAndroidResourceProcessor(t *testing.T) {
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
"out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
"out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.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",
+ "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
},
directResources: nil,
@@ -1094,16 +1094,16 @@ func TestAndroidResourceProcessor(t *testing.T) {
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_import_dep/android_common/busybox/R.jar",
+ "out/soong/.intermediates/transitive_import/android_common/busybox/R.jar",
"out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.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",
+ "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar",
},
dontVerifyTransitive: true,
@@ -1137,12 +1137,12 @@ func TestAndroidResourceProcessor(t *testing.T) {
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
"out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
"out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.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",
+ "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
},
directResources: nil,
@@ -1157,12 +1157,12 @@ func TestAndroidResourceProcessor(t *testing.T) {
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",
+ "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.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",
+ "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar",
},
transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"},
@@ -3244,7 +3244,10 @@ func TestUsesLibraries(t *testing.T) {
name: "static-y",
srcs: ["a.java"],
uses_libs: ["runtime-required-y"],
- optional_uses_libs: ["runtime-optional-y"],
+ optional_uses_libs: [
+ "runtime-optional-y",
+ "missing-lib-a",
+ ],
sdk_version: "current",
}
@@ -3280,7 +3283,7 @@ func TestUsesLibraries(t *testing.T) {
sdk_version: "current",
optional_uses_libs: [
"bar",
- "baz",
+ "missing-lib-b",
],
}
@@ -3295,7 +3298,7 @@ func TestUsesLibraries(t *testing.T) {
],
optional_uses_libs: [
"bar",
- "baz",
+ "missing-lib-b",
],
}
`
@@ -3317,10 +3320,10 @@ func TestUsesLibraries(t *testing.T) {
// propagated from dependencies.
actualManifestFixerArgs := app.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
expectManifestFixerArgs := `--extract-native-libs=true ` +
- `--uses-library qux ` +
- `--uses-library quuz ` +
`--uses-library foo ` +
`--uses-library com.non.sdk.lib ` +
+ `--uses-library qux ` +
+ `--uses-library quuz ` +
`--uses-library runtime-library ` +
`--uses-library runtime-required-x ` +
`--uses-library runtime-required-y ` +
@@ -3339,9 +3342,10 @@ func TestUsesLibraries(t *testing.T) {
`--uses-library runtime-required-x ` +
`--uses-library runtime-required-y ` +
`--optional-uses-library bar ` +
- `--optional-uses-library baz ` +
`--optional-uses-library runtime-optional-x ` +
- `--optional-uses-library runtime-optional-y `
+ `--optional-uses-library runtime-optional-y ` +
+ `--missing-optional-uses-library missing-lib-b ` +
+ `--missing-optional-uses-library missing-lib-a`
android.AssertStringDoesContain(t, "verify cmd args", verifyCmd, verifyArgs)
// Test that all libraries are verified for an APK (library order matters).
@@ -3350,7 +3354,7 @@ func TestUsesLibraries(t *testing.T) {
`--uses-library com.non.sdk.lib ` +
`--uses-library android.test.runner ` +
`--optional-uses-library bar ` +
- `--optional-uses-library baz `
+ `--missing-optional-uses-library missing-lib-b `
android.AssertStringDoesContain(t, "verify apk cmd args", verifyApkCmd, verifyApkArgs)
// Test that necessary args are passed for constructing CLC in Ninja phase.
@@ -3625,7 +3629,10 @@ func TestExportedProguardFlagFiles(t *testing.T) {
android_app {
name: "foo",
sdk_version: "current",
- static_libs: ["lib1"],
+ static_libs: [
+ "lib1",
+ "lib3",
+ ],
}
android_library {
@@ -3633,22 +3640,49 @@ func TestExportedProguardFlagFiles(t *testing.T) {
sdk_version: "current",
optimize: {
proguard_flags_files: ["lib1proguard.cfg"],
+ },
+ static_libs: ["lib2"],
+ }
+
+ android_library {
+ name: "lib2",
+ sdk_version: "current",
+ optimize: {
+ proguard_flags_files: ["lib2proguard.cfg"],
}
}
- `)
- m := ctx.ModuleForTests("foo", "android_common")
- hasLib1Proguard := false
- for _, s := range m.Rule("java.r8").Implicits.Strings() {
- if s == "lib1proguard.cfg" {
- hasLib1Proguard = true
- break
+ android_library_import {
+ name: "lib3",
+ sdk_version: "current",
+ aars: ["lib3.aar"],
+ static_libs: ["lib4"],
}
- }
- if !hasLib1Proguard {
- t.Errorf("App does not use library proguard config")
- }
+ android_library {
+ name: "lib4",
+ sdk_version: "current",
+ optimize: {
+ proguard_flags_files: ["lib4proguard.cfg"],
+ }
+ }
+
+
+ `)
+
+ m := ctx.ModuleForTests("foo", "android_common")
+ r8 := m.Rule("java.r8")
+ implicits := r8.Implicits.RelativeToTop().Strings()
+ android.AssertStringListContains(t, "r8 implicits", implicits, "lib1proguard.cfg")
+ android.AssertStringListContains(t, "r8 implicits", implicits, "lib2proguard.cfg")
+ android.AssertStringListContains(t, "r8 implicits", implicits, "lib4proguard.cfg")
+ android.AssertStringListContains(t, "r8 implicits", implicits, "out/soong/.intermediates/lib3/android_common/aar/proguard.txt")
+
+ flags := r8.Args["r8Flags"]
+ android.AssertStringDoesContain(t, "r8 flags", flags, "-include lib1proguard.cfg")
+ android.AssertStringDoesContain(t, "r8 flags", flags, "-include lib2proguard.cfg")
+ android.AssertStringDoesContain(t, "r8 flags", flags, "-include lib4proguard.cfg")
+ android.AssertStringDoesContain(t, "r8 flags", flags, "-include out/soong/.intermediates/lib3/android_common/aar/proguard.txt")
}
func TestTargetSdkVersionManifestFixer(t *testing.T) {
@@ -4288,52 +4322,6 @@ func TestPrivappAllowlistAndroidMk(t *testing.T) {
)
}
-func TestApexGlobalMinSdkVersionOverride(t *testing.T) {
- result := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.ApexGlobalMinSdkVersionOverride = proptools.StringPtr("Tiramisu")
- }),
- ).RunTestWithBp(t, `
- android_app {
- name: "com.android.bar",
- srcs: ["a.java"],
- sdk_version: "current",
- }
- android_app {
- name: "com.android.foo",
- srcs: ["a.java"],
- sdk_version: "current",
- min_sdk_version: "S",
- updatable: true,
- }
- override_android_app {
- name: "com.android.go.foo",
- base: "com.android.foo",
- }
- `)
- foo := result.ModuleForTests("com.android.foo", "android_common").Rule("manifestFixer")
- fooOverride := result.ModuleForTests("com.android.foo", "android_common_com.android.go.foo").Rule("manifestFixer")
- bar := result.ModuleForTests("com.android.bar", "android_common").Rule("manifestFixer")
-
- android.AssertStringDoesContain(t,
- "expected manifest fixer to set com.android.bar minSdkVersion to S",
- bar.BuildParams.Args["args"],
- "--minSdkVersion S",
- )
- android.AssertStringDoesContain(t,
- "com.android.foo: expected manifest fixer to set minSdkVersion to T",
- foo.BuildParams.Args["args"],
- "--minSdkVersion T",
- )
- android.AssertStringDoesContain(t,
- "com.android.go.foo: expected manifest fixer to set minSdkVersion to T",
- fooOverride.BuildParams.Args["args"],
- "--minSdkVersion T",
- )
-
-}
-
func TestAppFlagsPackages(t *testing.T) {
ctx := testApp(t, `
android_app {
@@ -4348,6 +4336,7 @@ func TestAppFlagsPackages(t *testing.T) {
aconfig_declarations {
name: "bar",
package: "com.example.package.bar",
+ container: "com.android.foo",
srcs: [
"bar.aconfig",
],
@@ -4355,6 +4344,7 @@ func TestAppFlagsPackages(t *testing.T) {
aconfig_declarations {
name: "baz",
package: "com.example.package.baz",
+ container: "com.android.foo",
srcs: [
"baz.aconfig",
],
@@ -4401,3 +4391,91 @@ func TestNoDexpreoptOptionalUsesLibDoesNotHaveImpl(t *testing.T) {
dexpreopt := result.ModuleForTests("app", "android_common").MaybeRule("dexpreopt").Rule
android.AssertBoolEquals(t, "dexpreopt should be disabled if optional_uses_libs does not have an implementation", true, dexpreopt == nil)
}
+
+func TestTestOnlyApp(t *testing.T) {
+ t.Parallel()
+ ctx := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ ).RunTestWithBp(t, `
+ // These should be test-only
+ android_test {
+ name: "android-test",
+ }
+ android_test_helper_app {
+ name: "helper-app",
+ }
+ override_android_test {
+ name: "override-test",
+ base: "android-app",
+ }
+ // And these should not be
+ android_app {
+ name: "android-app",
+ srcs: ["b.java"],
+ sdk_version: "current",
+ }
+ `)
+
+ expectedTestOnly := []string{
+ "android-test",
+ "helper-app",
+ "override-test",
+ }
+
+ expectedTopLevel := []string{
+ "android-test",
+ "override-test",
+ }
+
+ assertTestOnlyAndTopLevel(t, ctx, expectedTestOnly, expectedTopLevel)
+}
+
+func TestAppStem(t *testing.T) {
+ ctx := testApp(t, `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ stem: "foo-new",
+ sdk_version: "current",
+ }`)
+
+ foo := ctx.ModuleForTests("foo", "android_common")
+
+ outputs := fmt.Sprint(foo.AllOutputs())
+ if !strings.Contains(outputs, "foo-new.apk") {
+ t.Errorf("Module output does not contain expected apk %s", "foo-new.apk")
+ }
+}
+
+func TestAppMinSdkVersionOverride(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ ).RunTestWithBp(t, `
+ android_app {
+ name: "com.android.foo",
+ srcs: ["a.java"],
+ sdk_version: "current",
+ min_sdk_version: "31",
+ updatable: true,
+ }
+ override_android_app {
+ name: "com.android.go.foo",
+ base: "com.android.foo",
+ min_sdk_version: "33",
+ }
+ `)
+ foo := result.ModuleForTests("com.android.foo", "android_common").Rule("manifestFixer")
+ fooOverride := result.ModuleForTests("com.android.foo", "android_common_com.android.go.foo").Rule("manifestFixer")
+
+ android.AssertStringDoesContain(t,
+ "com.android.foo: expected manifest fixer to set minSdkVersion to T",
+ foo.BuildParams.Args["args"],
+ "--minSdkVersion 31",
+ )
+ android.AssertStringDoesContain(t,
+ "com.android.go.foo: expected manifest fixer to set minSdkVersion to T",
+ fooOverride.BuildParams.Args["args"],
+ "--minSdkVersion 33",
+ )
+
+}
diff --git a/java/base.go b/java/base.go
index d8ccec6c6..5c637b500 100644
--- a/java/base.go
+++ b/java/base.go
@@ -26,7 +26,6 @@ import (
"github.com/google/blueprint/pathtools"
"github.com/google/blueprint/proptools"
- "android/soong/aconfig"
"android/soong/android"
"android/soong/dexpreopt"
"android/soong/java/config"
@@ -201,6 +200,9 @@ type CommonProperties struct {
// Additional srcJars tacked in by GeneratedJavaLibraryModule
Generated_srcjars []android.Path `android:"mutated"`
+ // intermediate aconfig cache file tacked in by GeneratedJavaLibraryModule
+ Aconfig_Cache_files []android.Path `android:"mutated"`
+
// If true, then only the headers are built and not the implementation jar.
Headers_only *bool
@@ -230,10 +232,6 @@ type DeviceProperties struct {
// If the SDK kind is empty, it will be set to public.
Sdk_version *string
- // if not blank, set the minimum version of the sdk that the compiled artifacts will run against.
- // Defaults to sdk_version if not set. See sdk_version for possible values.
- Min_sdk_version *string
-
// if not blank, set the maximum version of the sdk that the compiled artifacts will run against.
// Defaults to empty string "". See sdk_version for possible values.
Max_sdk_version *string
@@ -306,13 +304,17 @@ type DeviceProperties struct {
HiddenAPIFlagFileProperties
}
-// Device properties that can be overridden by overriding module (e.g. override_android_app)
-type OverridableDeviceProperties struct {
+// Properties that can be overridden by overriding module (e.g. override_android_app)
+type OverridableProperties struct {
// set the name of the output. If not set, `name` is used.
// To override a module with this property set, overriding module might need to set this as well.
// Otherwise, both the overridden and the overriding modules will have the same output name, which
// can cause the duplicate output error.
Stem *string
+
+ // if not blank, set the minimum version of the sdk that the compiled artifacts will run against.
+ // Defaults to sdk_version if not set. See sdk_version for possible values.
+ Min_sdk_version *string
}
// Functionality common to Module and Import
@@ -435,7 +437,8 @@ type Module struct {
protoProperties android.ProtoProperties
deviceProperties DeviceProperties
- overridableDeviceProperties OverridableDeviceProperties
+ overridableProperties OverridableProperties
+ sourceProperties android.SourceProperties
// jar file containing header classes including static library dependencies, suitable for
// inserting into the bootclasspath/classpath of another compile
@@ -537,14 +540,16 @@ type Module struct {
// or the module should override Stem().
stem string
- // Single aconfig "cache file" merged from this module and all dependencies.
- mergedAconfigFiles map[string]android.Paths
-
// Values that will be set in the JarJarProvider data for jarjar repackaging,
// and merged with our dependencies' rules.
jarjarRenameRules map[string]string
stubsLinkType StubsLinkType
+
+ // Paths to the aconfig intermediate cache files that are provided by the
+ // java_aconfig_library or java_library modules that are statically linked
+ // to this module. Does not contain cache files from all transitive dependencies.
+ aconfigCacheFiles android.Paths
}
func (j *Module) CheckStableSdkVersion(ctx android.BaseModuleContext) error {
@@ -617,6 +622,7 @@ func (j *Module) checkHeadersOnly(ctx android.ModuleContext) {
func (j *Module) addHostProperties() {
j.AddProperties(
&j.properties,
+ &j.overridableProperties,
&j.protoProperties,
&j.usesLibraryProperties,
)
@@ -626,7 +632,6 @@ func (j *Module) addHostAndDeviceProperties() {
j.addHostProperties()
j.AddProperties(
&j.deviceProperties,
- &j.overridableDeviceProperties,
&j.dexer.dexProperties,
&j.dexpreoptProperties,
&j.linter.properties,
@@ -713,6 +718,7 @@ func (j *Module) shouldInstrumentInApex(ctx android.BaseModuleContext) bool {
// doesn't make sense) or framework libraries (e.g. libraries found in the InstrumentFrameworkModules list) unless EMMA_INSTRUMENT_FRAMEWORK is true.
apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
isJacocoAgent := ctx.ModuleName() == "jacocoagent"
+
if j.DirectlyInAnyApex() && !isJacocoAgent && !apexInfo.IsForPlatform() {
if !inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
return true
@@ -736,8 +742,8 @@ func (j *Module) SystemModules() string {
}
func (j *Module) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
- if j.deviceProperties.Min_sdk_version != nil {
- return android.ApiLevelFrom(ctx, *j.deviceProperties.Min_sdk_version)
+ if j.overridableProperties.Min_sdk_version != nil {
+ return android.ApiLevelFrom(ctx, *j.overridableProperties.Min_sdk_version)
}
return j.SdkVersion(ctx).ApiLevel
}
@@ -805,7 +811,7 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) {
// Add dependency on libraries that provide additional hidden api annotations.
ctx.AddVariationDependencies(nil, hiddenApiAnnotationsTag, j.properties.Hiddenapi_additional_annotations...)
- if ctx.DeviceConfig().VndkVersion() != "" && ctx.Config().EnforceInterPartitionJavaSdkLibrary() {
+ if ctx.Config().EnforceInterPartitionJavaSdkLibrary() {
// Require java_sdk_library at inter-partition java dependency to ensure stable
// interface between partitions. If inter-partition java_library dependency is detected,
// raise build error because java_library doesn't have a stable interface.
@@ -838,9 +844,11 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) {
if dep != nil {
if component, ok := dep.(SdkLibraryComponentDependency); ok {
if lib := component.OptionalSdkLibraryImplementation(); lib != nil {
- // Add library as optional if it's one of the optional compatibility libs.
+ // Add library as optional if it's one of the optional compatibility libs or it's
+ // explicitly listed in the optional_uses_libs property.
tag := usesLibReqTag
- if android.InList(*lib, dexpreopt.OptionalCompatUsesLibs) {
+ if android.InList(*lib, dexpreopt.OptionalCompatUsesLibs) ||
+ android.InList(*lib, j.usesLibrary.usesLibraryProperties.Optional_uses_libs) {
tag = usesLibOptTag
}
ctx.AddVariationDependencies(nil, tag, *lib)
@@ -1203,6 +1211,8 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
// final R classes from the app.
flags.classpath = append(android.CopyOf(extraClasspathJars), flags.classpath...)
+ j.aconfigCacheFiles = append(deps.aconfigProtoFiles, j.properties.Aconfig_Cache_files...)
+
// If compiling headers then compile them and skip the rest
if proptools.Bool(j.properties.Headers_only) {
if srcFiles.HasExt(".kt") {
@@ -1220,14 +1230,15 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
}
android.SetProvider(ctx, JavaInfoProvider, JavaInfo{
- HeaderJars: android.PathsIfNonNil(j.headerJarFile),
- TransitiveLibsHeaderJars: j.transitiveLibsHeaderJars,
- TransitiveStaticLibsHeaderJars: j.transitiveStaticLibsHeaderJars,
- AidlIncludeDirs: j.exportAidlIncludeDirs,
- ExportedPlugins: j.exportedPluginJars,
- ExportedPluginClasses: j.exportedPluginClasses,
- ExportedPluginDisableTurbine: j.exportedDisableTurbine,
- StubsLinkType: j.stubsLinkType,
+ HeaderJars: android.PathsIfNonNil(j.headerJarFile),
+ TransitiveLibsHeaderJars: j.transitiveLibsHeaderJars,
+ TransitiveStaticLibsHeaderJars: j.transitiveStaticLibsHeaderJars,
+ AidlIncludeDirs: j.exportAidlIncludeDirs,
+ ExportedPlugins: j.exportedPluginJars,
+ ExportedPluginClasses: j.exportedPluginClasses,
+ ExportedPluginDisableTurbine: j.exportedDisableTurbine,
+ StubsLinkType: j.stubsLinkType,
+ AconfigIntermediateCacheOutputPaths: deps.aconfigProtoFiles,
})
j.outputFile = j.headerJarFile
@@ -1294,10 +1305,12 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
return
}
+ kotlinJarPath := j.repackageFlagsIfNecessary(ctx, kotlinJar.OutputPath, jarName, "kotlinc")
+
// Make javac rule depend on the kotlinc rule
flags.classpath = append(classpath{kotlinHeaderJar}, flags.classpath...)
- kotlinJars = append(kotlinJars, kotlinJar)
+ kotlinJars = append(kotlinJars, kotlinJarPath)
kotlinHeaderJars = append(kotlinHeaderJars, kotlinHeaderJar)
// Jar kotlin classes into the final jar after javac
@@ -1377,6 +1390,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
for idx, shardSrc := range shardSrcs {
classes := j.compileJavaClasses(ctx, jarName, idx, shardSrc,
nil, flags, extraJarDeps)
+ classes = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(idx))
jars = append(jars, classes)
}
}
@@ -1389,11 +1403,13 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
for idx, shardSrcJars := range shardSrcJarsList {
classes := j.compileJavaClasses(ctx, jarName, startIdx+idx,
nil, shardSrcJars, flags, extraJarDeps)
+ classes = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(startIdx+idx))
jars = append(jars, classes)
}
}
} else {
classes := j.compileJavaClasses(ctx, jarName, -1, uniqueJavaFiles, srcJars, flags, extraJarDeps)
+ classes = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac")
jars = append(jars, classes)
}
if ctx.Failed() {
@@ -1552,16 +1568,6 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
}
}
- // Automatic jarjar rules propagation
- if j.repackageJarjarRules != nil {
- repackagedJarjarFile := android.PathForModuleOut(ctx, "repackaged-jarjar", jarName).OutputPath
- TransformJarJar(ctx, repackagedJarjarFile, outputFile, j.repackageJarjarRules)
- outputFile = repackagedJarjarFile
- if ctx.Failed() {
- return
- }
- }
-
// Check package restrictions if necessary.
if len(j.properties.Permitted_packages) > 0 {
// Time stamp file created by the package check rule.
@@ -1679,7 +1685,11 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
j.dexJarFile = makeDexJarPathFromPath(dexOutputFile)
// Dexpreopting
- j.dexpreopt(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), dexOutputFile)
+ libName := android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName())
+ if j.SdkLibraryName() != nil && strings.HasSuffix(ctx.ModuleName(), ".impl") {
+ libName = strings.TrimSuffix(libName, ".impl")
+ }
+ j.dexpreopt(ctx, libName, dexOutputFile)
outputFile = dexOutputFile
} else {
@@ -1727,25 +1737,24 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
ctx.CheckbuildFile(outputFile)
- android.CollectDependencyAconfigFiles(ctx, &j.mergedAconfigFiles)
-
android.SetProvider(ctx, JavaInfoProvider, JavaInfo{
- HeaderJars: android.PathsIfNonNil(j.headerJarFile),
- RepackagedHeaderJars: android.PathsIfNonNil(j.repackagedHeaderJarFile),
- TransitiveLibsHeaderJars: j.transitiveLibsHeaderJars,
- TransitiveStaticLibsHeaderJars: j.transitiveStaticLibsHeaderJars,
- ImplementationAndResourcesJars: android.PathsIfNonNil(j.implementationAndResourcesJar),
- ImplementationJars: android.PathsIfNonNil(j.implementationJarFile),
- ResourceJars: android.PathsIfNonNil(j.resourceJar),
- AidlIncludeDirs: j.exportAidlIncludeDirs,
- SrcJarArgs: j.srcJarArgs,
- SrcJarDeps: j.srcJarDeps,
- TransitiveSrcFiles: j.transitiveSrcFiles,
- ExportedPlugins: j.exportedPluginJars,
- ExportedPluginClasses: j.exportedPluginClasses,
- ExportedPluginDisableTurbine: j.exportedDisableTurbine,
- JacocoReportClassesFile: j.jacocoReportClassesFile,
- StubsLinkType: j.stubsLinkType,
+ HeaderJars: android.PathsIfNonNil(j.headerJarFile),
+ RepackagedHeaderJars: android.PathsIfNonNil(j.repackagedHeaderJarFile),
+ TransitiveLibsHeaderJars: j.transitiveLibsHeaderJars,
+ TransitiveStaticLibsHeaderJars: j.transitiveStaticLibsHeaderJars,
+ ImplementationAndResourcesJars: android.PathsIfNonNil(j.implementationAndResourcesJar),
+ ImplementationJars: android.PathsIfNonNil(j.implementationJarFile),
+ ResourceJars: android.PathsIfNonNil(j.resourceJar),
+ AidlIncludeDirs: j.exportAidlIncludeDirs,
+ SrcJarArgs: j.srcJarArgs,
+ SrcJarDeps: j.srcJarDeps,
+ TransitiveSrcFiles: j.transitiveSrcFiles,
+ ExportedPlugins: j.exportedPluginJars,
+ ExportedPluginClasses: j.exportedPluginClasses,
+ ExportedPluginDisableTurbine: j.exportedDisableTurbine,
+ JacocoReportClassesFile: j.jacocoReportClassesFile,
+ StubsLinkType: j.stubsLinkType,
+ AconfigIntermediateCacheOutputPaths: j.aconfigCacheFiles,
})
// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
@@ -1756,10 +1765,7 @@ func (j *Module) useCompose() bool {
return android.InList("androidx.compose.runtime_runtime", j.properties.Static_libs)
}
-func (j *Module) collectProguardSpecInfo(ctx android.ModuleContext) ProguardSpecInfo {
- transitiveUnconditionalExportedFlags := []*android.DepSet[android.Path]{}
- transitiveProguardFlags := []*android.DepSet[android.Path]{}
-
+func collectDepProguardSpecInfo(ctx android.ModuleContext) (transitiveProguardFlags, transitiveUnconditionalExportedFlags []*android.DepSet[android.Path]) {
ctx.VisitDirectDeps(func(m android.Module) {
depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider)
depTag := ctx.OtherModuleDependencyTag(m)
@@ -1774,6 +1780,12 @@ func (j *Module) collectProguardSpecInfo(ctx android.ModuleContext) ProguardSpec
}
})
+ return transitiveProguardFlags, transitiveUnconditionalExportedFlags
+}
+
+func (j *Module) collectProguardSpecInfo(ctx android.ModuleContext) ProguardSpecInfo {
+ transitiveProguardFlags, transitiveUnconditionalExportedFlags := collectDepProguardSpecInfo(ctx)
+
directUnconditionalExportedFlags := android.Paths{}
proguardFlagsForThisModule := android.PathsForModuleSrc(ctx, j.dexProperties.Optimize.Proguard_flags_files)
exportUnconditionally := proptools.Bool(j.dexProperties.Optimize.Export_proguard_flags_files)
@@ -2296,6 +2308,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
// annotation processor that generates API is incompatible with the turbine
// optimization.
deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine
+ deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.AconfigIntermediateCacheOutputPaths...)
case pluginTag:
if plugin, ok := module.(*Plugin); ok {
if plugin.pluginProperties.Processor_class != nil {
@@ -2354,6 +2367,11 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
deps.staticJars = append(deps.staticJars, dep.Srcs()...)
deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs()...)
}
+ } else if dep, ok := android.OtherModuleProvider(ctx, module, android.CodegenInfoProvider); ok {
+ switch tag {
+ case staticLibTag:
+ deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...)
+ }
} else {
switch tag {
case bootClasspathTag:
@@ -2376,6 +2394,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
}
addCLCFromDep(ctx, module, j.classLoaderContexts)
+ addMissingOptionalUsesLibsFromDep(ctx, module, &j.usesLibrary)
})
return deps
@@ -2551,7 +2570,7 @@ func collectDirectDepsProviders(ctx android.ModuleContext) (result *JarJarProvid
default:
return RenameUseExclude, "srcfile"
}
- } else if _, ok := android.OtherModuleProvider(ctx, m, aconfig.CodegenInfoProvider); ok {
+ } else if _, ok := android.OtherModuleProvider(ctx, m, android.CodegenInfoProvider); ok {
return RenameUseInclude, "aconfig_declarations_group"
} else {
switch tag {
@@ -2679,6 +2698,16 @@ func getJarJarRuleText(provider *JarJarProviderData) string {
return result
}
+// Repackage the flags if the jarjar rule txt for the flags is generated
+func (j *Module) repackageFlagsIfNecessary(ctx android.ModuleContext, infile android.WritablePath, jarName, info string) android.WritablePath {
+ if j.repackageJarjarRules == nil {
+ return infile
+ }
+ repackagedJarjarFile := android.PathForModuleOut(ctx, "repackaged-jarjar", info+jarName)
+ TransformJarJar(ctx, repackagedJarjarFile, infile, j.repackageJarjarRules)
+ return repackagedJarjarFile
+}
+
func addPlugins(deps *deps, pluginJars android.Paths, pluginClasses ...string) {
deps.processorPath = append(deps.processorPath, pluginJars...)
deps.processorClasses = append(deps.processorClasses, pluginClasses...)
@@ -2699,3 +2728,13 @@ type ModuleWithStem interface {
}
var _ ModuleWithStem = (*Module)(nil)
+
+type ModuleWithUsesLibrary interface {
+ UsesLibrary() *usesLibrary
+}
+
+func (j *Module) UsesLibrary() *usesLibrary {
+ return &j.usesLibrary
+}
+
+var _ ModuleWithUsesLibrary = (*Module)(nil)
diff --git a/java/boot_jars.go b/java/boot_jars.go
index 5d40ec389..6223dede8 100644
--- a/java/boot_jars.go
+++ b/java/boot_jars.go
@@ -21,8 +21,8 @@ import (
// isActiveModule returns true if the given module should be considered for boot
// jars, i.e. if it's enabled and the preferred one in case of source and
// prebuilt alternatives.
-func isActiveModule(module android.Module) bool {
- if !module.Enabled() {
+func isActiveModule(ctx android.ConfigAndErrorContext, module android.Module) bool {
+ if !module.Enabled(ctx) {
return false
}
return android.IsModulePreferred(module)
diff --git a/java/bootclasspath.go b/java/bootclasspath.go
index c7dc3afae..77ddf5c05 100644
--- a/java/bootclasspath.go
+++ b/java/bootclasspath.go
@@ -127,7 +127,10 @@ func reportMissingVariationDependency(ctx android.BottomUpMutatorContext, variat
// added by addDependencyOntoApexModulePair.
func gatherApexModulePairDepsWithTag(ctx android.BaseModuleContext, tag blueprint.DependencyTag) []android.Module {
var modules []android.Module
- ctx.VisitDirectDepsIf(isActiveModule, func(module android.Module) {
+ isActiveModulePred := func(module android.Module) bool {
+ return isActiveModule(ctx, module)
+ }
+ ctx.VisitDirectDepsIf(isActiveModulePred, func(module android.Module) {
t := ctx.OtherModuleDependencyTag(module)
if t == tag {
modules = append(modules, module)
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index 7c45d3043..4d3d794d8 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -77,7 +77,7 @@ func (b bootclasspathFragmentContentDependencyTag) SdkMemberType(child android.M
return javaSdkLibrarySdkMemberType
}
- return javaBootLibsSdkMemberType
+ return JavaBootLibsSdkMemberType
}
func (b bootclasspathFragmentContentDependencyTag) ExportMember() bool {
@@ -474,7 +474,7 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo
// Only perform a consistency check if this module is the active module. That will prevent an
// unused prebuilt that was created without instrumentation from breaking an instrumentation
// build.
- if isActiveModule(ctx.Module()) {
+ if isActiveModule(ctx, ctx.Module()) {
b.bootclasspathFragmentPropertyCheck(ctx)
}
@@ -519,7 +519,7 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo
// 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()) {
+ if !isActiveModule(ctx, ctx.Module()) {
return ""
}
@@ -590,13 +590,36 @@ func (b *BootclasspathFragmentModule) configuredJars(ctx android.ModuleContext)
// So ignore it even if it is not in PRODUCT_APEX_BOOT_JARS.
// TODO(b/202896428): Add better way to handle this.
_, unknown = android.RemoveFromList("android.car-module", unknown)
- if isActiveModule(ctx.Module()) && len(unknown) > 0 {
- ctx.ModuleErrorf("%s in contents must also be declared in PRODUCT_APEX_BOOT_JARS", unknown)
+ if isApexVariant(ctx) && len(unknown) > 0 {
+ if android.IsModulePrebuilt(ctx.Module()) {
+ // prebuilt bcpf. the validation of this will be done at the top-level apex
+ providerClasspathFragmentValidationInfoProvider(ctx, unknown)
+ } else if !disableSourceApexVariant(ctx) {
+ // source bcpf, and prebuilt apex are not selected.
+ ctx.ModuleErrorf("%s in contents must also be declared in PRODUCT_APEX_BOOT_JARS", unknown)
+ }
}
}
return jars
}
+var ClasspathFragmentValidationInfoProvider = blueprint.NewProvider[ClasspathFragmentValidationInfo]()
+
+type ClasspathFragmentValidationInfo struct {
+ ClasspathFragmentModuleName string
+ UnknownJars []string
+}
+
+// Set a provider with the list of jars that have not been added to PRODUCT_APEX_BOOT_JARS
+// The validation will be done in the ctx of the top-level _selected_ apex
+func providerClasspathFragmentValidationInfoProvider(ctx android.ModuleContext, unknown []string) {
+ info := ClasspathFragmentValidationInfo{
+ ClasspathFragmentModuleName: ctx.ModuleName(),
+ UnknownJars: unknown,
+ }
+ android.SetProvider(ctx, ClasspathFragmentValidationInfoProvider, info)
+}
+
// generateHiddenAPIBuildActions generates all the hidden API related build rules.
func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, contents []android.Module, fragments []android.Module) *HiddenAPIOutput {
diff --git a/java/builder.go b/java/builder.go
index b07a622e4..5d84d0b43 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -120,6 +120,8 @@ var (
`--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED ` +
`--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED ` +
`--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED ` +
+ `--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED ` +
+ `--add-exports=jdk.internal.opt/jdk.internal.opt=ALL-UNNAMED ` +
`-jar ${config.JavaKytheExtractorJar} ` +
`${config.JavacHeapFlags} ${config.CommonJdkFlags} ` +
`$processorpath $processor $javacFlags $bootClasspath $classpath ` +
diff --git a/java/classpath_fragment.go b/java/classpath_fragment.go
index 0ebab4d8c..07bc5c163 100644
--- a/java/classpath_fragment.go
+++ b/java/classpath_fragment.go
@@ -151,10 +151,14 @@ func configuredJarListToClasspathJars(ctx android.ModuleContext, configuredJars
return jars
}
+func (c *ClasspathFragmentBase) outputFilename() string {
+ return strings.ToLower(c.classpathType.String()) + ".pb"
+}
+
func (c *ClasspathFragmentBase) generateClasspathProtoBuildActions(ctx android.ModuleContext, configuredJars android.ConfiguredJarList, jars []classpathJar) {
generateProto := proptools.BoolDefault(c.properties.Generate_classpaths_proto, true)
if generateProto {
- outputFilename := strings.ToLower(c.classpathType.String()) + ".pb"
+ outputFilename := c.outputFilename()
c.outputFilepath = android.PathForModuleOut(ctx, outputFilename).OutputPath
c.installDirPath = android.PathForModuleInstall(ctx, "etc", "classpaths")
@@ -181,6 +185,10 @@ func (c *ClasspathFragmentBase) generateClasspathProtoBuildActions(ctx android.M
android.SetProvider(ctx, ClasspathFragmentProtoContentInfoProvider, classpathProtoInfo)
}
+func (c *ClasspathFragmentBase) installClasspathProto(ctx android.ModuleContext) android.InstallPath {
+ return ctx.InstallFile(c.installDirPath, c.outputFilename(), c.outputFilepath)
+}
+
func writeClasspathsTextproto(ctx android.ModuleContext, output android.WritablePath, jars []classpathJar) {
var content strings.Builder
diff --git a/java/code_metadata_test.go b/java/code_metadata_test.go
index 0ef348afe..99b1f5226 100644
--- a/java/code_metadata_test.go
+++ b/java/code_metadata_test.go
@@ -7,6 +7,7 @@ import (
"android/soong/android"
soongTesting "android/soong/testing"
"android/soong/testing/code_metadata_internal_proto"
+
"google.golang.org/protobuf/proto"
)
diff --git a/java/config/config.go b/java/config/config.go
index 6a945ac9c..2bb50f62a 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -26,8 +26,7 @@ import (
)
var (
- pctx = android.NewPackageContext("android/soong/java/config")
- exportedVars = android.NewExportedVariables(pctx)
+ pctx = android.NewPackageContext("android/soong/java/config")
LegacyCorePlatformBootclasspathLibraries = []string{"legacy.core.platform.api.stubs", "core-lambda-stubs"}
LegacyCorePlatformSystemModules = "legacy-core-platform-api-stubs-system-modules"
@@ -79,30 +78,30 @@ var (
func init() {
pctx.Import("github.com/google/blueprint/bootstrap")
- exportedVars.ExportStringStaticVariable("JavacHeapSize", "4096M")
- exportedVars.ExportStringStaticVariable("JavacHeapFlags", "-J-Xmx${JavacHeapSize}")
+ pctx.StaticVariable("JavacHeapSize", "4096M")
+ pctx.StaticVariable("JavacHeapFlags", "-J-Xmx${JavacHeapSize}")
// ErrorProne can use significantly more memory than javac alone, give it a higher heap
// size (b/221480398).
- exportedVars.ExportStringStaticVariable("ErrorProneHeapSize", "8192M")
- exportedVars.ExportStringStaticVariable("ErrorProneHeapFlags", "-J-Xmx${ErrorProneHeapSize}")
+ pctx.StaticVariable("ErrorProneHeapSize", "8192M")
+ pctx.StaticVariable("ErrorProneHeapFlags", "-J-Xmx${ErrorProneHeapSize}")
// D8 invocations are shorter lived, so we restrict their JIT tiering relative to R8.
// Note that the `-JXX` prefix syntax is specific to the R8/D8 invocation wrappers.
- exportedVars.ExportStringListStaticVariable("D8Flags", append([]string{
+ pctx.StaticVariable("D8Flags", strings.Join(append([]string{
"-JXmx4096M",
"-JXX:+TieredCompilation",
"-JXX:TieredStopAtLevel=1",
"-JDcom.android.tools.r8.emitRecordAnnotationsInDex",
"-JDcom.android.tools.r8.emitPermittedSubclassesAnnotationsInDex",
- }, dexerJavaVmFlagsList...))
- exportedVars.ExportStringListStaticVariable("R8Flags", append([]string{
+ }, dexerJavaVmFlagsList...), " "))
+ pctx.StaticVariable("R8Flags", strings.Join(append([]string{
"-JXmx4096M",
"-JDcom.android.tools.r8.emitRecordAnnotationsInDex",
"-JDcom.android.tools.r8.emitPermittedSubclassesAnnotationsInDex",
- }, dexerJavaVmFlagsList...))
+ }, dexerJavaVmFlagsList...), " "))
- exportedVars.ExportStringListStaticVariable("CommonJdkFlags", []string{
+ pctx.StaticVariable("CommonJdkFlags", strings.Join([]string{
`-Xmaxerrs 9999999`,
`-encoding UTF-8`,
`-sourcepath ""`,
@@ -116,10 +115,10 @@ func init() {
// b/65004097: prevent using java.lang.invoke.StringConcatFactory when using -target 1.9
`-XDstringConcat=inline`,
- })
+ }, " "))
- exportedVars.ExportStringListStaticVariable("JavaVmFlags", javaVmFlagsList)
- exportedVars.ExportStringListStaticVariable("JavacVmFlags", javacVmFlagsList)
+ pctx.StaticVariable("JavaVmFlags", strings.Join(javaVmFlagsList, " "))
+ pctx.StaticVariable("JavacVmFlags", strings.Join(javacVmFlagsList, " "))
pctx.VariableConfigMethod("hostPrebuiltTag", android.Config.PrebuiltOS)
@@ -131,12 +130,7 @@ func init() {
if override := ctx.Config().Getenv("OVERRIDE_JLINK_VERSION_NUMBER"); override != "" {
return override
}
- switch ctx.Config().Getenv("EXPERIMENTAL_USE_OPENJDK21_TOOLCHAIN") {
- case "true":
- return "21"
- default:
- return "17"
- }
+ return "21"
})
pctx.SourcePathVariable("JavaToolchain", "${JavaHome}/bin")
diff --git a/java/config/droidstubs.go b/java/config/droidstubs.go
index 39eec444c..04a3f96b9 100644
--- a/java/config/droidstubs.go
+++ b/java/config/droidstubs.go
@@ -58,11 +58,7 @@ const (
)
func init() {
- exportedVars.ExportStringList("MetalavaFlags", metalavaFlags)
+ pctx.StaticVariable("MetalavaAnnotationsFlags", strings.Join(metalavaAnnotationsFlags, " "))
- exportedVars.ExportString("MetalavaAddOpens", MetalavaAddOpens)
-
- exportedVars.ExportStringListStaticVariable("MetalavaAnnotationsFlags", metalavaAnnotationsFlags)
-
- exportedVars.ExportStringListStaticVariable("MetalavaAnnotationWarningsFlags", metalavaAnnotationsWarningsFlags)
+ pctx.StaticVariable("MetalavaAnnotationWarningsFlags", strings.Join(metalavaAnnotationsWarningsFlags, " "))
}
diff --git a/java/config/error_prone.go b/java/config/error_prone.go
index 5f853c812..767164f70 100644
--- a/java/config/error_prone.go
+++ b/java/config/error_prone.go
@@ -15,6 +15,7 @@
package config
import (
+ "android/soong/android"
"strings"
)
@@ -29,23 +30,23 @@ var (
)
// Wrapper that grabs value of val late so it can be initialized by a later module's init function
-func errorProneVar(val *[]string, sep string) func() string {
- return func() string {
+func errorProneVar(val *[]string, sep string) func(android.PackageVarContext) string {
+ return func(android.PackageVarContext) string {
return strings.Join(*val, sep)
}
}
func init() {
- exportedVars.ExportVariableFuncVariable("ErrorProneClasspath", errorProneVar(&ErrorProneClasspath, ":"))
- exportedVars.ExportVariableFuncVariable("ErrorProneChecksError", errorProneVar(&ErrorProneChecksError, " "))
- exportedVars.ExportVariableFuncVariable("ErrorProneChecksWarning", errorProneVar(&ErrorProneChecksWarning, " "))
- exportedVars.ExportVariableFuncVariable("ErrorProneChecksDefaultDisabled", errorProneVar(&ErrorProneChecksDefaultDisabled, " "))
- exportedVars.ExportVariableFuncVariable("ErrorProneChecksOff", errorProneVar(&ErrorProneChecksOff, " "))
- exportedVars.ExportVariableFuncVariable("ErrorProneFlags", errorProneVar(&ErrorProneFlags, " "))
- exportedVars.ExportStringListStaticVariable("ErrorProneChecks", []string{
+ pctx.VariableFunc("ErrorProneClasspath", errorProneVar(&ErrorProneClasspath, ":"))
+ pctx.VariableFunc("ErrorProneChecksError", errorProneVar(&ErrorProneChecksError, " "))
+ pctx.VariableFunc("ErrorProneChecksWarning", errorProneVar(&ErrorProneChecksWarning, " "))
+ pctx.VariableFunc("ErrorProneChecksDefaultDisabled", errorProneVar(&ErrorProneChecksDefaultDisabled, " "))
+ pctx.VariableFunc("ErrorProneChecksOff", errorProneVar(&ErrorProneChecksOff, " "))
+ pctx.VariableFunc("ErrorProneFlags", errorProneVar(&ErrorProneFlags, " "))
+ pctx.StaticVariable("ErrorProneChecks", strings.Join([]string{
"${ErrorProneChecksOff}",
"${ErrorProneChecksError}",
"${ErrorProneChecksWarning}",
"${ErrorProneChecksDefaultDisabled}",
- })
+ }, " "))
}
diff --git a/java/device_host_converter_test.go b/java/device_host_converter_test.go
index 3413da03d..6ccc5c1b1 100644
--- a/java/device_host_converter_test.go
+++ b/java/device_host_converter_test.go
@@ -16,7 +16,7 @@ package java
import (
"android/soong/android"
- "reflect"
+ "slices"
"strings"
"testing"
)
@@ -84,7 +84,7 @@ func TestDeviceForHost(t *testing.T) {
deviceImportCombined.Output,
}
- if !reflect.DeepEqual(combined.Inputs, expectedInputs) {
+ if !slices.Equal(combined.Inputs.Strings(), expectedInputs.Strings()) {
t.Errorf("expected host_module combined inputs:\n%q\ngot:\n%q",
expectedInputs, combined.Inputs)
}
@@ -95,7 +95,7 @@ func TestDeviceForHost(t *testing.T) {
deviceRes.Output,
}
- if !reflect.DeepEqual(resCombined.Inputs, expectedInputs) {
+ if !slices.Equal(resCombined.Inputs.Strings(), expectedInputs.Strings()) {
t.Errorf("expected host_module res combined inputs:\n%q\ngot:\n%q",
expectedInputs, resCombined.Inputs)
}
@@ -165,7 +165,7 @@ func TestHostForDevice(t *testing.T) {
hostImportCombined.Output,
}
- if !reflect.DeepEqual(combined.Inputs, expectedInputs) {
+ if !slices.Equal(combined.Inputs.Strings(), expectedInputs.Strings()) {
t.Errorf("expected device_module combined inputs:\n%q\ngot:\n%q",
expectedInputs, combined.Inputs)
}
@@ -176,7 +176,7 @@ func TestHostForDevice(t *testing.T) {
hostRes.Output,
}
- if !reflect.DeepEqual(resCombined.Inputs, expectedInputs) {
+ if !slices.Equal(resCombined.Inputs.Strings(), expectedInputs.Strings()) {
t.Errorf("expected device_module res combined inputs:\n%q\ngot:\n%q",
expectedInputs, resCombined.Inputs)
}
diff --git a/java/dex.go b/java/dex.go
index 4474c636a..8cfffaf1f 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -66,6 +66,12 @@ type DexProperties struct {
// If true, optimize for size by removing unused resources. Defaults to false.
Shrink_resources *bool
+ // If true, use optimized resource shrinking in R8, overriding the
+ // Shrink_resources setting. Defaults to false.
+ // Optimized shrinking means that R8 will trace and treeshake resources together with code
+ // and apply additional optimizations. This implies non final fields in the R classes.
+ Optimized_shrink_resources *bool
+
// Flags to pass to proguard.
Proguard_flags []string
@@ -105,6 +111,14 @@ func (d *dexer) effectiveOptimizeEnabled() bool {
return BoolDefault(d.dexProperties.Optimize.Enabled, d.dexProperties.Optimize.EnabledByDefault)
}
+func (d *DexProperties) resourceShrinkingEnabled(ctx android.ModuleContext) bool {
+ return !ctx.Config().Eng() && BoolDefault(d.Optimize.Optimized_shrink_resources, Bool(d.Optimize.Shrink_resources))
+}
+
+func (d *DexProperties) optimizedResourceShrinkingEnabled(ctx android.ModuleContext) bool {
+ return d.resourceShrinkingEnabled(ctx) && Bool(d.Optimize.Optimized_shrink_resources)
+}
+
var d8, d8RE = pctx.MultiCommandRemoteStaticRules("d8",
blueprint.RuleParams{
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
@@ -351,10 +365,14 @@ func (d *dexer) r8Flags(ctx android.ModuleContext, flags javaBuilderFlags) (r8Fl
r8Flags = append(r8Flags, "-ignorewarnings")
}
+ // resourcesInput is empty when we don't use resource shrinking, if on, pass these to R8
if d.resourcesInput.Valid() {
r8Flags = append(r8Flags, "--resource-input", d.resourcesInput.Path().String())
r8Deps = append(r8Deps, d.resourcesInput.Path())
r8Flags = append(r8Flags, "--resource-output", d.resourcesOutput.Path().String())
+ if Bool(opt.Optimized_shrink_resources) {
+ r8Flags = append(r8Flags, "--optimized-resource-shrinking")
+ }
}
return r8Flags, r8Deps
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 38ed856ee..4d6dbffe1 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -196,8 +196,10 @@ func disableSourceApexVariant(ctx android.BaseModuleContext) bool {
}
apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
psi := android.PrebuiltSelectionInfoMap{}
- ctx.VisitDirectDepsWithTag(android.PrebuiltDepTag, func(am android.Module) {
- psi, _ = android.OtherModuleProvider(ctx, am, android.PrebuiltSelectionInfoProvider)
+ ctx.VisitDirectDeps(func(am android.Module) {
+ if prebuiltSelectionInfo, ok := android.OtherModuleProvider(ctx, am, android.PrebuiltSelectionInfoProvider); ok {
+ psi = prebuiltSelectionInfo
+ }
})
// Find the apex variant for this module
_, apexVariantsWithoutTestApexes, _ := android.ListSetDifference(apexInfo.InApexVariants, apexInfo.TestApexes)
@@ -243,10 +245,6 @@ func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext, libName s
return true
}
- if disableSourceApexVariant(ctx) {
- return true
- }
-
if _, isApex := android.ModuleProvider(ctx, android.ApexBundleInfoProvider); isApex {
// dexpreopt rules for system server jars can be generated in the ModuleCtx of prebuilt apexes
return false
@@ -264,6 +262,20 @@ func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext, libName s
if !isApexSystemServerJar {
return true
}
+ ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
+ allApexInfos := []android.ApexInfo{}
+ if allApexInfosProvider, ok := android.ModuleProvider(ctx, android.AllApexInfoProvider); ok {
+ allApexInfos = allApexInfosProvider.ApexInfos
+ }
+ if len(allApexInfos) > 0 && !ai.MinSdkVersion.EqualTo(allApexInfos[0].MinSdkVersion) {
+ // Apex system server jars are dexpreopted and installed on to the system image.
+ // Since we can have BigAndroid and Go variants of system server jar providing apexes,
+ // and these two variants can have different min_sdk_versions, hide one of the apex variants
+ // from make to prevent collisions.
+ //
+ // Unlike cc, min_sdk_version does not have an effect on the build actions of java libraries.
+ ctx.Module().MakeUninstallable()
+ }
} else {
// Don't preopt the platform variant of an APEX system server jar to avoid conflicts.
if isApexSystemServerJar {
@@ -501,8 +513,12 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, libName string, dexJa
Output(appProductPackages)
productPackagesRule.Restat().Build("product_packages."+dexJarStem, "dexpreopt product_packages")
+ // Prebuilts are active, do not copy the dexpreopt'd source javalib to out/soong/system_server_dexjars
+ // The javalib from the deapexed prebuilt will be copied to this location.
+ // TODO (b/331665856): Implement a principled solution for this.
+ copyApexSystemServerJarDex := !disableSourceApexVariant(ctx) && !ctx.Module().IsHideFromMake()
dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(
- ctx, globalSoong, global, dexpreoptConfig, appProductPackages)
+ ctx, globalSoong, global, dexpreoptConfig, appProductPackages, copyApexSystemServerJarDex)
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 f7e3cb93a..7229ca02d 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -562,7 +562,7 @@ func gatherBootclasspathFragments(ctx android.ModuleContext) map[string]android.
return ctx.Config().Once(dexBootJarsFragmentsKey, func() interface{} {
fragments := make(map[string]android.Module)
ctx.WalkDeps(func(child, parent android.Module) bool {
- if !isActiveModule(child) {
+ if !isActiveModule(ctx, child) {
return false
}
tag := ctx.OtherModuleDependencyTag(child)
@@ -1125,7 +1125,7 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p
image.unstrippedInstalls = unstrippedInstalls
// Only set the licenseMetadataFile from the active module.
- if isActiveModule(ctx.Module()) {
+ if isActiveModule(ctx, ctx.Module()) {
image.licenseMetadataFile = android.OptionalPathForPath(ctx.LicenseMetadataFile())
}
diff --git a/java/droiddoc.go b/java/droiddoc.go
index df40d016c..176779eb4 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -21,7 +21,6 @@ import (
"github.com/google/blueprint/proptools"
- "android/soong/aconfig"
"android/soong/android"
"android/soong/java/config"
)
@@ -222,8 +221,6 @@ type Javadoc struct {
stubsSrcJar android.WritablePath
exportableStubsSrcJar android.WritablePath
-
- runtimeStubsSrcJar android.WritablePath
}
func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) {
@@ -394,12 +391,14 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
} else if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
deps.classpath = append(deps.classpath, dep.HeaderJars...)
deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
+ deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.AconfigIntermediateCacheOutputPaths...)
} else if dep, ok := module.(android.SourceFileProducer); ok {
checkProducesJars(ctx, dep)
deps.classpath = append(deps.classpath, dep.Srcs()...)
} else {
ctx.ModuleErrorf("depends on non-java module %q", otherName)
}
+
case java9LibTag:
if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...)
@@ -416,7 +415,7 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
case aconfigDeclarationTag:
if dep, ok := android.OtherModuleProvider(ctx, module, android.AconfigDeclarationsProviderKey); ok {
deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPath)
- } else if dep, ok := android.OtherModuleProvider(ctx, module, aconfig.CodegenInfoProvider); ok {
+ } else if dep, ok := android.OtherModuleProvider(ctx, module, android.CodegenInfoProvider); ok {
deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...)
} else {
ctx.ModuleErrorf("Only aconfig_declarations and aconfig_declarations_group "+
@@ -432,6 +431,19 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
j.implicits = append(j.implicits, srcFiles...)
+ // Module can depend on a java_aconfig_library module using the ":module_name{.tag}" syntax.
+ // Find the corresponding aconfig_declarations module name for such case.
+ for _, src := range j.properties.Srcs {
+ if moduleName, tag := android.SrcIsModuleWithTag(src); moduleName != "" {
+ otherModule := android.GetModuleFromPathDep(ctx, moduleName, tag)
+ if otherModule != nil {
+ if dep, ok := android.OtherModuleProvider(ctx, otherModule, android.CodegenInfoProvider); ok {
+ deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...)
+ }
+ }
+ }
+ }
+
filterByPackage := func(srcs []android.Path, filterPackages []string) []android.Path {
if filterPackages == nil {
return srcs
diff --git a/java/droidstubs.go b/java/droidstubs.go
index f4bcaca15..ca81343f0 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -106,9 +106,6 @@ type Droidstubs struct {
everythingArtifacts stubsArtifacts
exportableArtifacts stubsArtifacts
- // Single aconfig "cache file" merged from this module and all dependencies.
- mergedAconfigFiles map[string]android.Paths
-
exportableApiFile android.WritablePath
exportableRemovedApiFile android.WritablePath
}
@@ -227,7 +224,6 @@ type currentApiTimestampProvider interface {
type annotationFlagsParams struct {
migratingNullability bool
validatingNullability bool
- extractAnnotations bool
nullabilityWarningsFile android.WritablePath
annotationsZip android.WritablePath
}
@@ -243,19 +239,16 @@ type stubsCommandParams struct {
stubConfig stubsCommandConfigParams
}
type stubsCommandConfigParams struct {
- stubsType StubsType
- javaVersion javaVersion
- deps deps
- checkApi bool
- generateStubs bool
- doApiLint bool
- doCheckReleased bool
- writeSdkValues bool
- migratingNullability bool
- validatingNullability bool
- annotationsEnabled bool
- apiLevelsAnnotationsEnabled bool
- extractAnnotations bool
+ stubsType StubsType
+ javaVersion javaVersion
+ deps deps
+ checkApi bool
+ generateStubs bool
+ doApiLint bool
+ doCheckReleased bool
+ writeSdkValues bool
+ migratingNullability bool
+ validatingNullability bool
}
// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
@@ -372,7 +365,7 @@ func (d *Droidstubs) ApiFilePath(stubsType StubsType) (ret android.Path, err err
ret, err = nil, fmt.Errorf("api file path not supported for the stub type %s", stubsType.String())
}
if ret == nil && err == nil {
- err = fmt.Errorf("stubs srcjar is null for the stub type %s", stubsType.String())
+ err = fmt.Errorf("api file is null for the stub type %s", stubsType.String())
}
return ret, err
}
@@ -482,34 +475,41 @@ func (d *Droidstubs) sdkValuesFlags(ctx android.ModuleContext, cmd *android.Rule
}
func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.OptionalPath, stubsType StubsType, checkApi bool) {
- if checkApi || String(d.properties.Api_filename) != "" {
- filename := proptools.StringDefault(d.properties.Api_filename, ctx.ModuleName()+"_api.txt")
- uncheckedApiFile := android.PathForModuleOut(ctx, stubsType.String(), filename)
- cmd.FlagWithOutput("--api ", uncheckedApiFile)
+ apiFileName := proptools.StringDefault(d.properties.Api_filename, ctx.ModuleName()+"_api.txt")
+ uncheckedApiFile := android.PathForModuleOut(ctx, stubsType.String(), apiFileName)
+ cmd.FlagWithOutput("--api ", uncheckedApiFile)
+ if checkApi || String(d.properties.Api_filename) != "" {
if stubsType == Everything {
d.apiFile = uncheckedApiFile
} else if stubsType == Exportable {
d.exportableApiFile = uncheckedApiFile
}
} else if sourceApiFile := proptools.String(d.properties.Check_api.Current.Api_file); sourceApiFile != "" {
- // If check api is disabled then make the source file available for export.
- d.apiFile = android.PathForModuleSrc(ctx, sourceApiFile)
+ if stubsType == Everything {
+ // If check api is disabled then make the source file available for export.
+ d.apiFile = android.PathForModuleSrc(ctx, sourceApiFile)
+ } else if stubsType == Exportable {
+ d.exportableApiFile = uncheckedApiFile
+ }
}
+ removedApiFileName := proptools.StringDefault(d.properties.Removed_api_filename, ctx.ModuleName()+"_removed.txt")
+ uncheckedRemovedFile := android.PathForModuleOut(ctx, stubsType.String(), removedApiFileName)
+ cmd.FlagWithOutput("--removed-api ", uncheckedRemovedFile)
if checkApi || String(d.properties.Removed_api_filename) != "" {
- filename := proptools.StringDefault(d.properties.Removed_api_filename, ctx.ModuleName()+"_removed.txt")
- uncheckedRemovedFile := android.PathForModuleOut(ctx, stubsType.String(), filename)
- cmd.FlagWithOutput("--removed-api ", uncheckedRemovedFile)
-
if stubsType == Everything {
d.removedApiFile = uncheckedRemovedFile
} else if stubsType == Exportable {
d.exportableRemovedApiFile = uncheckedRemovedFile
}
} else if sourceRemovedApiFile := proptools.String(d.properties.Check_api.Current.Removed_api_file); sourceRemovedApiFile != "" {
- // If check api is disabled then make the source removed api file available for export.
- d.removedApiFile = android.PathForModuleSrc(ctx, sourceRemovedApiFile)
+ if stubsType == Everything {
+ // If check api is disabled then make the source removed api file available for export.
+ d.removedApiFile = android.PathForModuleSrc(ctx, sourceRemovedApiFile)
+ } else if stubsType == Exportable {
+ d.exportableRemovedApiFile = uncheckedRemovedFile
+ }
}
if stubsDir.Valid() {
@@ -525,30 +525,30 @@ func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuil
}
func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, params annotationFlagsParams) {
- cmd.Flag(config.MetalavaAnnotationsFlags)
+ if Bool(d.properties.Annotations_enabled) {
+ cmd.Flag(config.MetalavaAnnotationsFlags)
- if params.migratingNullability {
- previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
- cmd.FlagWithInput("--migrate-nullness ", previousApi)
- }
+ if params.migratingNullability {
+ previousApiFiles := android.PathsForModuleSrc(ctx, []string{String(d.properties.Previous_api)})
+ cmd.FlagForEachInput("--migrate-nullness ", previousApiFiles)
+ }
- if s := String(d.properties.Validate_nullability_from_list); s != "" {
- cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
- }
+ if s := String(d.properties.Validate_nullability_from_list); s != "" {
+ cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
+ }
- if params.validatingNullability {
- cmd.FlagWithOutput("--nullability-warnings-txt ", params.nullabilityWarningsFile)
- }
+ if params.validatingNullability {
+ cmd.FlagWithOutput("--nullability-warnings-txt ", params.nullabilityWarningsFile)
+ }
- if params.extractAnnotations {
cmd.FlagWithOutput("--extract-annotations ", params.annotationsZip)
- }
- if len(d.properties.Merge_annotations_dirs) != 0 {
- d.mergeAnnoDirFlags(ctx, cmd)
- }
+ if len(d.properties.Merge_annotations_dirs) != 0 {
+ d.mergeAnnoDirFlags(ctx, cmd)
+ }
- cmd.Flag(config.MetalavaAnnotationsWarningsFlags)
+ cmd.Flag(config.MetalavaAnnotationsWarningsFlags)
+ }
}
func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
@@ -573,11 +573,9 @@ func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *a
})
}
-func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, params stubsCommandParams) {
+func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, apiVersionsXml android.WritablePath) {
var apiVersions android.Path
- stubsType := params.stubConfig.stubsType
- apiVersionsXml := params.apiVersionsXml
- if params.stubConfig.apiLevelsAnnotationsEnabled {
+ if proptools.Bool(d.properties.Api_levels_annotations_enabled) {
d.apiLevelsGenerationFlags(ctx, cmd, stubsType, apiVersionsXml)
apiVersions = apiVersionsXml
} else {
@@ -588,9 +586,7 @@ func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *a
} else if stubsType == Exportable {
apiVersions = s.exportableArtifacts.apiVersionsXml
} else {
- // if the stubs type does not generate api-versions.xml file, default to using the
- // everything artifacts
- apiVersions = s.everythingArtifacts.apiVersionsXml
+ ctx.ModuleErrorf("%s stubs type does not generate api-versions.xml file", stubsType.String())
}
} else {
ctx.PropertyErrorf("api_levels_module",
@@ -605,6 +601,11 @@ func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *a
}
}
+// AndroidPlusUpdatableJar is the name of some extra jars added into `module-lib` and
+// `system-server` directories that contain all the APIs provided by the platform and updatable
+// modules because the `android.jar` files do not. See b/337836752.
+const AndroidPlusUpdatableJar = "android-plus-updatable.jar"
+
func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, apiVersionsXml android.WritablePath) {
if len(d.properties.Api_levels_annotations_dirs) == 0 {
ctx.PropertyErrorf("api_levels_annotations_dirs",
@@ -615,25 +616,72 @@ func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *an
filename := proptools.StringDefault(d.properties.Api_levels_jar_filename, "android.jar")
+ // TODO: Avoid the duplication of API surfaces, reuse apiScope.
+ // Add all relevant --android-jar-pattern patterns for Metalava.
+ // When parsing a stub jar for a specific version, Metalava picks the first pattern that defines
+ // an actual file present on disk (in the order the patterns were passed). For system APIs for
+ // privileged apps that are only defined since API level 21 (Lollipop), fallback to public stubs
+ // for older releases. Similarly, module-lib falls back to system API.
+ var sdkDirs []string
+ apiLevelsSdkType := proptools.StringDefault(d.properties.Api_levels_sdk_type, "public")
+ switch apiLevelsSdkType {
+ case "system-server":
+ sdkDirs = []string{"system-server", "module-lib", "system", "public"}
+ case "module-lib":
+ sdkDirs = []string{"module-lib", "system", "public"}
+ case "system":
+ sdkDirs = []string{"system", "public"}
+ case "public":
+ sdkDirs = []string{"public"}
+ default:
+ ctx.PropertyErrorf("api_levels_sdk_type", "needs to be one of %v", allowedApiLevelSdkTypes)
+ return
+ }
+
+ // Construct a pattern to match the appropriate extensions that should be included in the
+ // generated api-versions.xml file.
+ //
+ // Use the first item in the sdkDirs array as that is the sdk type for the target API levels
+ // being generated but has the advantage over `Api_levels_sdk_type` as it has been validated.
+ // The exception is for system-server which needs to include module-lib and system-server. That
+ // is because while system-server extends module-lib the system-server extension directory only
+ // contains service-* modules which provide system-server APIs it does not list the modules which
+ // only provide a module-lib, so they have to be included separately.
+ extensionSurfacesPattern := sdkDirs[0]
+ if apiLevelsSdkType == "system-server" {
+ // Take the first two items in sdkDirs, which are system-server and module-lib, and construct
+ // a pattern that will match either.
+ extensionSurfacesPattern = strings.Join(sdkDirs[0:2], "|")
+ }
+ extensionsPattern := fmt.Sprintf(`/extensions/[0-9]+/(%s)/.*\.jar`, extensionSurfacesPattern)
+
var dirs []string
var extensions_dir string
ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
if t, ok := m.(*ExportedDroiddocDir); ok {
- extRegex := regexp.MustCompile(t.dir.String() + `/extensions/[0-9]+/public/.*\.jar`)
+ extRegex := regexp.MustCompile(t.dir.String() + extensionsPattern)
// Grab the first extensions_dir and we find while scanning ExportedDroiddocDir.deps;
// ideally this should be read from prebuiltApis.properties.Extensions_*
for _, dep := range t.deps {
+ // Check to see if it matches an extension first.
+ depBase := dep.Base()
if extRegex.MatchString(dep.String()) && d.properties.Extensions_info_file != nil {
if extensions_dir == "" {
extensions_dir = t.dir.String() + "/extensions"
}
cmd.Implicit(dep)
- }
- if dep.Base() == filename {
+ } else if depBase == filename {
+ // Check to see if it matches a dessert release for an SDK, e.g. Android, Car, Wear, etc..
cmd.Implicit(dep)
- }
- if filename != "android.jar" && dep.Base() == "android.jar" {
+ } else if depBase == AndroidPlusUpdatableJar && d.properties.Extensions_info_file != nil {
+ // The output api-versions.xml has been requested to include information on SDK
+ // extensions. That means it also needs to include
+ // so
+ // The module-lib and system-server directories should use `android-plus-updatable.jar`
+ // instead of `android.jar`. See AndroidPlusUpdatableJar for more information.
+ cmd.Implicit(dep)
+ } else if filename != "android.jar" && depBase == "android.jar" {
// Metalava implicitly searches these patterns:
// prebuilts/tools/common/api-versions/android-%/android.jar
// prebuilts/sdk/%/public/android.jar
@@ -651,29 +699,25 @@ func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *an
}
})
- // Add all relevant --android-jar-pattern patterns for Metalava.
- // When parsing a stub jar for a specific version, Metalava picks the first pattern that defines
- // an actual file present on disk (in the order the patterns were passed). For system APIs for
- // privileged apps that are only defined since API level 21 (Lollipop), fallback to public stubs
- // for older releases. Similarly, module-lib falls back to system API.
- var sdkDirs []string
- switch proptools.StringDefault(d.properties.Api_levels_sdk_type, "public") {
- case "system-server":
- sdkDirs = []string{"system-server", "module-lib", "system", "public"}
- case "module-lib":
- sdkDirs = []string{"module-lib", "system", "public"}
- case "system":
- sdkDirs = []string{"system", "public"}
- case "public":
- sdkDirs = []string{"public"}
- default:
- ctx.PropertyErrorf("api_levels_sdk_type", "needs to be one of %v", allowedApiLevelSdkTypes)
- return
- }
-
+ // Generate the list of --android-jar-pattern options. The order matters so the first one which
+ // matches will be the one that is used for a specific api level..
for _, sdkDir := range sdkDirs {
for _, dir := range dirs {
- cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/%%/%s/%s", dir, sdkDir, filename))
+ addPattern := func(jarFilename string) {
+ cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/%%/%s/%s", dir, sdkDir, jarFilename))
+ }
+
+ if sdkDir == "module-lib" || sdkDir == "system-server" {
+ // The module-lib and system-server android.jars do not include the updatable modules (as
+ // doing so in the source would introduce dependency cycles and the prebuilts have to
+ // match the sources). So, instead an additional `android-plus-updatable.jar` will be used
+ // that does include the updatable modules and this pattern will match that. This pattern
+ // is added in addition to the following pattern to decouple this change from the change
+ // to add the `android-plus-updatable.jar`.
+ addPattern(AndroidPlusUpdatableJar)
+ }
+
+ addPattern(filename)
}
}
@@ -688,12 +732,29 @@ func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *an
}
}
+func (d *Droidstubs) apiCompatibilityFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType) {
+ if len(d.Javadoc.properties.Out) > 0 {
+ ctx.PropertyErrorf("out", "out property may not be combined with check_api")
+ }
+
+ apiFiles := android.PathsForModuleSrc(ctx, []string{String(d.properties.Check_api.Last_released.Api_file)})
+ removedApiFiles := android.PathsForModuleSrc(ctx, []string{String(d.properties.Check_api.Last_released.Removed_api_file)})
+
+ cmd.FlagForEachInput("--check-compatibility:api:released ", apiFiles)
+ cmd.FlagForEachInput("--check-compatibility:removed:released ", removedApiFiles)
+
+ baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
+ if baselineFile.Valid() {
+ cmd.FlagWithInput("--baseline:compatibility:released ", baselineFile.Path())
+ }
+}
+
func metalavaUseRbe(ctx android.ModuleContext) bool {
return ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_METALAVA")
}
-func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion javaVersion, srcs android.Paths,
- srcJarList android.Path, bootclasspath, classpath classpath, homeDir android.WritablePath) *android.RuleBuilderCommand {
+func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
+ srcJarList android.Path, homeDir android.WritablePath, params stubsCommandConfigParams) *android.RuleBuilderCommand {
rule.Command().Text("rm -rf").Flag(homeDir.String())
rule.Command().Text("mkdir -p").Flag(homeDir.String())
@@ -723,14 +784,14 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi
cmd.BuiltTool("metalava").ImplicitTool(ctx.Config().HostJavaToolPath(ctx, "metalava.jar")).
Flag(config.JavacVmFlags).
Flag(config.MetalavaAddOpens).
- FlagWithArg("--java-source ", javaVersion.String()).
- FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, "metalava.rsp"), srcs).
+ FlagWithArg("--java-source ", params.javaVersion.String()).
+ FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, fmt.Sprintf("%s.metalava.rsp", params.stubsType.String())), srcs).
FlagWithInput("@", srcJarList)
// Metalava does not differentiate between bootclasspath and classpath and has not done so for
// years, so it is unlikely to change any time soon.
- combinedPaths := append(([]android.Path)(nil), bootclasspath.Paths()...)
- combinedPaths = append(combinedPaths, classpath.Paths()...)
+ combinedPaths := append(([]android.Path)(nil), params.deps.bootClasspath.Paths()...)
+ combinedPaths = append(combinedPaths, params.deps.classpath.Paths()...)
if len(combinedPaths) > 0 {
cmd.FlagWithInputList("--classpath ", combinedPaths, ":")
}
@@ -811,8 +872,7 @@ func (d *Droidstubs) commonMetalavaStubCmd(ctx android.ModuleContext, rule *andr
srcJarList := zipSyncCmd(ctx, rule, params.srcJarDir, d.Javadoc.srcJars)
homeDir := android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "home")
- cmd := metalavaCmd(ctx, rule, params.stubConfig.javaVersion, d.Javadoc.srcFiles, srcJarList,
- params.stubConfig.deps.bootClasspath, params.stubConfig.deps.classpath, homeDir)
+ cmd := metalavaCmd(ctx, rule, d.Javadoc.srcFiles, srcJarList, homeDir, params.stubConfig)
cmd.Implicits(d.Javadoc.implicits)
d.stubsFlags(ctx, cmd, params.stubsDir, params.stubConfig.stubsType, params.stubConfig.checkApi)
@@ -824,16 +884,17 @@ func (d *Droidstubs) commonMetalavaStubCmd(ctx android.ModuleContext, rule *andr
annotationParams := annotationFlagsParams{
migratingNullability: params.stubConfig.migratingNullability,
validatingNullability: params.stubConfig.validatingNullability,
- extractAnnotations: params.stubConfig.extractAnnotations,
nullabilityWarningsFile: params.nullabilityWarningsFile,
annotationsZip: params.annotationsZip,
}
- if params.stubConfig.annotationsEnabled {
- d.annotationsFlags(ctx, cmd, annotationParams)
- }
+ d.annotationsFlags(ctx, cmd, annotationParams)
d.inclusionAnnotationsFlags(ctx, cmd)
- d.apiLevelsAnnotationsFlags(ctx, cmd, params)
+ d.apiLevelsAnnotationsFlags(ctx, cmd, params.stubConfig.stubsType, params.apiVersionsXml)
+
+ if params.stubConfig.doCheckReleased {
+ d.apiCompatibilityFlags(ctx, cmd, params.stubConfig.stubsType)
+ }
d.expandArgs(ctx, cmd)
@@ -863,13 +924,13 @@ func (d *Droidstubs) everythingStubCmd(ctx android.ModuleContext, params stubsCo
d.everythingArtifacts.metadataZip = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"-metadata.zip")
}
- if params.annotationsEnabled {
+ if Bool(d.properties.Annotations_enabled) {
if params.validatingNullability {
d.everythingArtifacts.nullabilityWarningsFile = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"_nullability_warnings.txt")
}
d.everythingArtifacts.annotationsZip = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"_annotations.zip")
}
- if params.apiLevelsAnnotationsEnabled {
+ if Bool(d.properties.Api_levels_annotations_enabled) {
d.everythingArtifacts.apiVersionsXml = android.PathForModuleOut(ctx, Everything.String(), "api-versions.xml")
}
@@ -933,12 +994,12 @@ func (d *Droidstubs) everythingOptionalCmd(ctx android.ModuleContext, cmd *andro
// Add API lint options.
if doApiLint {
- newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since)
- if newSince.Valid() {
- cmd.FlagWithInput("--api-lint ", newSince.Path())
- } else {
- cmd.Flag("--api-lint")
+ var newSince android.Paths
+ if d.properties.Check_api.Api_lint.New_since != nil {
+ newSince = android.PathsForModuleSrc(ctx, []string{proptools.String(d.properties.Check_api.Api_lint.New_since)})
}
+ cmd.Flag("--api-lint")
+ cmd.FlagForEachInput("--api-lint-previous-api ", newSince)
d.apiLintReport = android.PathForModuleOut(ctx, Everything.String(), "api_lint_report.txt")
cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) // TODO: Change to ":api-lint"
@@ -993,25 +1054,12 @@ func (d *Droidstubs) everythingOptionalCmd(ctx android.ModuleContext, cmd *andro
// Add "check released" options. (Detect incompatible API changes from the last public release)
if doCheckReleased {
- if len(d.Javadoc.properties.Out) > 0 {
- ctx.PropertyErrorf("out", "out property may not be combined with check_api")
- }
-
- apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
- removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
- updatedBaselineOutput := android.PathForModuleOut(ctx, Everything.String(), "last_released_baseline.txt")
-
d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_last_released_api.timestamp")
-
- cmd.FlagWithInput("--check-compatibility:api:released ", apiFile)
- cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
-
if baselineFile.Valid() {
- cmd.FlagWithInput("--baseline:compatibility:released ", baselineFile.Path())
+ updatedBaselineOutput := android.PathForModuleOut(ctx, Everything.String(), "last_released_baseline.txt")
cmd.FlagWithOutput("--update-baseline:compatibility:released ", updatedBaselineOutput)
}
-
// Note this string includes quote ($' ... '), which decodes the "\n"s.
msg := `$'\n******************************\n` +
`You have tried to change the API from what has been previously released in\n` +
@@ -1047,7 +1095,7 @@ func (d *Droidstubs) exportableStubCmd(ctx android.ModuleContext, params stubsCo
optionalCmdParams.metadataDir = d.exportableArtifacts.metadataDir
}
- if params.annotationsEnabled {
+ if Bool(d.properties.Annotations_enabled) {
if params.validatingNullability {
d.exportableArtifacts.nullabilityWarningsFile = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"_nullability_warnings.txt")
optionalCmdParams.nullabilityWarningsFile = d.exportableArtifacts.nullabilityWarningsFile
@@ -1055,7 +1103,7 @@ func (d *Droidstubs) exportableStubCmd(ctx android.ModuleContext, params stubsCo
d.exportableArtifacts.annotationsZip = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"_annotations.zip")
optionalCmdParams.annotationsZip = d.exportableArtifacts.annotationsZip
}
- if params.apiLevelsAnnotationsEnabled {
+ if Bool(d.properties.Api_levels_annotations_enabled) {
d.exportableArtifacts.apiVersionsXml = android.PathForModuleOut(ctx, params.stubsType.String(), "api-versions.xml")
optionalCmdParams.apiVersionsXml = d.exportableArtifacts.apiVersionsXml
}
@@ -1073,38 +1121,6 @@ func (d *Droidstubs) exportableStubCmd(ctx android.ModuleContext, params stubsCo
d.optionalStubCmd(ctx, optionalCmdParams)
}
-// Sandbox rule for generating runtime stubs
-func (d *Droidstubs) runtimeStubCmd(ctx android.ModuleContext, params stubsCommandConfigParams) {
-
- // We are only interested in generating the stubs srcjar,
- // not other artifacts for the runtime stubs
- params.checkApi = false
- params.writeSdkValues = false
- params.validatingNullability = false
- params.extractAnnotations = false
- params.apiLevelsAnnotationsEnabled = false
-
- optionalCmdParams := stubsCommandParams{
- stubConfig: params,
- }
-
- d.Javadoc.runtimeStubsSrcJar = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"-"+"stubs.srcjar")
- optionalCmdParams.stubsSrcJar = d.Javadoc.runtimeStubsSrcJar
-
- // If aconfig_declarations property is not defined, all flagged apis symbols are stripped
- // as no aconfig flags are enabled. In such case, the runtime stubs are identical to the
- // exportable stubs, thus no additional metalava invocation is needed.
- if len(d.properties.Aconfig_declarations) == 0 {
- rule := android.NewRuleBuilder(pctx, ctx)
- rule.Command().
- Text("cp").Flag("-f").
- Input(d.exportableStubsSrcJar).Output(d.runtimeStubsSrcJar)
- rule.Build(fmt.Sprintf("metalava_%s", params.stubsType.String()), "metalava merged")
- } else {
- d.optionalStubCmd(ctx, optionalCmdParams)
- }
-}
-
func (d *Droidstubs) optionalStubCmd(ctx android.ModuleContext, params stubsCommandParams) {
params.srcJarDir = android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "srcjars")
@@ -1176,8 +1192,6 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
annotationsEnabled := Bool(d.properties.Annotations_enabled)
- extractAnnotations := annotationsEnabled
-
migratingNullability := annotationsEnabled && String(d.properties.Previous_api) != ""
validatingNullability := annotationsEnabled && (strings.Contains(String(d.Javadoc.properties.Args), "--validate-nullability-from-merged-stubs") ||
String(d.properties.Validate_nullability_from_list) != "")
@@ -1185,40 +1199,27 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
checkApi := apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released")
- apiLevelsAnnotationsEnabled := proptools.Bool(d.properties.Api_levels_annotations_enabled)
-
stubCmdParams := stubsCommandConfigParams{
- javaVersion: javaVersion,
- deps: deps,
- checkApi: checkApi,
- generateStubs: generateStubs,
- doApiLint: doApiLint,
- doCheckReleased: doCheckReleased,
- writeSdkValues: writeSdkValues,
- migratingNullability: migratingNullability,
- validatingNullability: validatingNullability,
- annotationsEnabled: annotationsEnabled,
- apiLevelsAnnotationsEnabled: apiLevelsAnnotationsEnabled,
- extractAnnotations: extractAnnotations,
+ javaVersion: javaVersion,
+ deps: deps,
+ checkApi: checkApi,
+ generateStubs: generateStubs,
+ doApiLint: doApiLint,
+ doCheckReleased: doCheckReleased,
+ writeSdkValues: writeSdkValues,
+ migratingNullability: migratingNullability,
+ validatingNullability: validatingNullability,
}
stubCmdParams.stubsType = Everything
// Create default (i.e. "everything" stubs) rule for metalava
d.everythingStubCmd(ctx, stubCmdParams)
- // The module generates "exportable" stubs regardless of whether
+ // The module generates "exportable" (and "runtime" eventually) stubs regardless of whether
// aconfig_declarations property is defined or not. If the property is not defined, the module simply
// strips all flagged apis to generate the "exportable" stubs
stubCmdParams.stubsType = Exportable
d.exportableStubCmd(ctx, stubCmdParams)
- // "runtime" stubs do not generate any other artifacts than the stubs.
- // Therefore, metalava does not have to run for "runtime" configuration
- // when the module does not generate stubs.
- if stubCmdParams.generateStubs {
- stubCmdParams.stubsType = Runtime
- d.runtimeStubCmd(ctx, stubCmdParams)
- }
-
if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
if len(d.Javadoc.properties.Out) > 0 {
@@ -1338,7 +1339,6 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
rule.Build("nullabilityWarningsCheck", "nullability warnings check")
}
- android.CollectDependencyAconfigFiles(ctx, &d.mergedAconfigFiles)
}
func (d *Droidstubs) createApiContribution(ctx android.DefaultableHookContext) {
@@ -1366,7 +1366,7 @@ func (d *Droidstubs) createApiContribution(ctx android.DefaultableHookContext) {
// use a strict naming convention
var (
droidstubsModuleNamingToSdkKind = map[string]android.SdkKind{
- //public is commented out since the core libraries use public in their java_sdk_library names
+ // public is commented out since the core libraries use public in their java_sdk_library names
"intracore": android.SdkIntraCore,
"intra.core": android.SdkIntraCore,
"system_server": android.SdkSystemServer,
diff --git a/java/droidstubs_test.go b/java/droidstubs_test.go
index c86e8bf0f..6a14f3645 100644
--- a/java/droidstubs_test.go
+++ b/java/droidstubs_test.go
@@ -379,6 +379,7 @@ func TestAconfigDeclarations(t *testing.T) {
aconfig_declarations {
name: "bar",
package: "com.example.package",
+ container: "com.android.foo",
srcs: [
"bar.aconfig",
],
@@ -397,47 +398,23 @@ func TestAconfigDeclarations(t *testing.T) {
"bar",
],
}
- droidstubs {
- name: "baz",
- srcs: ["a/A.java"],
- api_surface: "public",
- check_api: {
- current: {
- api_file: "a/current.txt",
- removed_api_file: "a/removed.txt",
- }
- },
- }
`)
// Check that droidstubs depend on aconfig_declarations
android.AssertBoolEquals(t, "foo expected to depend on bar",
CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "bar"), true)
- fooModule := result.ModuleForTests("foo", "android_common")
+ m := result.ModuleForTests("foo", "android_common")
android.AssertStringDoesContain(t, "foo generates revert annotations file",
- strings.Join(fooModule.AllOutputs(), ""), "revert-annotations-exportable.txt")
+ strings.Join(m.AllOutputs(), ""), "revert-annotations-exportable.txt")
// revert-annotations.txt passed to exportable stubs generation metalava command
- exportableManifest := fooModule.Output("metalava_exportable.sbox.textproto")
- exportableCmdline := String(android.RuleBuilderSboxProtoForTests(t, result.TestContext, exportableManifest).Commands[0].Command)
- android.AssertStringDoesContain(t, "flagged api hide command not included", exportableCmdline, "revert-annotations-exportable.txt")
+ manifest := m.Output("metalava_exportable.sbox.textproto")
+ cmdline := String(android.RuleBuilderSboxProtoForTests(t, result.TestContext, manifest).Commands[0].Command)
+ android.AssertStringDoesContain(t, "flagged api hide command not included", cmdline, "revert-annotations-exportable.txt")
android.AssertStringDoesContain(t, "foo generates exportable stubs jar",
- strings.Join(fooModule.AllOutputs(), ""), "exportable/foo-stubs.srcjar")
-
- // revert-annotations.txt passed to runtime stubs generation metalava command
- runtimeManifest := fooModule.Output("metalava_runtime.sbox.textproto")
- runtimeCmdline := String(android.RuleBuilderSboxProtoForTests(t, result.TestContext, runtimeManifest).Commands[0].Command)
- android.AssertStringDoesContain(t, "flagged api hide command not included", runtimeCmdline, "revert-annotations-runtime.txt")
-
- android.AssertStringDoesContain(t, "foo generates runtime stubs jar",
- strings.Join(fooModule.AllOutputs(), ""), "runtime/foo-stubs.srcjar")
-
- // If aconfig_declarations property is not defined, the runtime stubs is a copy of the exportable stubs
- bazModule := result.ModuleForTests("baz", "android_common")
- bazRuntimeCmdline := bazModule.Rule("metalava_runtime").RuleParams.Command
- android.AssertStringDoesContain(t, "copy command should include the input stub", bazRuntimeCmdline, "exportable/baz-stubs.srcjar")
+ strings.Join(m.AllOutputs(), ""), "exportable/foo-stubs.srcjar")
}
func TestReleaseExportRuntimeApis(t *testing.T) {
@@ -458,6 +435,7 @@ func TestReleaseExportRuntimeApis(t *testing.T) {
aconfig_declarations {
name: "bar",
package: "com.example.package",
+ container: "com.android.foo",
srcs: [
"bar.aconfig",
],
diff --git a/java/fuzz.go b/java/fuzz.go
index dc4c6bec5..d37c55804 100644
--- a/java/fuzz.go
+++ b/java/fuzz.go
@@ -64,6 +64,8 @@ func JavaFuzzFactory() android.Module {
module.Module.properties.Installable = proptools.BoolPtr(true)
module.Module.dexpreopter.isTest = true
module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
+ module.Module.sourceProperties.Test_only = proptools.BoolPtr(true)
+ module.Module.sourceProperties.Top_level_test_target = true
android.AddLoadHook(module, func(ctx android.LoadHookContext) {
disableLinuxBionic := struct {
@@ -177,7 +179,7 @@ func (s *javaFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
javaFuzzModule.ApexModuleBase,
}
- if ok := fuzz.IsValid(fuzzModuleValidator); !ok {
+ if ok := fuzz.IsValid(ctx, fuzzModuleValidator); !ok {
return
}
diff --git a/java/gen.go b/java/gen.go
index 68a9b53fe..1b4f4c7dc 100644
--- a/java/gen.go
+++ b/java/gen.go
@@ -27,7 +27,6 @@ import (
func init() {
pctx.SourcePathVariable("logtagsCmd", "build/make/tools/java-event-log-tags.py")
- pctx.SourcePathVariable("mergeLogtagsCmd", "build/make/tools/merge-event-log-tags.py")
pctx.SourcePathVariable("logtagsLib", "build/make/tools/event_log_tags.py")
}
@@ -37,12 +36,6 @@ var (
Command: "$logtagsCmd -o $out $in",
CommandDeps: []string{"$logtagsCmd", "$logtagsLib"},
})
-
- mergeLogtags = pctx.AndroidStaticRule("mergeLogtags",
- blueprint.RuleParams{
- Command: "$mergeLogtagsCmd -o $out $in",
- CommandDeps: []string{"$mergeLogtagsCmd", "$logtagsLib"},
- })
)
func genAidl(ctx android.ModuleContext, aidlFiles android.Paths, aidlGlobalFlags string, aidlIndividualFlags map[string]string, deps android.Paths) android.Paths {
@@ -178,37 +171,9 @@ func (j *Module) genSources(ctx android.ModuleContext, srcFiles android.Paths,
outSrcFiles = append(outSrcFiles, srcJarFiles...)
}
- return outSrcFiles
-}
-
-func LogtagsSingleton() android.Singleton {
- return &logtagsSingleton{}
-}
-
-type logtagsProducer interface {
- logtags() android.Paths
-}
-
-func (j *Module) logtags() android.Paths {
- return j.logtagsSrcs
-}
-
-var _ logtagsProducer = (*Module)(nil)
-
-type logtagsSingleton struct{}
-
-func (l *logtagsSingleton) GenerateBuildActions(ctx android.SingletonContext) {
- var allLogtags android.Paths
- ctx.VisitAllModules(func(module android.Module) {
- if logtags, ok := module.(logtagsProducer); ok {
- allLogtags = append(allLogtags, logtags.logtags()...)
- }
+ android.SetProvider(ctx, android.LogtagsProviderKey, &android.LogtagsInfo{
+ Logtags: j.logtagsSrcs,
})
- ctx.Build(pctx, android.BuildParams{
- Rule: mergeLogtags,
- Description: "merge logtags",
- Output: android.PathForIntermediates(ctx, "all-event-log-tags.txt"),
- Inputs: allLogtags,
- })
+ return outSrcFiles
}
diff --git a/java/generated_java_library.go b/java/generated_java_library.go
index e8316ccc4..d5e6d8fec 100644
--- a/java/generated_java_library.go
+++ b/java/generated_java_library.go
@@ -34,7 +34,7 @@ type GeneratedJavaLibraryCallbacks interface {
// 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
+ GenerateSourceJarBuildActions(module *GeneratedJavaLibraryModule, ctx android.ModuleContext) (android.Path, android.Path)
}
// GeneratedJavaLibraryModuleFactory provides a utility for modules that are generated
@@ -103,8 +103,10 @@ func (module *GeneratedJavaLibraryModule) GenerateAndroidBuildActions(ctx androi
checkPropertyEmpty(ctx, module, "plugins", module.Library.properties.Plugins)
checkPropertyEmpty(ctx, module, "exported_plugins", module.Library.properties.Exported_plugins)
- srcJarPath := module.callbacks.GenerateSourceJarBuildActions(module, ctx)
+ srcJarPath, cacheOutputPath := module.callbacks.GenerateSourceJarBuildActions(module, ctx)
+
module.Library.properties.Generated_srcjars = append(module.Library.properties.Generated_srcjars, srcJarPath)
+ module.Library.properties.Aconfig_Cache_files = append(module.Library.properties.Aconfig_Cache_files, cacheOutputPath)
module.Library.GenerateAndroidBuildActions(ctx)
}
diff --git a/java/generated_java_library_test.go b/java/generated_java_library_test.go
index be816cda9..a5c4be111 100644
--- a/java/generated_java_library_test.go
+++ b/java/generated_java_library_test.go
@@ -36,8 +36,8 @@ type JavaGenLibTestCallbacks struct {
func (callbacks *JavaGenLibTestCallbacks) DepsMutator(module *GeneratedJavaLibraryModule, ctx android.BottomUpMutatorContext) {
}
-func (callbacks *JavaGenLibTestCallbacks) GenerateSourceJarBuildActions(module *GeneratedJavaLibraryModule, ctx android.ModuleContext) android.Path {
- return android.PathForOutput(ctx, "blah.srcjar")
+func (callbacks *JavaGenLibTestCallbacks) GenerateSourceJarBuildActions(module *GeneratedJavaLibraryModule, ctx android.ModuleContext) (android.Path, android.Path) {
+ return android.PathForOutput(ctx, "blah.srcjar"), android.PathForOutput(ctx, "blah.pb")
}
func testGenLib(t *testing.T, errorHandler android.FixtureErrorHandler, bp string) *android.TestResult {
diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go
index e4beb5e55..cab5402e9 100644
--- a/java/hiddenapi_modular.go
+++ b/java/hiddenapi_modular.go
@@ -1428,7 +1428,7 @@ func deferReportingMissingBootDexJar(ctx android.ModuleContext, module android.M
// should not contribute to anything. So, rather than have a missing dex jar cause a Soong
// failure defer the error reporting to Ninja. Unless the prebuilt build target is explicitly
// built Ninja should never use the dex jar file.
- if !isActiveModule(module) {
+ if !isActiveModule(ctx, module) {
return true
}
@@ -1478,13 +1478,3 @@ func retrieveEncodedBootDexJarFromModule(ctx android.ModuleContext, module andro
}
return bootDexJar.Path()
}
-
-// extractEncodedDexJarsFromModules extracts the encoded dex jars from the supplied modules.
-func extractEncodedDexJarsFromModules(ctx android.ModuleContext, contents []android.Module) bootDexJarByModule {
- encodedDexJarsByModuleName := bootDexJarByModule{}
- for _, module := range contents {
- path := retrieveEncodedBootDexJarFromModule(ctx, module)
- encodedDexJarsByModuleName.addPath(module, path)
- }
- return encodedDexJarsByModuleName
-}
diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go
index 8cb78cd54..7d21b7a61 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -150,6 +150,10 @@ func isModuleInConfiguredList(ctx android.BaseModuleContext, module android.Modu
// Strip a prebuilt_ prefix so that this can match a prebuilt module that has not been renamed.
name = android.RemoveOptionalPrebuiltPrefix(name)
+ // Strip the ".impl" suffix, so that the implementation library of the java_sdk_library is
+ // treated identical to the top level java_sdk_library.
+ name = strings.TrimSuffix(name, ".impl")
+
// Ignore any module that is not listed in the boot image configuration.
index := configuredBootJars.IndexOfJar(name)
if index == -1 {
diff --git a/java/hiddenapi_singleton_test.go b/java/hiddenapi_singleton_test.go
index c1fee2184..62297978c 100644
--- a/java/hiddenapi_singleton_test.go
+++ b/java/hiddenapi_singleton_test.go
@@ -198,13 +198,22 @@ func TestHiddenAPISingletonSdks(t *testing.T) {
hiddenApiFixtureFactory,
tc.preparer,
prepareForTestWithDefaultPlatformBootclasspath,
+ // Make sure that we have atleast one platform library so that we can check the monolithic hiddenapi
+ // file creation.
+ FixtureConfigureBootJars("platform:foo"),
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.Always_use_prebuilt_sdks = proptools.BoolPtr(tc.unbundledBuild)
variables.BuildFlags = map[string]string{
"RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true",
}
}),
- ).RunTest(t)
+ ).RunTestWithBp(t, `
+ java_library {
+ name: "foo",
+ srcs: ["a.java"],
+ compile_dex: true,
+ }
+ `)
hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common")
hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags")
@@ -303,7 +312,7 @@ func TestHiddenAPIEncoding_JavaSdkLibrary(t *testing.T) {
`)
checkDexEncoded := func(t *testing.T, name, unencodedDexJar, encodedDexJar string) {
- moduleForTests := result.ModuleForTests(name, "android_common")
+ moduleForTests := result.ModuleForTests(name+".impl", "android_common")
encodeDexRule := moduleForTests.Rule("hiddenAPIEncodeDex")
actualUnencodedDexJar := encodeDexRule.Input
@@ -319,18 +328,8 @@ func TestHiddenAPIEncoding_JavaSdkLibrary(t *testing.T) {
// The java_library embedded with the java_sdk_library must be dex encoded.
t.Run("foo", func(t *testing.T) {
- expectedUnencodedDexJar := "out/soong/.intermediates/foo/android_common/aligned/foo.jar"
- expectedEncodedDexJar := "out/soong/.intermediates/foo/android_common/hiddenapi/foo.jar"
+ expectedUnencodedDexJar := "out/soong/.intermediates/foo.impl/android_common/aligned/foo.jar"
+ expectedEncodedDexJar := "out/soong/.intermediates/foo.impl/android_common/hiddenapi/foo.jar"
checkDexEncoded(t, "foo", expectedUnencodedDexJar, expectedEncodedDexJar)
})
-
- // The dex jar of the child implementation java_library of the java_sdk_library is not currently
- // dex encoded.
- t.Run("foo.impl", func(t *testing.T) {
- fooImpl := result.ModuleForTests("foo.impl", "android_common")
- encodeDexRule := fooImpl.MaybeRule("hiddenAPIEncodeDex")
- if encodeDexRule.Rule != nil {
- t.Errorf("foo.impl is not expected to be encoded")
- }
- })
}
diff --git a/java/jacoco.go b/java/jacoco.go
index a820b3855..696a0cc37 100644
--- a/java/jacoco.go
+++ b/java/jacoco.go
@@ -53,7 +53,7 @@ func jacocoDepsMutator(ctx android.BottomUpMutatorContext) {
}
j, ok := ctx.Module().(instrumentable)
- if !ctx.Module().Enabled() || !ok {
+ if !ctx.Module().Enabled(ctx) || !ok {
return
}
diff --git a/java/java.go b/java/java.go
index 794020dc5..9fe7a2ff8 100644
--- a/java/java.go
+++ b/java/java.go
@@ -21,10 +21,10 @@ package java
import (
"fmt"
"path/filepath"
+ "slices"
"sort"
"strings"
- "android/soong/aconfig"
"android/soong/remoteexec"
"android/soong/testing"
@@ -75,7 +75,6 @@ func registerJavaBuildComponents(ctx android.RegistrationContext) {
ctx.BottomUp("jacoco_deps", jacocoDepsMutator).Parallel()
})
- ctx.RegisterParallelSingletonType("logtags", LogtagsSingleton)
ctx.RegisterParallelSingletonType("kythe_java_extract", kytheExtractJavaFactory)
}
@@ -83,8 +82,8 @@ func RegisterJavaSdkMemberTypes() {
// Register sdk member types.
android.RegisterSdkMemberType(javaHeaderLibsSdkMemberType)
android.RegisterSdkMemberType(javaLibsSdkMemberType)
- android.RegisterSdkMemberType(javaBootLibsSdkMemberType)
- android.RegisterSdkMemberType(javaSystemserverLibsSdkMemberType)
+ android.RegisterSdkMemberType(JavaBootLibsSdkMemberType)
+ android.RegisterSdkMemberType(JavaSystemserverLibsSdkMemberType)
android.RegisterSdkMemberType(javaTestSdkMemberType)
}
@@ -155,7 +154,7 @@ var (
// either java_libs, or java_header_libs would end up exporting more information than was strictly
// necessary. The java_boot_libs property to allow those modules to be exported as part of the
// sdk/module_exports without exposing any unnecessary information.
- javaBootLibsSdkMemberType = &librarySdkMemberType{
+ JavaBootLibsSdkMemberType = &librarySdkMemberType{
android.SdkMemberTypeBase{
PropertyName: "java_boot_libs",
SupportsSdk: true,
@@ -194,7 +193,7 @@ var (
// either java_libs, or java_header_libs would end up exporting more information than was strictly
// necessary. The java_systemserver_libs property to allow those modules to be exported as part of
// the sdk/module_exports without exposing any unnecessary information.
- javaSystemserverLibsSdkMemberType = &librarySdkMemberType{
+ JavaSystemserverLibsSdkMemberType = &librarySdkMemberType{
android.SdkMemberTypeBase{
PropertyName: "java_systemserver_libs",
SupportsSdk: true,
@@ -310,6 +309,10 @@ type JavaInfo struct {
// implementation jars. If the provider is set by java_sdk_library, the link type is "unknown"
// and selection between the stub jar vs implementation jar is deferred to SdkLibrary.sdkJars(...)
StubsLinkType StubsLinkType
+
+ // AconfigIntermediateCacheOutputPaths is a path to the cache files collected from the
+ // java_aconfig_library modules that are statically linked to this module.
+ AconfigIntermediateCacheOutputPaths android.Paths
}
var JavaInfoProvider = blueprint.NewProvider[JavaInfo]()
@@ -346,6 +349,12 @@ func (j *Module) XrefJavaFiles() android.Paths {
return j.kytheFiles
}
+func (d dependencyTag) PropagateAconfigValidation() bool {
+ return d.static
+}
+
+var _ android.PropagateAconfigValidationDependencyTag = dependencyTag{}
+
type dependencyTag struct {
blueprint.BaseDependencyTag
name string
@@ -355,14 +364,16 @@ type dependencyTag struct {
// True if the dependency is a toolchain, for example an annotation processor.
toolchain bool
+
+ static bool
+
+ installable bool
}
-// installDependencyTag is a dependency tag that is annotated to cause the installed files of the
-// dependency to be installed when the parent module is installed.
-type installDependencyTag struct {
- blueprint.BaseDependencyTag
- android.InstallAlwaysNeededDependencyTag
- name string
+var _ android.InstallNeededDependencyTag = (*dependencyTag)(nil)
+
+func (d dependencyTag) InstallDepNeeded() bool {
+ return d.installable
}
func (d dependencyTag) LicenseAnnotations() []android.LicenseAnnotation {
@@ -394,13 +405,13 @@ func makeUsesLibraryDependencyTag(sdkVersion int, optional bool) usesLibraryDepe
}
func IsJniDepTag(depTag blueprint.DependencyTag) bool {
- return depTag == jniLibTag
+ return depTag == jniLibTag || depTag == jniInstallTag
}
var (
dataNativeBinsTag = dependencyTag{name: "dataNativeBins"}
dataDeviceBinsTag = dependencyTag{name: "dataDeviceBins"}
- staticLibTag = dependencyTag{name: "staticlib"}
+ staticLibTag = dependencyTag{name: "staticlib", static: true}
libTag = dependencyTag{name: "javalib", runtimeLinked: true}
sdkLibTag = dependencyTag{name: "sdklib", runtimeLinked: true}
java9LibTag = dependencyTag{name: "java9lib", runtimeLinked: true}
@@ -423,8 +434,8 @@ var (
javaApiContributionTag = dependencyTag{name: "java-api-contribution"}
depApiSrcsTag = dependencyTag{name: "dep-api-srcs"}
aconfigDeclarationTag = dependencyTag{name: "aconfig-declaration"}
- jniInstallTag = installDependencyTag{name: "jni install"}
- binaryInstallTag = installDependencyTag{name: "binary install"}
+ jniInstallTag = dependencyTag{name: "jni install", runtimeLinked: true, installable: true}
+ binaryInstallTag = dependencyTag{name: "binary install", runtimeLinked: true, installable: true}
usesLibReqTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, false)
usesLibOptTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, true)
usesLibCompat28OptTag = makeUsesLibraryDependencyTag(28, true)
@@ -480,6 +491,7 @@ type jniLib struct {
coverageFile android.OptionalPath
unstrippedFile android.Path
partition string
+ installPaths android.InstallPaths
}
func sdkDeps(ctx android.BottomUpMutatorContext, sdkContext android.SdkContext, d dexer) {
@@ -555,6 +567,12 @@ func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext an
return normalizeJavaVersion(ctx, javaVersion)
} else if ctx.Device() {
return defaultJavaLanguageVersion(ctx, sdkContext.SdkVersion(ctx))
+ } else if ctx.Config().TargetsJava21() {
+ // Temporary experimental flag to be able to try and build with
+ // java version 21 options. The flag, if used, just sets Java
+ // 21 as the default version, leaving any components that
+ // target an older version intact.
+ return JAVA_VERSION_21
} else {
return JAVA_VERSION_17
}
@@ -575,6 +593,7 @@ const (
JAVA_VERSION_9 = 9
JAVA_VERSION_11 = 11
JAVA_VERSION_17 = 17
+ JAVA_VERSION_21 = 21
)
func (v javaVersion) String() string {
@@ -593,6 +612,8 @@ func (v javaVersion) String() string {
return "11"
case JAVA_VERSION_17:
return "17"
+ case JAVA_VERSION_21:
+ return "21"
default:
return "unsupported"
}
@@ -635,6 +656,8 @@ func normalizeJavaVersion(ctx android.BaseModuleContext, javaVersion string) jav
return JAVA_VERSION_11
case "17":
return JAVA_VERSION_17
+ case "21":
+ return JAVA_VERSION_21
case "10", "12", "13", "14", "15", "16":
ctx.PropertyErrorf("java_version", "Java language level %s is not supported", javaVersion)
return JAVA_VERSION_UNSUPPORTED
@@ -658,6 +681,10 @@ type Library struct {
var _ android.ApexModule = (*Library)(nil)
+func (j *Library) CheckDepsMinSdkVersion(ctx android.ModuleContext) {
+ CheckMinSdkVersion(ctx, j)
+}
+
// Provides access to the list of permitted packages from apex boot jars.
type PermittedPackagesForUpdatableBootJars interface {
PermittedPackagesForUpdatableBootJars() []string
@@ -680,10 +707,11 @@ func shouldUncompressDex(ctx android.ModuleContext, libName string, dexpreopter
return true
}
- // Store uncompressed dex files that are preopted on /system.
- if !dexpreopter.dexpreoptDisabled(ctx, libName) && (ctx.Host() || !dexpreopter.odexOnSystemOther(ctx, libName, dexpreopter.installPath)) {
+ // Store uncompressed dex files that are preopted on /system or /system_other.
+ if !dexpreopter.dexpreoptDisabled(ctx, libName) {
return true
}
+
if ctx.Config().UncompressPrivAppDex() &&
inList(ctx.ModuleName(), ctx.Config().ModulesLoadedByPrivilegedModules()) {
return true
@@ -787,6 +815,7 @@ var (
"android.hardware.security.keymint-V2-java": true,
"android.hardware.security.keymint-V3-java": true,
"android.hardware.security.keymint-V4-java": true,
+ "android.hardware.security.secretkeeper-V1-java": true,
"android.hardware.security.secureclock-V1-java": true,
"android.hardware.security.secureclock-V2-java": true,
"android.hardware.thermal-V1-java": true,
@@ -872,12 +901,24 @@ func init() {
}
func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ if disableSourceApexVariant(ctx) {
+ // Prebuilts are active, do not create the installation rules for the source javalib.
+ // Even though the source javalib is not used, we need to hide it to prevent duplicate installation rules.
+ // TODO (b/331665856): Implement a principled solution for this.
+ j.HideFromMake()
+ }
j.provideHiddenAPIPropertyInfo(ctx)
j.sdkVersion = j.SdkVersion(ctx)
j.minSdkVersion = j.MinSdkVersion(ctx)
j.maxSdkVersion = j.MaxSdkVersion(ctx)
+ // Check min_sdk_version of the transitive dependencies if this module is created from
+ // java_sdk_library.
+ if j.overridableProperties.Min_sdk_version != nil && j.SdkLibraryName() != nil {
+ j.CheckDepsMinSdkVersion(ctx)
+ }
+
// SdkLibrary.GenerateAndroidBuildActions(ctx) sets the stubsLinkType to Unknown.
// If the stubsLinkType has already been set to Unknown, the stubsLinkType should
// not be overridden.
@@ -889,7 +930,7 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
}
- j.stem = proptools.StringDefault(j.overridableDeviceProperties.Stem, ctx.ModuleName())
+ j.stem = proptools.StringDefault(j.overridableProperties.Stem, ctx.ModuleName())
proguardSpecInfo := j.collectProguardSpecInfo(ctx)
android.SetProvider(ctx, ProguardSpecInfoProvider, proguardSpecInfo)
@@ -908,8 +949,12 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.checkSdkVersions(ctx)
j.checkHeadersOnly(ctx)
if ctx.Device() {
+ libName := j.Name()
+ if j.SdkLibraryName() != nil && strings.HasSuffix(libName, ".impl") {
+ libName = proptools.String(j.SdkLibraryName())
+ }
j.dexpreopter.installPath = j.dexpreopter.getInstallPath(
- ctx, j.Name(), android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar"))
+ ctx, libName, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar"))
j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
setUncompressDex(ctx, &j.dexpreopter, &j.dexer)
j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
@@ -920,8 +965,24 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
j.compile(ctx, nil, nil, nil)
- exclusivelyForApex := !apexInfo.IsForPlatform()
- if (Bool(j.properties.Installable) || ctx.Host()) && !exclusivelyForApex {
+ // If this module is an impl library created from java_sdk_library,
+ // install the files under the java_sdk_library module outdir instead of this module outdir.
+ if j.SdkLibraryName() != nil && strings.HasSuffix(j.Name(), ".impl") {
+ j.setInstallRules(ctx, proptools.String(j.SdkLibraryName()))
+ } else {
+ j.setInstallRules(ctx, ctx.ModuleName())
+ }
+
+ android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
+ TestOnly: Bool(j.sourceProperties.Test_only),
+ TopLevelTarget: j.sourceProperties.Top_level_test_target,
+ })
+}
+
+func (j *Library) setInstallRules(ctx android.ModuleContext, installModuleName string) {
+ apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
+
+ if (Bool(j.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() {
var extraInstallDeps android.InstallPaths
if j.InstallMixin != nil {
extraInstallDeps = j.InstallMixin(ctx, j.outputFile)
@@ -938,7 +999,7 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
if !ctx.Host() {
archDir = ctx.DeviceConfig().DeviceArch()
}
- installDir = android.PathForModuleInstall(ctx, ctx.ModuleName(), archDir)
+ installDir = android.PathForModuleInstall(ctx, installModuleName, archDir)
} else {
installDir = android.PathForModuleInstall(ctx, "framework")
}
@@ -947,8 +1008,18 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
- j.deps(ctx)
j.usesLibrary.deps(ctx, false)
+ j.deps(ctx)
+
+ if j.SdkLibraryName() != nil && strings.HasSuffix(j.Name(), ".impl") {
+ if dexpreopt.IsDex2oatNeeded(ctx) {
+ dexpreopt.RegisterToolDeps(ctx)
+ }
+ prebuiltSdkLibExists := ctx.OtherModuleExists(android.PrebuiltNameFromSource(proptools.String(j.SdkLibraryName())))
+ if prebuiltSdkLibExists && ctx.OtherModuleExists("all_apex_contributions") {
+ ctx.AddDependency(ctx.Module(), android.AcDepTag, "all_apex_contributions")
+ }
+ }
}
const (
@@ -1032,7 +1103,7 @@ 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 {
+ if j.overridableProperties.Min_sdk_version != nil {
canonical, err := android.ReplaceFinalizedCodenames(ctx.SdkModuleContext().Config(), j.minSdkVersion.String())
if err != nil {
ctx.ModuleErrorf("%s", err)
@@ -1109,6 +1180,7 @@ func LibraryFactory() android.Module {
module := &Library{}
module.addHostAndDeviceProperties()
+ module.AddProperties(&module.sourceProperties)
module.initModuleAndImport(module)
@@ -1425,6 +1497,14 @@ func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.Test.generateAndroidBuildActionsWithConfig(ctx, configs)
android.SetProvider(ctx, testing.TestModuleProviderKey, testing.TestModuleProviderData{})
+ android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
+ InstalledFiles: j.data,
+ OutputFile: j.outputFile,
+ TestConfig: j.testConfig,
+ RequiredModuleNames: j.RequiredModuleNames(),
+ TestSuites: j.testProperties.Test_suites,
+ IsHost: true,
+ })
}
func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -1582,6 +1662,8 @@ func TestFactory() android.Module {
module.Module.properties.Installable = proptools.BoolPtr(true)
module.Module.dexpreopter.isTest = true
module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
+ module.Module.sourceProperties.Test_only = proptools.BoolPtr(true)
+ module.Module.sourceProperties.Top_level_test_target = true
InitJavaModule(module, android.HostAndDeviceSupported)
return module
@@ -1597,6 +1679,7 @@ func TestHelperLibraryFactory() android.Module {
module.Module.properties.Installable = proptools.BoolPtr(true)
module.Module.dexpreopter.isTest = true
module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
+ module.Module.sourceProperties.Test_only = proptools.BoolPtr(true)
InitJavaModule(module, android.HostAndDeviceSupported)
return module
@@ -1652,6 +1735,8 @@ func InitTestHost(th *TestHost, installable *bool, testSuites []string, autoGenC
th.properties.Installable = installable
th.testProperties.Auto_gen_config = autoGenConfig
th.testProperties.Test_suites = testSuites
+ th.sourceProperties.Test_only = proptools.BoolPtr(true)
+ th.sourceProperties.Top_level_test_target = true
}
//
@@ -1686,7 +1771,7 @@ func (j *Binary) HostToolPath() android.OptionalPath {
}
func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- j.stem = proptools.StringDefault(j.overridableDeviceProperties.Stem, ctx.ModuleName())
+ j.stem = proptools.StringDefault(j.overridableProperties.Stem, ctx.ModuleName())
if ctx.Arch().ArchType == android.Common {
// Compile the jar
@@ -1777,7 +1862,7 @@ func BinaryFactory() android.Module {
module := &Binary{}
module.addHostAndDeviceProperties()
- module.AddProperties(&module.binaryProperties)
+ module.AddProperties(&module.binaryProperties, &module.sourceProperties)
module.Module.properties.Installable = proptools.BoolPtr(true)
@@ -2172,7 +2257,7 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
case aconfigDeclarationTag:
if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.IntermediateCacheOutputPath)
- } else if provider, ok := android.OtherModuleProvider(ctx, dep, aconfig.CodegenInfoProvider); ok {
+ } else if provider, ok := android.OtherModuleProvider(ctx, dep, android.CodegenInfoProvider); ok {
al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.IntermediateCacheOutputPaths...)
} else {
ctx.ModuleErrorf("Only aconfig_declarations and aconfig_declarations_group "+
@@ -2325,6 +2410,9 @@ type ImportProperties struct {
// List of shared java libs that this module has dependencies to
Libs []string
+ // List of static java libs that this module has dependencies to
+ Static_libs []string
+
// List of files to remove from the jar file(s)
Exclude_files []string
@@ -2377,9 +2465,10 @@ type Import struct {
dexJarFileErr error
dexJarInstallFile android.Path
- combinedClasspathFile android.Path
- classLoaderContexts dexpreopt.ClassLoaderContextMap
- exportAidlIncludeDirs android.Paths
+ combinedImplementationFile android.Path
+ combinedHeaderFile android.Path
+ classLoaderContexts dexpreopt.ClassLoaderContextMap
+ exportAidlIncludeDirs android.Paths
hideApexVariantFromMake bool
@@ -2463,6 +2552,7 @@ func (j *Import) setStrictUpdatabilityLinting(bool) {
func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {
ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
+ ctx.AddVariationDependencies(nil, staticLibTag, j.properties.Static_libs...)
if ctx.Device() && Bool(j.dexProperties.Compile_dex) {
sdkDeps(ctx, android.SdkContext(j), j.dexer)
@@ -2492,23 +2582,13 @@ func (j *Import) commonBuildActions(ctx android.ModuleContext) {
func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.commonBuildActions(ctx)
- jars := android.PathsForModuleSrc(ctx, j.properties.Jars)
-
- jarName := j.Stem() + ".jar"
- outputFile := android.PathForModuleOut(ctx, "combined", jarName)
- TransformJarsToJar(ctx, outputFile, "for prebuilts", jars, android.OptionalPath{},
- false, j.properties.Exclude_files, j.properties.Exclude_dirs)
- if Bool(j.properties.Jetifier) {
- inputFile := outputFile
- outputFile = android.PathForModuleOut(ctx, "jetifier", jarName)
- TransformJetifier(ctx, outputFile, inputFile)
- }
- j.combinedClasspathFile = outputFile
j.classLoaderContexts = make(dexpreopt.ClassLoaderContextMap)
var flags javaBuilderFlags
j.collectTransitiveHeaderJars(ctx)
+ var staticJars android.Paths
+ var staticHeaderJars android.Paths
ctx.VisitDirectDeps(func(module android.Module) {
tag := ctx.OtherModuleDependencyTag(module)
if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
@@ -2518,6 +2598,8 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
flags.dexClasspath = append(flags.dexClasspath, dep.HeaderJars...)
case staticLibTag:
flags.classpath = append(flags.classpath, dep.HeaderJars...)
+ staticJars = append(staticJars, dep.ImplementationAndResourcesJars...)
+ staticHeaderJars = append(staticHeaderJars, dep.HeaderJars...)
case bootClasspathTag:
flags.bootClasspath = append(flags.bootClasspath, dep.HeaderJars...)
}
@@ -2531,6 +2613,50 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
addCLCFromDep(ctx, module, j.classLoaderContexts)
})
+ jars := android.PathsForModuleSrc(ctx, j.properties.Jars)
+ jarName := j.Stem() + ".jar"
+
+ // Always pass the input jars to TransformJarsToJar, even if there is only a single jar, we need the output
+ // file of the module to be named jarName.
+ outputFile := android.PathForModuleOut(ctx, "combined", jarName)
+ implementationJars := append(slices.Clone(jars), staticJars...)
+ TransformJarsToJar(ctx, outputFile, "combine prebuilt implementation jars", implementationJars, android.OptionalPath{},
+ false, j.properties.Exclude_files, j.properties.Exclude_dirs)
+
+ // If no dependencies have separate header jars then there is no need to create a separate
+ // header jar for this module.
+ reuseImplementationJarAsHeaderJar := slices.Equal(staticJars, staticHeaderJars)
+
+ var headerOutputFile android.ModuleOutPath
+ if reuseImplementationJarAsHeaderJar {
+ headerOutputFile = outputFile
+ } else {
+ headerJars := append(slices.Clone(jars), staticHeaderJars...)
+ headerOutputFile = android.PathForModuleOut(ctx, "turbine-combined", jarName)
+ TransformJarsToJar(ctx, headerOutputFile, "combine prebuilt header jars", headerJars, android.OptionalPath{},
+ false, j.properties.Exclude_files, j.properties.Exclude_dirs)
+ }
+
+ if Bool(j.properties.Jetifier) {
+ inputFile := outputFile
+ outputFile = android.PathForModuleOut(ctx, "jetifier", jarName)
+ TransformJetifier(ctx, outputFile, inputFile)
+
+ if !reuseImplementationJarAsHeaderJar {
+ headerInputFile := headerOutputFile
+ headerOutputFile = android.PathForModuleOut(ctx, "jetifier-headers", jarName)
+ TransformJetifier(ctx, headerOutputFile, headerInputFile)
+ } else {
+ headerOutputFile = outputFile
+ }
+ }
+
+ // Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource.
+ // Also strip the relative path from the header output file so that the reuseImplementationJarAsHeaderJar check
+ // in a module that depends on this module considers them equal.
+ j.combinedHeaderFile = headerOutputFile.WithoutRel()
+ j.combinedImplementationFile = outputFile.WithoutRel()
+
j.maybeInstall(ctx, jarName, outputFile)
j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs)
@@ -2614,11 +2740,11 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
android.SetProvider(ctx, JavaInfoProvider, JavaInfo{
- HeaderJars: android.PathsIfNonNil(j.combinedClasspathFile),
+ HeaderJars: android.PathsIfNonNil(j.combinedHeaderFile),
TransitiveLibsHeaderJars: j.transitiveLibsHeaderJars,
TransitiveStaticLibsHeaderJars: j.transitiveStaticLibsHeaderJars,
- ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedClasspathFile),
- ImplementationJars: android.PathsIfNonNil(j.combinedClasspathFile),
+ ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedImplementationFile),
+ ImplementationJars: android.PathsIfNonNil(j.combinedImplementationFile),
AidlIncludeDirs: j.exportAidlIncludeDirs,
StubsLinkType: j.stubsLinkType,
// TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
@@ -2646,7 +2772,7 @@ func (j *Import) maybeInstall(ctx android.ModuleContext, jarName string, outputF
func (j *Import) OutputFiles(tag string) (android.Paths, error) {
switch tag {
case "", ".jar":
- return android.Paths{j.combinedClasspathFile}, nil
+ return android.Paths{j.combinedImplementationFile}, nil
default:
return nil, fmt.Errorf("unsupported module reference tag %q", tag)
}
@@ -2655,17 +2781,11 @@ func (j *Import) OutputFiles(tag string) (android.Paths, error) {
var _ android.OutputFileProducer = (*Import)(nil)
func (j *Import) HeaderJars() android.Paths {
- if j.combinedClasspathFile == nil {
- return nil
- }
- return android.Paths{j.combinedClasspathFile}
+ return android.PathsIfNonNil(j.combinedHeaderFile)
}
func (j *Import) ImplementationAndResourcesJars() android.Paths {
- if j.combinedClasspathFile == nil {
- return nil
- }
- return android.Paths{j.combinedClasspathFile}
+ return android.PathsIfNonNil(j.combinedImplementationFile)
}
func (j *Import) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
@@ -2997,7 +3117,7 @@ func DefaultsFactory() android.Module {
module.AddProperties(
&CommonProperties{},
&DeviceProperties{},
- &OverridableDeviceProperties{},
+ &OverridableProperties{},
&DexProperties{},
&DexpreoptProperties{},
&android.ProtoProperties{},
@@ -3094,13 +3214,35 @@ func addCLCFromDep(ctx android.ModuleContext, depModule android.Module,
// <uses_library> and should not be added to CLC, but the transitive <uses-library> dependencies
// from its CLC should be added to the current CLC.
if sdkLib != nil {
- clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, false,
+ optional := false
+ if module, ok := ctx.Module().(ModuleWithUsesLibrary); ok {
+ if android.InList(*sdkLib, module.UsesLibrary().usesLibraryProperties.Optional_uses_libs) {
+ optional = true
+ }
+ }
+ clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, optional,
dep.DexJarBuildPath(ctx).PathOrNil(), dep.DexJarInstallPath(), dep.ClassLoaderContexts())
} else {
clcMap.AddContextMap(dep.ClassLoaderContexts(), depName)
}
}
+func addMissingOptionalUsesLibsFromDep(ctx android.ModuleContext, depModule android.Module,
+ usesLibrary *usesLibrary) {
+
+ dep, ok := depModule.(ModuleWithUsesLibrary)
+ if !ok {
+ return
+ }
+
+ for _, lib := range dep.UsesLibrary().usesLibraryProperties.Missing_optional_uses_libs {
+ if !android.InList(lib, usesLibrary.usesLibraryProperties.Missing_optional_uses_libs) {
+ usesLibrary.usesLibraryProperties.Missing_optional_uses_libs =
+ append(usesLibrary.usesLibraryProperties.Missing_optional_uses_libs, lib)
+ }
+ }
+}
+
type JavaApiContributionImport struct {
JavaApiContribution
diff --git a/java/java_test.go b/java/java_test.go
index 2f3ccb98d..2f2793202 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -588,10 +588,11 @@ func TestPrebuilts(t *testing.T) {
javac := fooModule.Rule("javac")
combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac")
barModule := ctx.ModuleForTests("bar", "android_common")
- barJar := barModule.Rule("combineJar").Output
+ barJar := barModule.Output("combined/bar.jar").Output
bazModule := ctx.ModuleForTests("baz", "android_common")
bazJar := bazModule.Rule("combineJar").Output
- sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs", "android_common").Rule("combineJar").Output
+ sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs", "android_common").
+ Output("combined/sdklib.stubs.jar").Output
fooLibrary := fooModule.Module().(*Library)
assertDeepEquals(t, "foo unique sources incorrect",
@@ -1035,7 +1036,7 @@ func TestExcludeFileGroupInSrcs(t *testing.T) {
}
}
-func TestJavaLibrary(t *testing.T) {
+func TestJavaLibraryOutputFiles(t *testing.T) {
testJavaWithFS(t, "", map[string][]byte{
"libcore/Android.bp": []byte(`
java_library {
@@ -1052,7 +1053,7 @@ func TestJavaLibrary(t *testing.T) {
})
}
-func TestJavaImport(t *testing.T) {
+func TestJavaImportOutputFiles(t *testing.T) {
testJavaWithFS(t, "", map[string][]byte{
"libcore/Android.bp": []byte(`
java_import {
@@ -1068,6 +1069,85 @@ func TestJavaImport(t *testing.T) {
})
}
+func TestJavaImport(t *testing.T) {
+ bp := `
+ java_library {
+ name: "source_library",
+ srcs: ["source.java"],
+ }
+
+ java_import {
+ name: "import_with_no_deps",
+ jars: ["no_deps.jar"],
+ }
+
+ java_import {
+ name: "import_with_source_deps",
+ jars: ["source_deps.jar"],
+ static_libs: ["source_library"],
+ }
+
+ java_import {
+ name: "import_with_import_deps",
+ jars: ["import_deps.jar"],
+ static_libs: ["import_with_no_deps"],
+ }
+ `
+ ctx := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ ).RunTestWithBp(t, bp)
+
+ source := ctx.ModuleForTests("source_library", "android_common")
+ sourceJar := source.Output("javac/source_library.jar")
+ sourceHeaderJar := source.Output("turbine-combined/source_library.jar")
+ sourceJavaInfo, _ := android.SingletonModuleProvider(ctx, source.Module(), JavaInfoProvider)
+
+ // The source library produces separate implementation and header jars
+ android.AssertPathsRelativeToTopEquals(t, "source library implementation jar",
+ []string{sourceJar.Output.String()}, sourceJavaInfo.ImplementationAndResourcesJars)
+ android.AssertPathsRelativeToTopEquals(t, "source library header jar",
+ []string{sourceHeaderJar.Output.String()}, sourceJavaInfo.HeaderJars)
+
+ importWithNoDeps := ctx.ModuleForTests("import_with_no_deps", "android_common")
+ importWithNoDepsJar := importWithNoDeps.Output("combined/import_with_no_deps.jar")
+ importWithNoDepsJavaInfo, _ := android.SingletonModuleProvider(ctx, importWithNoDeps.Module(), JavaInfoProvider)
+
+ // An import with no deps produces a single jar used as both the header and implementation jar.
+ android.AssertPathsRelativeToTopEquals(t, "import with no deps implementation jar",
+ []string{importWithNoDepsJar.Output.String()}, importWithNoDepsJavaInfo.ImplementationAndResourcesJars)
+ android.AssertPathsRelativeToTopEquals(t, "import with no deps header jar",
+ []string{importWithNoDepsJar.Output.String()}, importWithNoDepsJavaInfo.HeaderJars)
+ android.AssertPathsRelativeToTopEquals(t, "import with no deps combined inputs",
+ []string{"no_deps.jar"}, importWithNoDepsJar.Inputs)
+
+ importWithSourceDeps := ctx.ModuleForTests("import_with_source_deps", "android_common")
+ importWithSourceDepsJar := importWithSourceDeps.Output("combined/import_with_source_deps.jar")
+ importWithSourceDepsHeaderJar := importWithSourceDeps.Output("turbine-combined/import_with_source_deps.jar")
+ importWithSourceDepsJavaInfo, _ := android.SingletonModuleProvider(ctx, importWithSourceDeps.Module(), JavaInfoProvider)
+
+ // An import with source deps produces separate header and implementation jars.
+ android.AssertPathsRelativeToTopEquals(t, "import with source deps implementation jar",
+ []string{importWithSourceDepsJar.Output.String()}, importWithSourceDepsJavaInfo.ImplementationAndResourcesJars)
+ android.AssertPathsRelativeToTopEquals(t, "import with source deps header jar",
+ []string{importWithSourceDepsHeaderJar.Output.String()}, importWithSourceDepsJavaInfo.HeaderJars)
+ android.AssertPathsRelativeToTopEquals(t, "import with source deps combined implementation jar inputs",
+ []string{"source_deps.jar", sourceJar.Output.String()}, importWithSourceDepsJar.Inputs)
+ android.AssertPathsRelativeToTopEquals(t, "import with source deps combined header jar inputs",
+ []string{"source_deps.jar", sourceHeaderJar.Output.String()}, importWithSourceDepsHeaderJar.Inputs)
+
+ importWithImportDeps := ctx.ModuleForTests("import_with_import_deps", "android_common")
+ importWithImportDepsJar := importWithImportDeps.Output("combined/import_with_import_deps.jar")
+ importWithImportDepsJavaInfo, _ := android.SingletonModuleProvider(ctx, importWithImportDeps.Module(), JavaInfoProvider)
+
+ // An import with only import deps produces a single jar used as both the header and implementation jar.
+ android.AssertPathsRelativeToTopEquals(t, "import with import deps implementation jar",
+ []string{importWithImportDepsJar.Output.String()}, importWithImportDepsJavaInfo.ImplementationAndResourcesJars)
+ android.AssertPathsRelativeToTopEquals(t, "import with import deps header jar",
+ []string{importWithImportDepsJar.Output.String()}, importWithImportDepsJavaInfo.HeaderJars)
+ android.AssertPathsRelativeToTopEquals(t, "import with import deps combined implementation jar inputs",
+ []string{"import_deps.jar", importWithNoDepsJar.Output.String()}, importWithImportDepsJar.Inputs)
+}
+
var compilerFlagsTestCases = []struct {
in string
out bool
@@ -2643,6 +2723,70 @@ func TestMultiplePrebuilts(t *testing.T) {
}
}
+func TestMultiplePlatformCompatConfigPrebuilts(t *testing.T) {
+ bp := `
+ // multiple variations of platform_compat_config
+ // source
+ platform_compat_config {
+ name: "myconfig",
+ }
+ // prebuilt "v1"
+ prebuilt_platform_compat_config {
+ name: "myconfig",
+ metadata: "myconfig.xml",
+ }
+ // prebuilt "v2"
+ prebuilt_platform_compat_config {
+ name: "myconfig.v2",
+ source_module_name: "myconfig", // without source_module_name, the singleton will merge two .xml files
+ metadata: "myconfig.v2.xml",
+ }
+
+ // selectors
+ apex_contributions {
+ name: "myapex_contributions",
+ contents: ["%v"],
+ }
+ `
+ testCases := []struct {
+ desc string
+ selectedDependencyName string
+ expectedPlatformCompatConfigXml string
+ }{
+ {
+ desc: "Source platform_compat_config is selected using apex_contributions",
+ selectedDependencyName: "myconfig",
+ expectedPlatformCompatConfigXml: "out/soong/.intermediates/myconfig/android_common/myconfig_meta.xml",
+ },
+ {
+ desc: "Prebuilt platform_compat_config v1 is selected using apex_contributions",
+ selectedDependencyName: "prebuilt_myconfig",
+ expectedPlatformCompatConfigXml: "myconfig.xml",
+ },
+ {
+ desc: "Prebuilt platform_compat_config v2 is selected using apex_contributions",
+ selectedDependencyName: "prebuilt_myconfig.v2",
+ expectedPlatformCompatConfigXml: "myconfig.v2.xml",
+ },
+ }
+
+ for _, tc := range testCases {
+ ctx := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ PrepareForTestWithPlatformCompatConfig,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.BuildFlags = map[string]string{
+ "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "myapex_contributions",
+ }
+ }),
+ ).RunTestWithBp(t, fmt.Sprintf(bp, tc.selectedDependencyName))
+
+ mergedGlobalConfig := ctx.SingletonForTests("platform_compat_config_singleton").Output("compat_config/merged_compat_config.xml")
+ android.AssertIntEquals(t, "The merged compat config file should only have a single dependency", 1, len(mergedGlobalConfig.Implicits))
+ android.AssertStringEquals(t, "The merged compat config file is missing the appropriate platform compat config", mergedGlobalConfig.Implicits[0].String(), tc.expectedPlatformCompatConfigXml)
+ }
+}
+
func TestApiLibraryAconfigDeclarations(t *testing.T) {
result := android.GroupFixturePreparers(
prepareForJavaTest,
@@ -2657,6 +2801,7 @@ func TestApiLibraryAconfigDeclarations(t *testing.T) {
aconfig_declarations {
name: "bar",
package: "com.example.package",
+ container: "com.android.foo",
srcs: [
"bar.aconfig",
],
@@ -2693,3 +2838,207 @@ func TestApiLibraryAconfigDeclarations(t *testing.T) {
cmdline := String(android.RuleBuilderSboxProtoForTests(t, result.TestContext, manifest).Commands[0].Command)
android.AssertStringDoesContain(t, "flagged api hide command not included", cmdline, "revert-annotations-exportable.txt")
}
+
+func TestTestOnly(t *testing.T) {
+ t.Parallel()
+ ctx := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ ).RunTestWithBp(t, `
+ // These should be test-only
+ java_library {
+ name: "lib1-test-only",
+ srcs: ["a.java"],
+ test_only: true,
+ }
+ java_test {
+ name: "java-test",
+ }
+ java_test_host {
+ name: "java-test-host",
+ }
+ java_test_helper_library {
+ name: "helper-library",
+ }
+ java_binary {
+ name: "java-data-binary",
+ srcs: ["foo.java"],
+ main_class: "foo.bar.jb",
+ test_only: true,
+ }
+
+ // These are NOT
+ java_library {
+ name: "lib2-app",
+ srcs: ["b.java"],
+ }
+ java_import {
+ name: "bar",
+ jars: ["bar.jar"],
+ }
+ java_binary {
+ name: "java-binary",
+ srcs: ["foo.java"],
+ main_class: "foo.bar.jb",
+ }
+ `)
+
+ expectedTestOnlyModules := []string{
+ "lib1-test-only",
+ "java-test",
+ "java-test-host",
+ "helper-library",
+ "java-data-binary",
+ }
+ expectedTopLevelTests := []string{
+ "java-test",
+ "java-test-host",
+ }
+ assertTestOnlyAndTopLevel(t, ctx, expectedTestOnlyModules, expectedTopLevelTests)
+}
+
+// Don't allow setting test-only on things that are always tests or never tests.
+func TestInvalidTestOnlyTargets(t *testing.T) {
+ testCases := []string{
+ ` java_test { name: "java-test", test_only: true, srcs: ["foo.java"], } `,
+ ` java_test_host { name: "java-test-host", test_only: true, srcs: ["foo.java"], } `,
+ ` java_test_import { name: "java-test-import", test_only: true, } `,
+ ` java_api_library { name: "java-api-library", test_only: true, } `,
+ ` java_test_helper_library { name: "test-help-lib", test_only: true, } `,
+ ` java_defaults { name: "java-defaults", test_only: true, } `,
+ }
+
+ for i, bp := range testCases {
+ android.GroupFixturePreparers(prepareForJavaTest).
+ ExtendWithErrorHandler(
+ expectOneError("unrecognized property \"test_only\"",
+ fmt.Sprintf("testcase: %d", i))).
+ RunTestWithBp(t, bp)
+ }
+}
+
+// Expect exactly one that matches 'expected'.
+// Append 'msg' to the Errorf that printed.
+func expectOneError(expected string, msg string) android.FixtureErrorHandler {
+ return android.FixtureCustomErrorHandler(func(t *testing.T, result *android.TestResult) {
+ t.Helper()
+ if len(result.Errs) != 1 {
+ t.Errorf("Expected exactly one error, but found: %d when setting test_only on: %s", len(result.Errs), msg)
+ return
+ }
+ actualErrMsg := result.Errs[0].Error()
+ if !strings.Contains(actualErrMsg, expected) {
+ t.Errorf("Different error than expected. Received: [%v] on %s expected: %s", actualErrMsg, msg, expected)
+ }
+ })
+}
+
+func TestJavaLibHostWithStem(t *testing.T) {
+ ctx, _ := testJava(t, `
+ java_library_host {
+ name: "foo",
+ srcs: ["a.java"],
+ stem: "foo-new",
+ }
+ `)
+
+ buildOS := ctx.Config().BuildOS.String()
+ foo := ctx.ModuleForTests("foo", buildOS+"_common")
+
+ outputs := fmt.Sprint(foo.AllOutputs())
+ if !strings.Contains(outputs, "foo-new.jar") {
+ t.Errorf("Module output does not contain expected jar %s", "foo-new.jar")
+ }
+}
+
+func TestJavaLibWithStem(t *testing.T) {
+ ctx, _ := testJava(t, `
+ java_library {
+ name: "foo",
+ srcs: ["a.java"],
+ stem: "foo-new",
+ }
+ `)
+
+ foo := ctx.ModuleForTests("foo", "android_common")
+
+ outputs := fmt.Sprint(foo.AllOutputs())
+ if !strings.Contains(outputs, "foo-new.jar") {
+ t.Errorf("Module output does not contain expected jar %s", "foo-new.jar")
+ }
+}
+
+func TestJavaLibraryOutputFilesRel(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ ).RunTestWithBp(t, `
+ java_library {
+ name: "foo",
+ srcs: ["a.java"],
+ }
+
+ java_import {
+ name: "bar",
+ jars: ["bar.aar"],
+
+ }
+
+ java_import {
+ name: "baz",
+ jars: ["baz.aar"],
+ static_libs: ["bar"],
+ }
+ `)
+
+ foo := result.ModuleForTests("foo", "android_common")
+ bar := result.ModuleForTests("bar", "android_common")
+ baz := result.ModuleForTests("baz", "android_common")
+
+ fooOutputPath := android.OutputFileForModule(android.PathContext(nil), foo.Module(), "")
+ barOutputPath := android.OutputFileForModule(android.PathContext(nil), bar.Module(), "")
+ bazOutputPath := android.OutputFileForModule(android.PathContext(nil), baz.Module(), "")
+
+ android.AssertPathRelativeToTopEquals(t, "foo output path",
+ "out/soong/.intermediates/foo/android_common/javac/foo.jar", fooOutputPath)
+ android.AssertPathRelativeToTopEquals(t, "bar output path",
+ "out/soong/.intermediates/bar/android_common/combined/bar.jar", barOutputPath)
+ android.AssertPathRelativeToTopEquals(t, "baz output path",
+ "out/soong/.intermediates/baz/android_common/combined/baz.jar", bazOutputPath)
+
+ android.AssertStringEquals(t, "foo relative output path",
+ "foo.jar", fooOutputPath.Rel())
+ android.AssertStringEquals(t, "bar relative output path",
+ "bar.jar", barOutputPath.Rel())
+ android.AssertStringEquals(t, "baz relative output path",
+ "baz.jar", bazOutputPath.Rel())
+}
+
+func assertTestOnlyAndTopLevel(t *testing.T, ctx *android.TestResult, expectedTestOnly []string, expectedTopLevel []string) {
+ t.Helper()
+ actualTrueModules := []string{}
+ actualTopLevelTests := []string{}
+ addActuals := func(m blueprint.Module, key blueprint.ProviderKey[android.TestModuleInformation]) {
+ if provider, ok := android.OtherModuleProvider(ctx.TestContext.OtherModuleProviderAdaptor(), m, key); ok {
+ if provider.TestOnly {
+ actualTrueModules = append(actualTrueModules, m.Name())
+ }
+ if provider.TopLevelTarget {
+ actualTopLevelTests = append(actualTopLevelTests, m.Name())
+ }
+ }
+ }
+
+ ctx.VisitAllModules(func(m blueprint.Module) {
+ addActuals(m, android.TestOnlyProviderKey)
+
+ })
+
+ notEqual, left, right := android.ListSetDifference(expectedTestOnly, actualTrueModules)
+ if notEqual {
+ t.Errorf("test-only: Expected but not found: %v, Found but not expected: %v", left, right)
+ }
+
+ notEqual, left, right = android.ListSetDifference(expectedTopLevel, actualTopLevelTests)
+ if notEqual {
+ t.Errorf("top-level: Expected but not found: %v, Found but not expected: %v", left, right)
+ }
+}
diff --git a/java/jdeps.go b/java/jdeps.go
index 91f7ce715..340026318 100644
--- a/java/jdeps.go
+++ b/java/jdeps.go
@@ -48,7 +48,7 @@ func (j *jdepsGeneratorSingleton) GenerateBuildActions(ctx android.SingletonCont
moduleInfos := make(map[string]android.IdeInfo)
ctx.VisitAllModules(func(module android.Module) {
- if !module.Enabled() {
+ if !module.Enabled(ctx) {
return
}
diff --git a/java/lint.go b/java/lint.go
index c79f6e7bb..2eea07d31 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -606,7 +606,7 @@ func (l *lintSingleton) copyLintDependencies(ctx android.SingletonContext) {
apiVersionsDb := findModuleOrErr(ctx, files.apiVersionsModule)
if apiVersionsDb == nil {
if !ctx.Config().AllowMissingDependencies() {
- ctx.Errorf("lint: missing module api_versions_public")
+ ctx.Errorf("lint: missing module %s", files.apiVersionsModule)
}
return
}
@@ -614,7 +614,7 @@ func (l *lintSingleton) copyLintDependencies(ctx android.SingletonContext) {
sdkAnnotations := findModuleOrErr(ctx, files.annotationsModule)
if sdkAnnotations == nil {
if !ctx.Config().AllowMissingDependencies() {
- ctx.Errorf("lint: missing module sdk-annotations.zip")
+ ctx.Errorf("lint: missing module %s", files.annotationsModule)
}
return
}
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index 4db426e0d..8d4cf6823 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -221,6 +221,7 @@ func (b *platformBootclasspathModule) generateClasspathProtoBuildActions(ctx and
// ART and platform boot jars must have a corresponding entry in DEX2OATBOOTCLASSPATH
classpathJars := configuredJarListToClasspathJars(ctx, configuredJars, BOOTCLASSPATH, DEX2OATBOOTCLASSPATH)
b.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, configuredJars, classpathJars)
+ b.classpathFragmentBase().installClasspathProto(ctx)
}
func (b *platformBootclasspathModule) configuredJars(ctx android.ModuleContext) android.ConfiguredJarList {
@@ -293,6 +294,15 @@ func (b *platformBootclasspathModule) checkApexModules(ctx android.ModuleContext
// generateHiddenAPIBuildActions generates all the hidden API related build rules.
func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, modules []android.Module, fragments []android.Module) bootDexJarByModule {
+ createEmptyHiddenApiFiles := func() {
+ paths := android.OutputPaths{b.hiddenAPIFlagsCSV, b.hiddenAPIIndexCSV, b.hiddenAPIMetadataCSV}
+ for _, path := range paths {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Touch,
+ Output: path,
+ })
+ }
+ }
// Save the paths to the monolithic files for retrieval via OutputFiles().
b.hiddenAPIFlagsCSV = hiddenAPISingletonPaths(ctx).flags
@@ -305,13 +315,7 @@ func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.
// 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().DisableHiddenApiChecks() {
- paths := android.OutputPaths{b.hiddenAPIFlagsCSV, b.hiddenAPIIndexCSV, b.hiddenAPIMetadataCSV}
- for _, path := range paths {
- ctx.Build(pctx, android.BuildParams{
- Rule: android.Touch,
- Output: path,
- })
- }
+ createEmptyHiddenApiFiles()
return bootDexJarByModule
}
@@ -324,6 +328,13 @@ func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.
// the fragments will have already provided the flags that are needed.
classesJars := monolithicInfo.ClassesJars
+ if len(classesJars) == 0 {
+ // This product does not include any monolithic jars. Monolithic hiddenapi flag generation is not required.
+ // However, generate an empty file so that the dist tags in f/b/boot/Android.bp can be resolved, and `m dist` works.
+ createEmptyHiddenApiFiles()
+ return bootDexJarByModule
+ }
+
// Create the input to pass to buildRuleToGenerateHiddenAPIStubFlagsFile
input := newHiddenAPIFlagInput()
diff --git a/java/platform_bootclasspath_test.go b/java/platform_bootclasspath_test.go
index 37ff6395c..0d2acaea0 100644
--- a/java/platform_bootclasspath_test.go
+++ b/java/platform_bootclasspath_test.go
@@ -353,7 +353,7 @@ func TestPlatformBootclasspath_HiddenAPIMonolithicFiles(t *testing.T) {
// All the intermediate rules use the same inputs.
expectedIntermediateInputs := `
- out/soong/.intermediates/bar/android_common/javac/bar.jar
+ out/soong/.intermediates/bar.impl/android_common/javac/bar.jar
out/soong/.intermediates/foo-hiddenapi-annotations/android_common/javac/foo-hiddenapi-annotations.jar
out/soong/.intermediates/foo/android_common/javac/foo.jar
`
diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go
index 2197304a5..99fa092be 100644
--- a/java/platform_compat_config.go
+++ b/java/platform_compat_config.go
@@ -19,7 +19,9 @@ import (
"path/filepath"
"android/soong/android"
+
"github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
)
func init() {
@@ -184,6 +186,11 @@ type prebuiltCompatConfigModule struct {
type prebuiltCompatConfigProperties struct {
Metadata *string `android:"path"`
+
+ // Name of the source soong module that gets shadowed by this prebuilt
+ // If unspecified, follows the naming convention that the source module of
+ // the prebuilt is Name() without "prebuilt_" prefix
+ Source_module_name *string
}
func (module *prebuiltCompatConfigModule) Prebuilt() *android.Prebuilt {
@@ -198,6 +205,10 @@ func (module *prebuiltCompatConfigModule) compatConfigMetadata() android.Path {
return module.metadataFile
}
+func (module *prebuiltCompatConfigModule) BaseModuleName() string {
+ return proptools.StringDefault(module.properties.Source_module_name, module.ModuleBase.Name())
+}
+
var _ platformCompatConfigMetadataProvider = (*prebuiltCompatConfigModule)(nil)
func (module *prebuiltCompatConfigModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -223,7 +234,7 @@ func (p *platformCompatConfigSingleton) GenerateBuildActions(ctx android.Singlet
var compatConfigMetadata android.Paths
ctx.VisitAllModules(func(module android.Module) {
- if !module.Enabled() {
+ if !module.Enabled(ctx) {
return
}
if c, ok := module.(platformCompatConfigMetadataProvider); ok {
diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go
index 94e9c6c57..00613eee3 100644
--- a/java/prebuilt_apis.go
+++ b/java/prebuilt_apis.go
@@ -158,6 +158,21 @@ func createApiModule(mctx android.LoadHookContext, name string, path string) {
mctx.CreateModule(genrule.GenRuleFactory, &genruleProps)
}
+func createCombinedApiFilegroupModule(mctx android.LoadHookContext, name string, srcs []string) {
+ filegroupProps := struct {
+ Name *string
+ Srcs []string
+ }{}
+ filegroupProps.Name = proptools.StringPtr(name)
+
+ var transformedSrcs []string
+ for _, src := range srcs {
+ transformedSrcs = append(transformedSrcs, ":"+src)
+ }
+ filegroupProps.Srcs = transformedSrcs
+ mctx.CreateModule(android.FileGroupFactory, &filegroupProps)
+}
+
func createLatestApiModuleExtensionVersionFile(mctx android.LoadHookContext, name string, version string) {
genruleProps := struct {
Name *string
@@ -252,6 +267,10 @@ func PrebuiltApiModuleName(module, scope, version string) string {
return module + ".api." + scope + "." + version
}
+func PrebuiltApiCombinedModuleName(module, scope, version string) string {
+ return module + ".api.combined." + scope + "." + version
+}
+
func prebuiltApiFiles(mctx android.LoadHookContext, p *prebuiltApis) {
// <apiver>/<scope>/api/<module>.txt
apiLevelFiles := globApiDirs(mctx, p, "api/*.txt")
@@ -307,7 +326,9 @@ func prebuiltApiFiles(mctx android.LoadHookContext, p *prebuiltApis) {
}
// Sort the keys in order to make build.ninja stable
- for _, k := range android.SortedKeys(latest) {
+ sortedLatestKeys := android.SortedKeys(latest)
+
+ for _, k := range sortedLatestKeys {
info := latest[k]
name := PrebuiltApiModuleName(info.module, info.scope, "latest")
latestExtensionVersionModuleName := PrebuiltApiModuleName(info.module, info.scope, "latest.extension_version")
@@ -333,11 +354,38 @@ func prebuiltApiFiles(mctx android.LoadHookContext, p *prebuiltApis) {
}
}
// Create empty incompatibilities files for remaining modules
- for _, k := range android.SortedKeys(latest) {
+ // If the incompatibility module has been created, create a corresponding combined module
+ for _, k := range sortedLatestKeys {
if _, ok := incompatibilities[k]; !ok {
createEmptyFile(mctx, PrebuiltApiModuleName(latest[k].module+"-incompatibilities", latest[k].scope, "latest"))
}
}
+
+ // Create combined latest api and removed api files modules.
+ // The combined modules list all api files of the api scope and its subset api scopes.
+ for _, k := range sortedLatestKeys {
+ info := latest[k]
+ name := PrebuiltApiCombinedModuleName(info.module, info.scope, "latest")
+
+ // Iterate until the currentApiScope does not extend any other api scopes
+ // i.e. is not a superset of any other api scopes
+ // the relationship between the api scopes is defined in java/sdk_library.go
+ var srcs []string
+ currentApiScope := scopeByName[info.scope]
+ for currentApiScope != nil {
+ if _, ok := latest[fmt.Sprintf("%s.%s", info.module, currentApiScope.name)]; ok {
+ srcs = append(srcs, PrebuiltApiModuleName(info.module, currentApiScope.name, "latest"))
+ }
+ currentApiScope = currentApiScope.extends
+ }
+
+ // srcs is currently listed in the order from the widest api scope to the narrowest api scopes
+ // e.g. module lib -> system -> public
+ // In order to pass the files in metalava from the narrowest api scope to the widest api scope,
+ // the list has to be reversed.
+ android.ReverseSliceInPlace(srcs)
+ createCombinedApiFilegroupModule(mctx, name, srcs)
+ }
}
func createPrebuiltApiModules(mctx android.LoadHookContext) {
diff --git a/java/robolectric.go b/java/robolectric.go
index 9e8850ce9..18386c90c 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -46,6 +46,7 @@ const robolectricPrebuiltLibPattern = "platform-robolectric-%s-prebuilt"
var (
roboCoverageLibsTag = dependencyTag{name: "roboCoverageLibs"}
roboRuntimesTag = dependencyTag{name: "roboRuntimes"}
+ roboRuntimeOnlyTag = dependencyTag{name: "roboRuntimeOnlyTag"}
)
type robolectricProperties struct {
@@ -70,6 +71,9 @@ type robolectricProperties struct {
// Use /external/robolectric rather than /external/robolectric-shadows as the version of robolectric
// to use. /external/robolectric closely tracks github's master, and will fully replace /external/robolectric-shadows
Upstream *bool
+
+ // Use strict mode to limit access of Robolectric API directly. See go/roboStrictMode
+ Strict_mode *bool
}
type robolectricTest struct {
@@ -112,7 +116,7 @@ func (r *robolectricTest) DepsMutator(ctx android.BottomUpMutatorContext) {
if v := String(r.robolectricProperties.Robolectric_prebuilt_version); v != "" {
ctx.AddVariationDependencies(nil, libTag, fmt.Sprintf(robolectricPrebuiltLibPattern, v))
- } else {
+ } else if !proptools.Bool(r.robolectricProperties.Strict_mode) {
if proptools.Bool(r.robolectricProperties.Upstream) {
ctx.AddVariationDependencies(nil, libTag, robolectricCurrentLib+"_upstream")
} else {
@@ -120,6 +124,10 @@ func (r *robolectricTest) DepsMutator(ctx android.BottomUpMutatorContext) {
}
}
+ if proptools.Bool(r.robolectricProperties.Strict_mode) {
+ ctx.AddVariationDependencies(nil, roboRuntimeOnlyTag, robolectricCurrentLib+"_upstream")
+ }
+
ctx.AddVariationDependencies(nil, libTag, robolectricDefaultLibs...)
ctx.AddVariationDependencies(nil, roboCoverageLibsTag, r.robolectricProperties.Coverage_libs...)
@@ -192,19 +200,25 @@ func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext)
combinedJarJars = append(combinedJarJars, instrumentedApp.implementationAndResourcesJar)
}
- handleLibDeps := func(dep android.Module) {
+ handleLibDeps := func(dep android.Module, runtimeOnly bool) {
m, _ := android.OtherModuleProvider(ctx, dep, JavaInfoProvider)
- r.libs = append(r.libs, ctx.OtherModuleName(dep))
+ if !runtimeOnly {
+ r.libs = append(r.libs, ctx.OtherModuleName(dep))
+ }
if !android.InList(ctx.OtherModuleName(dep), config.FrameworkLibraries) {
combinedJarJars = append(combinedJarJars, m.ImplementationAndResourcesJars...)
}
}
for _, dep := range ctx.GetDirectDepsWithTag(libTag) {
- handleLibDeps(dep)
+ handleLibDeps(dep, false)
}
for _, dep := range ctx.GetDirectDepsWithTag(sdkLibTag) {
- handleLibDeps(dep)
+ handleLibDeps(dep, false)
+ }
+ // handle the runtimeOnly tag for strict_mode
+ for _, dep := range ctx.GetDirectDepsWithTag(roboRuntimeOnlyTag) {
+ handleLibDeps(dep, true)
}
r.combinedJar = android.PathForModuleOut(ctx, "robolectric_combined", r.outputFile.Base())
diff --git a/java/rro.go b/java/rro.go
index 3e0f8e94d..72170fc6d 100644
--- a/java/rro.go
+++ b/java/rro.go
@@ -122,6 +122,10 @@ func (r *RuntimeResourceOverlay) DepsMutator(ctx android.BottomUpMutatorContext)
ctx.AddVariationDependencies(nil, staticLibTag, r.properties.Static_libs...)
ctx.AddVariationDependencies(nil, libTag, r.properties.Resource_libs...)
+
+ for _, aconfig_declaration := range r.aaptProperties.Flags_packages {
+ ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
+ }
}
func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -151,6 +155,7 @@ func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleC
sdkContext: r,
enforceDefaultTargetSdkVersion: false,
extraLinkFlags: aaptLinkFlags,
+ aconfigTextFiles: getAconfigFilePaths(ctx),
},
)
diff --git a/java/rro_test.go b/java/rro_test.go
index c4a4d04be..742c83982 100644
--- a/java/rro_test.go
+++ b/java/rro_test.go
@@ -405,3 +405,51 @@ func TestRuntimeResourceOverlayPartition(t *testing.T) {
android.AssertPathRelativeToTopEquals(t, "Install dir is not correct for "+testCase.name, testCase.expectedPath, mod.installDir)
}
}
+
+func TestRuntimeResourceOverlayFlagsPackages(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ ).RunTestWithBp(t, `
+ runtime_resource_overlay {
+ name: "foo",
+ sdk_version: "current",
+ flags_packages: [
+ "bar",
+ "baz",
+ ],
+ }
+ aconfig_declarations {
+ name: "bar",
+ package: "com.example.package.bar",
+ container: "com.android.foo",
+ srcs: [
+ "bar.aconfig",
+ ],
+ }
+ aconfig_declarations {
+ name: "baz",
+ package: "com.example.package.baz",
+ container: "com.android.foo",
+ srcs: [
+ "baz.aconfig",
+ ],
+ }
+ `)
+
+ foo := result.ModuleForTests("foo", "android_common")
+
+ // runtime_resource_overlay module depends on aconfig_declarations listed in flags_packages
+ android.AssertBoolEquals(t, "foo expected to depend on bar", true,
+ CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "bar"))
+
+ android.AssertBoolEquals(t, "foo expected to depend on baz", true,
+ CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "baz"))
+
+ aapt2LinkRule := foo.Rule("android/soong/java.aapt2Link")
+ linkInFlags := aapt2LinkRule.Args["inFlags"]
+ android.AssertStringDoesContain(t,
+ "aapt2 link command expected to pass feature flags arguments",
+ linkInFlags,
+ "--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt",
+ )
+}
diff --git a/java/sdk.go b/java/sdk.go
index 3591ccdb6..4ef4ee251 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -31,7 +31,6 @@ func init() {
var sdkFrameworkAidlPathKey = android.NewOnceKey("sdkFrameworkAidlPathKey")
var nonUpdatableFrameworkAidlPathKey = android.NewOnceKey("nonUpdatableFrameworkAidlPathKey")
-var apiFingerprintPathKey = android.NewOnceKey("apiFingerprintPathKey")
func UseApiFingerprint(ctx android.BaseModuleContext) (useApiFingerprint bool, fingerprintSdkVersion string, fingerprintDeps android.OutputPath) {
if ctx.Config().UnbundledBuild() && !ctx.Config().AlwaysUsePrebuiltSdks() {
@@ -45,8 +44,8 @@ func UseApiFingerprint(ctx android.BaseModuleContext) (useApiFingerprint bool, f
useApiFingerprint = apiFingerprintTrue || dessertShaIsSet
if apiFingerprintTrue {
- fingerprintSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", ApiFingerprintPath(ctx).String())
- fingerprintDeps = ApiFingerprintPath(ctx)
+ fingerprintSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", android.ApiFingerprintPath(ctx).String())
+ fingerprintDeps = android.ApiFingerprintPath(ctx)
}
if dessertShaIsSet {
fingerprintSdkVersion = ctx.Config().Getenv("UNBUNDLED_BUILD_TARGET_SDK_WITH_DESSERT_SHA")
@@ -66,6 +65,12 @@ func defaultJavaLanguageVersion(ctx android.EarlyModuleContext, s android.SdkSpe
return JAVA_VERSION_9
} else if sdk.FinalOrFutureInt() <= 33 {
return JAVA_VERSION_11
+ } else if ctx.Config().TargetsJava21() {
+ // Temporary experimental flag to be able to try and build with
+ // java version 21 options. The flag, if used, just sets Java
+ // 21 as the default version, leaving any components that
+ // target an older version intact.
+ return JAVA_VERSION_21
} else {
return JAVA_VERSION_17
}
@@ -337,7 +342,7 @@ func nonUpdatableFrameworkAidlPath(ctx android.PathContext) android.OutputPath {
// Create api_fingerprint.txt
func createAPIFingerprint(ctx android.SingletonContext) {
- out := ApiFingerprintPath(ctx)
+ out := android.ApiFingerprintPath(ctx)
rule := android.NewRuleBuilder(pctx, ctx)
@@ -378,17 +383,11 @@ func createAPIFingerprint(ctx android.SingletonContext) {
rule.Build("api_fingerprint", "generate api_fingerprint.txt")
}
-func ApiFingerprintPath(ctx android.PathContext) android.OutputPath {
- return ctx.Config().Once(apiFingerprintPathKey, func() interface{} {
- return android.PathForOutput(ctx, "api_fingerprint.txt")
- }).(android.OutputPath)
-}
-
func sdkMakeVars(ctx android.MakeVarsContext) {
if ctx.Config().AlwaysUsePrebuiltSdks() {
return
}
ctx.Strict("FRAMEWORK_AIDL", sdkFrameworkAidlPath(ctx).String())
- ctx.Strict("API_FINGERPRINT", ApiFingerprintPath(ctx).String())
+ ctx.Strict("API_FINGERPRINT", android.ApiFingerprintPath(ctx).String())
}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index cdd04483d..72eb6e346 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -30,6 +30,7 @@ import (
"android/soong/android"
"android/soong/dexpreopt"
+ "android/soong/etc"
)
const (
@@ -704,10 +705,10 @@ type scopePaths struct {
annotationsZip android.OptionalPath
// The path to the latest API file.
- latestApiPath android.OptionalPath
+ latestApiPaths android.Paths
// The path to the latest removed API file.
- latestRemovedApiPath android.OptionalPath
+ latestRemovedApiPaths android.Paths
}
func (paths *scopePaths) extractStubsLibraryInfoFromDependency(ctx android.ModuleContext, dep android.Module) error {
@@ -828,28 +829,25 @@ func (paths *scopePaths) extractStubsSourceAndApiInfoFromApiStubsProvider(ctx an
})
}
-func extractSingleOptionalOutputPath(dep android.Module) (android.OptionalPath, error) {
+func extractOutputPaths(dep android.Module) (android.Paths, error) {
var paths android.Paths
if sourceFileProducer, ok := dep.(android.SourceFileProducer); ok {
paths = sourceFileProducer.Srcs()
+ return paths, nil
} else {
- return android.OptionalPath{}, fmt.Errorf("module %q does not produce source files", dep)
+ return nil, fmt.Errorf("module %q does not produce source files", dep)
}
- if len(paths) != 1 {
- return android.OptionalPath{}, fmt.Errorf("expected one path from %q, got %q", dep, paths)
- }
- return android.OptionalPathForPath(paths[0]), nil
}
func (paths *scopePaths) extractLatestApiPath(ctx android.ModuleContext, dep android.Module) error {
- outputPath, err := extractSingleOptionalOutputPath(dep)
- paths.latestApiPath = outputPath
+ outputPaths, err := extractOutputPaths(dep)
+ paths.latestApiPaths = outputPaths
return err
}
func (paths *scopePaths) extractLatestRemovedApiPath(ctx android.ModuleContext, dep android.Module) error {
- outputPath, err := extractSingleOptionalOutputPath(dep)
- paths.latestRemovedApiPath = outputPath
+ outputPaths, err := extractOutputPaths(dep)
+ paths.latestRemovedApiPaths = outputPaths
return err
}
@@ -948,6 +946,14 @@ type commonToSdkLibraryAndImport struct {
// Functionality related to this being used as a component of a java_sdk_library.
EmbeddableSdkLibraryComponent
+
+ // Path to the header jars of the implementation library
+ // This is non-empty only when api_only is false.
+ implLibraryHeaderJars android.Paths
+
+ // The reference to the implementation library created by the source module.
+ // Is nil if the source module does not exist.
+ implLibraryModule *Library
}
func (c *commonToSdkLibraryAndImport) initCommon(module commonSdkLibraryAndImportModule) {
@@ -994,6 +1000,10 @@ func (c *commonToSdkLibraryAndImport) generateCommonBuildActions(ctx android.Mod
c.doctagPaths = android.PathsForModuleSrc(ctx, c.commonSdkLibraryProperties.Doctag_files)
}
+func (c *commonToSdkLibraryAndImport) getImplLibraryModule() *Library {
+ return c.implLibraryModule
+}
+
// Module name of the runtime implementation library
func (c *commonToSdkLibraryAndImport) implLibraryModuleName() string {
return c.module.RootLibraryName() + ".impl"
@@ -1355,13 +1365,6 @@ type SdkLibraryDependency interface {
// class changes but it does not contain and implementation or JavaDoc.
SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths
- // Get the implementation jars appropriate for the supplied sdk version.
- //
- // These are either the implementation jar for the whole sdk library or the implementation
- // jars for the stubs. The latter should only be needed when generating JavaDoc as otherwise
- // they are identical to the corresponding header jars.
- SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths
-
// SdkApiStubDexJar returns the dex jar for the stubs for the prebuilt
// java_sdk_library_import module. It is needed by the hiddenapi processing tool which
// processes dex files.
@@ -1377,6 +1380,8 @@ type SdkLibraryDependency interface {
// sharedLibrary returns true if this can be used as a shared library.
sharedLibrary() bool
+
+ getImplLibraryModule() *Library
}
type SdkLibrary struct {
@@ -1388,6 +1393,8 @@ type SdkLibrary struct {
scopeToProperties map[*apiScope]*ApiScopeProperties
commonToSdkLibraryAndImport
+
+ builtInstalledForApex []dexpreopterInstall
}
var _ SdkLibraryDependency = (*SdkLibrary)(nil)
@@ -1396,6 +1403,20 @@ func (module *SdkLibrary) generateTestAndSystemScopesByDefault() bool {
return module.sdkLibraryProperties.Generate_system_and_test_apis
}
+func (module *SdkLibrary) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
+ if module.implLibraryModule != nil {
+ return module.implLibraryModule.DexJarBuildPath(ctx)
+ }
+ return makeUnsetDexJarPath()
+}
+
+func (module *SdkLibrary) DexJarInstallPath() android.Path {
+ if module.implLibraryModule != nil {
+ return module.implLibraryModule.DexJarInstallPath()
+ }
+ return nil
+}
+
func (module *SdkLibrary) getGeneratedApiScopes(ctx android.EarlyModuleContext) apiScopes {
// Check to see if any scopes have been explicitly enabled. If any have then all
// must be.
@@ -1447,6 +1468,10 @@ func (module *SdkLibrary) getGeneratedApiScopes(ctx android.EarlyModuleContext)
var _ android.ModuleWithMinSdkVersionCheck = (*SdkLibrary)(nil)
func (module *SdkLibrary) CheckMinSdkVersion(ctx android.ModuleContext) {
+ CheckMinSdkVersion(ctx, &module.Library)
+}
+
+func CheckMinSdkVersion(ctx android.ModuleContext, module *Library) {
android.CheckMinSdkVersion(ctx, module.MinSdkVersion(ctx), func(c android.ModuleContext, do android.PayloadDepsCallback) {
ctx.WalkDeps(func(child android.Module, parent android.Module) bool {
isExternal := !module.depIsInSameApex(ctx, child)
@@ -1479,6 +1504,18 @@ func IsXmlPermissionsFileDepTag(depTag blueprint.DependencyTag) bool {
var implLibraryTag = sdkLibraryComponentTag{name: "impl-library"}
+var _ android.InstallNeededDependencyTag = sdkLibraryComponentTag{}
+
+// To satisfy the CopyDirectlyInAnyApexTag interface. Implementation library of the sdk library
+// in an apex is considered to be directly in the apex, as if it was listed in java_libs.
+func (t sdkLibraryComponentTag) CopyDirectlyInAnyApex() {}
+
+var _ android.CopyDirectlyInAnyApexTag = implLibraryTag
+
+func (t sdkLibraryComponentTag) InstallDepNeeded() bool {
+ return t.name == "xml-permissions-file" || t.name == "impl-library"
+}
+
// Add the dependencies on the child modules in the component deps mutator.
func (module *SdkLibrary) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
for _, apiScope := range module.getGeneratedApiScopes(ctx) {
@@ -1543,10 +1580,6 @@ func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
m += "Please see the documentation of the prebuilt_apis module type (and a usage example in prebuilts/sdk) for a convenient way to generate these."
ctx.ModuleErrorf(m)
}
- if module.requiresRuntimeImplementationLibrary() {
- // Only add the deps for the library if it is actually going to be built.
- module.Library.deps(ctx)
- }
}
func (module *SdkLibrary) OutputFiles(tag string) (android.Paths, error) {
@@ -1555,7 +1588,7 @@ func (module *SdkLibrary) OutputFiles(tag string) (android.Paths, error) {
return paths, err
}
if module.requiresRuntimeImplementationLibrary() {
- return module.Library.OutputFiles(tag)
+ return module.implLibraryModule.OutputFiles(tag)
}
if tag == "" {
return nil, nil
@@ -1564,18 +1597,18 @@ func (module *SdkLibrary) OutputFiles(tag string) (android.Paths, error) {
}
func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- if proptools.String(module.deviceProperties.Min_sdk_version) != "" {
- module.CheckMinSdkVersion(ctx)
+ if disableSourceApexVariant(ctx) {
+ // Prebuilts are active, do not create the installation rules for the source javalib.
+ // Even though the source javalib is not used, we need to hide it to prevent duplicate installation rules.
+ // TODO (b/331665856): Implement a principled solution for this.
+ module.HideFromMake()
}
module.generateCommonBuildActions(ctx)
- // Only build an implementation library if required.
- if module.requiresRuntimeImplementationLibrary() {
- // stubsLinkType must be set before calling Library.GenerateAndroidBuildActions
- module.Library.stubsLinkType = Unknown
- module.Library.GenerateAndroidBuildActions(ctx)
- }
+ module.stem = proptools.StringDefault(module.overridableProperties.Stem, ctx.ModuleName())
+
+ module.provideHiddenAPIPropertyInfo(ctx)
// Collate the components exported by this module. All scope specific modules are exported but
// the impl and xml component modules are not.
@@ -1598,8 +1631,52 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
exportedComponents[ctx.OtherModuleName(to)] = struct{}{}
}
+
+ if tag == implLibraryTag {
+ if dep, ok := android.OtherModuleProvider(ctx, to, JavaInfoProvider); ok {
+ module.implLibraryHeaderJars = append(module.implLibraryHeaderJars, dep.HeaderJars...)
+ module.implLibraryModule = to.(*Library)
+ android.SetProvider(ctx, JavaInfoProvider, dep)
+ }
+ }
})
+ apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
+ if !apexInfo.IsForPlatform() {
+ module.hideApexVariantFromMake = true
+ }
+
+ if module.implLibraryModule != nil {
+ if ctx.Device() {
+ module.classesJarPaths = android.Paths{module.implLibraryModule.implementationJarFile}
+ module.bootDexJarPath = module.implLibraryModule.bootDexJarPath
+ module.uncompressDexState = module.implLibraryModule.uncompressDexState
+ module.active = module.implLibraryModule.active
+ }
+
+ module.outputFile = module.implLibraryModule.outputFile
+ module.dexJarFile = makeDexJarPathFromPath(module.implLibraryModule.dexJarFile.Path())
+ module.headerJarFile = module.implLibraryModule.headerJarFile
+ module.implementationAndResourcesJar = module.implLibraryModule.implementationAndResourcesJar
+ module.builtInstalledForApex = module.implLibraryModule.builtInstalledForApex
+ module.dexpreopter.configPath = module.implLibraryModule.dexpreopter.configPath
+ module.dexpreopter.outputProfilePathOnHost = module.implLibraryModule.dexpreopter.outputProfilePathOnHost
+
+ // Properties required for Library.AndroidMkEntries
+ module.logtagsSrcs = module.implLibraryModule.logtagsSrcs
+ module.dexpreopter.builtInstalled = module.implLibraryModule.dexpreopter.builtInstalled
+ module.jacocoReportClassesFile = module.implLibraryModule.jacocoReportClassesFile
+ module.dexer.proguardDictionary = module.implLibraryModule.dexer.proguardDictionary
+ module.dexer.proguardUsageZip = module.implLibraryModule.dexer.proguardUsageZip
+ module.linter.reports = module.implLibraryModule.linter.reports
+
+ if !module.Host() {
+ module.hostdexInstallFile = module.implLibraryModule.hostdexInstallFile
+ }
+
+ android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: module.implLibraryModule.uniqueSrcFiles.Strings()})
+ }
+
// Make the set of components exported by this module available for use elsewhere.
exportedComponentInfo := android.ExportedComponentsInfo{Components: android.SortedKeys(exportedComponents)}
android.SetProvider(ctx, android.ExportedComponentsInfoProvider, exportedComponentInfo)
@@ -1615,23 +1692,32 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
scopes[scope.name] = scopeInfo
scopeInfo["current_api"] = scope.snapshotRelativeCurrentApiTxtPath(baseModuleName)
scopeInfo["removed_api"] = scope.snapshotRelativeRemovedApiTxtPath(baseModuleName)
- if p := scopePaths.latestApiPath; p.Valid() {
- scopeInfo["latest_api"] = p.Path().String()
+ if p := scopePaths.latestApiPaths; len(p) > 0 {
+ // The last path in the list is the one that applies to this scope, the
+ // preceding ones, if any, are for the scope(s) that it extends.
+ scopeInfo["latest_api"] = p[len(p)-1].String()
}
- if p := scopePaths.latestRemovedApiPath; p.Valid() {
- scopeInfo["latest_removed_api"] = p.Path().String()
+ if p := scopePaths.latestRemovedApiPaths; len(p) > 0 {
+ // The last path in the list is the one that applies to this scope, the
+ // preceding ones, if any, are for the scope(s) that it extends.
+ scopeInfo["latest_removed_api"] = p[len(p)-1].String()
}
}
android.SetProvider(ctx, android.AdditionalSdkInfoProvider, android.AdditionalSdkInfo{additionalSdkInfo})
}
+func (module *SdkLibrary) BuiltInstalledForApex() []dexpreopterInstall {
+ return module.builtInstalledForApex
+}
+
func (module *SdkLibrary) AndroidMkEntries() []android.AndroidMkEntries {
if !module.requiresRuntimeImplementationLibrary() {
return nil
}
entriesList := module.Library.AndroidMkEntries()
+ entries := &entriesList[0]
+ entries.Required = append(entries.Required, module.implLibraryModuleName())
if module.sharedLibrary() {
- entries := &entriesList[0]
entries.Required = append(entries.Required, module.xmlPermissionsModuleName())
}
return entriesList
@@ -1672,12 +1758,16 @@ func latestPrebuiltApiModuleName(name string, apiScope *apiScope) string {
return PrebuiltApiModuleName(name, apiScope.name, "latest")
}
+func latestPrebuiltApiCombinedModuleName(name string, apiScope *apiScope) string {
+ return PrebuiltApiCombinedModuleName(name, apiScope.name, "latest")
+}
+
func (module *SdkLibrary) latestApiFilegroupName(apiScope *apiScope) string {
return ":" + module.latestApiModuleName(apiScope)
}
func (module *SdkLibrary) latestApiModuleName(apiScope *apiScope) string {
- return latestPrebuiltApiModuleName(module.distStem(), apiScope)
+ return latestPrebuiltApiCombinedModuleName(module.distStem(), apiScope)
}
func (module *SdkLibrary) latestRemovedApiFilegroupName(apiScope *apiScope) string {
@@ -1685,7 +1775,7 @@ func (module *SdkLibrary) latestRemovedApiFilegroupName(apiScope *apiScope) stri
}
func (module *SdkLibrary) latestRemovedApiModuleName(apiScope *apiScope) string {
- return latestPrebuiltApiModuleName(module.distStem()+"-removed", apiScope)
+ return latestPrebuiltApiCombinedModuleName(module.distStem()+"-removed", apiScope)
}
func (module *SdkLibrary) latestIncompatibilitiesFilegroupName(apiScope *apiScope) string {
@@ -1744,24 +1834,22 @@ func (module *SdkLibrary) createImplLibrary(mctx android.DefaultableHookContext)
props := struct {
Name *string
Visibility []string
- Instrument bool
Libs []string
Static_libs []string
Apex_available []string
+ Stem *string
}{
Name: proptools.StringPtr(module.implLibraryModuleName()),
Visibility: visibility,
- // Set the instrument property to ensure it is instrumented when instrumentation is required.
- Instrument: true,
- // Set the impl_only libs. Note that the module's "Libs" get appended as well, via the
- // addition of &module.properties below.
- Libs: module.sdkLibraryProperties.Impl_only_libs,
- // Set the impl_only static libs. Note that the module's "static_libs" get appended as well, via the
- // addition of &module.properties below.
- Static_libs: module.sdkLibraryProperties.Impl_only_static_libs,
+
+ Libs: append(module.properties.Libs, module.sdkLibraryProperties.Impl_only_libs...),
+
+ Static_libs: append(module.properties.Static_libs, module.sdkLibraryProperties.Impl_only_static_libs...),
// Pass the apex_available settings down so that the impl library can be statically
// embedded within a library that is added to an APEX. Needed for updatable-media.
Apex_available: module.ApexAvailable(),
+
+ Stem: proptools.StringPtr(module.Name()),
}
properties := []interface{}{
@@ -1771,6 +1859,7 @@ func (module *SdkLibrary) createImplLibrary(mctx android.DefaultableHookContext)
&module.dexProperties,
&module.dexpreoptProperties,
&module.linter.properties,
+ &module.overridableProperties,
&props,
module.sdkComponentPropertiesForChildLibrary(),
}
@@ -1993,20 +2082,25 @@ func (module *SdkLibrary) createStubsSourcesAndApi(mctx android.DefaultableHookC
if !Bool(module.sdkLibraryProperties.No_dist) {
// Dist the api txt and removed api txt artifacts for sdk builds.
distDir := proptools.StringPtr(path.Join(module.apiDistPath(apiScope), "api"))
+ stubsTypeTagPrefix := ""
+ if mctx.Config().ReleaseHiddenApiExportableStubs() {
+ stubsTypeTagPrefix = ".exportable"
+ }
for _, p := range []struct {
tag string
pattern string
}{
// "exportable" api files are copied to the dist directory instead of the
- // "everything" api files.
- {tag: ".exportable.api.txt", pattern: "%s.txt"},
- {tag: ".exportable.removed-api.txt", pattern: "%s-removed.txt"},
+ // "everything" api files when "RELEASE_HIDDEN_API_EXPORTABLE_STUBS" build flag
+ // is set. Otherwise, the "everything" api files are copied to the dist directory.
+ {tag: "%s.api.txt", pattern: "%s.txt"},
+ {tag: "%s.removed-api.txt", pattern: "%s-removed.txt"},
} {
props.Dists = append(props.Dists, android.Dist{
Targets: []string{"sdk", "win_sdk"},
Dir: distDir,
Dest: proptools.StringPtr(fmt.Sprintf(p.pattern, module.distStem())),
- Tag: proptools.StringPtr(p.tag),
+ Tag: proptools.StringPtr(fmt.Sprintf(p.tag, stubsTypeTagPrefix)),
})
}
}
@@ -2079,7 +2173,7 @@ func (module *SdkLibrary) createApiLibrary(mctx android.DefaultableHookContext,
mctx.CreateModule(ApiLibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}
-func (module *SdkLibrary) topLevelStubsLibraryProps(mctx android.DefaultableHookContext, apiScope *apiScope) libraryProperties {
+func (module *SdkLibrary) topLevelStubsLibraryProps(mctx android.DefaultableHookContext, apiScope *apiScope, doDist bool) libraryProperties {
props := libraryProperties{}
props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_library_visibility)
@@ -2095,13 +2189,22 @@ func (module *SdkLibrary) topLevelStubsLibraryProps(mctx android.DefaultableHook
}
props.Compile_dex = compileDex
+ if !Bool(module.sdkLibraryProperties.No_dist) && doDist {
+ 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")
+ }
+
return props
}
func (module *SdkLibrary) createTopLevelStubsLibrary(
mctx android.DefaultableHookContext, apiScope *apiScope, contributesToApiSurface bool) {
- props := module.topLevelStubsLibraryProps(mctx, apiScope)
+ // Dist the "everything" stubs when the RELEASE_HIDDEN_API_EXPORTABLE_STUBS build flag is false
+ doDist := !mctx.Config().ReleaseHiddenApiExportableStubs()
+ props := module.topLevelStubsLibraryProps(mctx, apiScope, doDist)
props.Name = proptools.StringPtr(module.stubsLibraryModuleName(apiScope))
// Add the stub compiling java_library/java_api_library as static lib based on build config
@@ -2117,18 +2220,11 @@ func (module *SdkLibrary) createTopLevelStubsLibrary(
func (module *SdkLibrary) createTopLevelExportableStubsLibrary(
mctx android.DefaultableHookContext, apiScope *apiScope) {
- props := module.topLevelStubsLibraryProps(mctx, apiScope)
+ // Dist the "exportable" stubs when the RELEASE_HIDDEN_API_EXPORTABLE_STUBS build flag is true
+ doDist := mctx.Config().ReleaseHiddenApiExportableStubs()
+ props := module.topLevelStubsLibraryProps(mctx, apiScope, doDist)
props.Name = proptools.StringPtr(module.exportableStubsLibraryModuleName(apiScope))
- // Dist the class jar artifact for sdk builds.
- // "exportable" stubs are copied to dist for sdk builds instead of the "everything" stubs.
- 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")
- }
-
staticLib := module.exportableSourceStubsLibraryModuleName(apiScope)
props.Static_libs = append(props.Static_libs, staticLib)
@@ -2145,6 +2241,9 @@ func (module *SdkLibrary) DepIsInSameApex(mctx android.BaseModuleContext, dep an
if depTag == xmlPermissionsFileTag {
return true
}
+ if dep.Name() == module.implLibraryModuleName() {
+ return true
+ }
return module.Library.DepIsInSameApex(mctx, dep)
}
@@ -2226,7 +2325,7 @@ func withinSameApexesAs(ctx android.BaseModuleContext, other android.Module) boo
return len(otherApexInfo.InApexVariants) > 0 && reflect.DeepEqual(apexInfo.InApexVariants, otherApexInfo.InApexVariants)
}
-func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec, headerJars bool) android.Paths {
+func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths {
// If the client doesn't set sdk_version, but if this library prefers stubs over
// the impl library, let's provide the widest API surface possible. To do so,
// force override sdk_version to module_current so that the closest possible API
@@ -2243,11 +2342,7 @@ func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion andr
// * No sdk_version specified on the referencing module.
// * The referencing module is in the same apex as this.
if sdkVersion.Kind == android.SdkPrivate || withinSameApexesAs(ctx, module) {
- if headerJars {
- return module.HeaderJars()
- } else {
- return module.ImplementationJars()
- }
+ return module.implLibraryHeaderJars
}
}
@@ -2256,12 +2351,7 @@ func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion andr
// to satisfy SdkLibraryDependency interface
func (module *SdkLibrary) SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths {
- return module.sdkJars(ctx, sdkVersion, true /*headerJars*/)
-}
-
-// to satisfy SdkLibraryDependency interface
-func (module *SdkLibrary) SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths {
- return module.sdkJars(ctx, sdkVersion, false /*headerJars*/)
+ return module.sdkJars(ctx, sdkVersion)
}
var javaSdkLibrariesKey = android.NewOnceKey("javaSdkLibraries")
@@ -2281,7 +2371,7 @@ func (module *SdkLibrary) getApiDir() string {
// once for public API level and once for system API level
func (module *SdkLibrary) CreateInternalModules(mctx android.DefaultableHookContext) {
// If the module has been disabled then don't create any child modules.
- if !module.Enabled() {
+ if !module.Enabled(mctx) {
return
}
@@ -2579,10 +2669,6 @@ type SdkLibraryImport struct {
commonToSdkLibraryAndImport
- // The reference to the implementation library created by the source module.
- // Is nil if the source module does not exist.
- implLibraryModule *Library
-
// The reference to the xml permissions module created by the source module.
// Is nil if the source module does not exist.
xmlPermissionsFileModule *sdkLibraryXml
@@ -2971,12 +3057,6 @@ func (module *SdkLibraryImport) SdkHeaderJars(ctx android.BaseModuleContext, sdk
return module.sdkJars(ctx, sdkVersion, true)
}
-// to satisfy SdkLibraryDependency interface
-func (module *SdkLibraryImport) SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths {
- // This module is just a wrapper for the stubs.
- return module.sdkJars(ctx, sdkVersion, false)
-}
-
// to satisfy UsesLibraryDependency interface
func (module *SdkLibraryImport) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
// The dex implementation jar extracted from the .apex file should be used in preference to the
@@ -3163,10 +3243,12 @@ func (module *sdkLibraryXml) SubDir() string {
}
// from android.PrebuiltEtcModule
-func (module *sdkLibraryXml) OutputFile() android.OutputPath {
- return module.outputFilePath
+func (module *sdkLibraryXml) OutputFiles(tag string) (android.Paths, error) {
+ return android.OutputPaths{module.outputFilePath}.Paths(), nil
}
+var _ etc.PrebuiltEtcModule = (*sdkLibraryXml)(nil)
+
// from android.ApexModule
func (module *sdkLibraryXml) AvailableFor(what string) bool {
return true
@@ -3236,14 +3318,14 @@ func formattedOptionalAttribute(attrName string, value *string) string {
if value == nil {
return ""
}
- return fmt.Sprintf(` %s=\"%s\"\n`, attrName, *value)
+ return fmt.Sprintf(" %s=\"%s\"\n", attrName, *value)
}
func formattedDependenciesAttribute(dependencies []string) string {
if dependencies == nil {
return ""
}
- return fmt.Sprintf(` dependency=\"%s\"\n`, strings.Join(dependencies, ":"))
+ return fmt.Sprintf(" dependency=\"%s\"\n", strings.Join(dependencies, ":"))
}
func (module *sdkLibraryXml) permissionsContents(ctx android.ModuleContext) string {
@@ -3260,28 +3342,28 @@ func (module *sdkLibraryXml) permissionsContents(ctx android.ModuleContext) stri
// similarly, min_device_sdk is only understood from T. So if a library is using that, we need to use the apex-library to make sure this library is not loaded before T
var libraryTag string
if module.properties.Min_device_sdk != nil {
- libraryTag = ` <apex-library\n`
+ libraryTag = " <apex-library\n"
} else {
- libraryTag = ` <library\n`
+ libraryTag = " <library\n"
}
return strings.Join([]string{
- `<?xml version=\"1.0\" encoding=\"utf-8\"?>\n`,
- `<!-- Copyright (C) 2018 The Android Open Source Project\n`,
- `\n`,
- ` Licensed under the Apache License, Version 2.0 (the \"License\");\n`,
- ` you may not use this file except in compliance with the License.\n`,
- ` You may obtain a copy of the License at\n`,
- `\n`,
- ` http://www.apache.org/licenses/LICENSE-2.0\n`,
- `\n`,
- ` Unless required by applicable law or agreed to in writing, software\n`,
- ` distributed under the License is distributed on an \"AS IS\" BASIS,\n`,
- ` WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n`,
- ` See the License for the specific language governing permissions and\n`,
- ` limitations under the License.\n`,
- `-->\n`,
- `<permissions>\n`,
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n",
+ "<!-- Copyright (C) 2018 The Android Open Source Project\n",
+ "\n",
+ " Licensed under the Apache License, Version 2.0 (the \"License\");\n",
+ " you may not use this file except in compliance with the License.\n",
+ " You may obtain a copy of the License at\n",
+ "\n",
+ " http://www.apache.org/licenses/LICENSE-2.0\n",
+ "\n",
+ " Unless required by applicable law or agreed to in writing, software\n",
+ " distributed under the License is distributed on an \"AS IS\" BASIS,\n",
+ " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
+ " See the License for the specific language governing permissions and\n",
+ " limitations under the License.\n",
+ "-->\n",
+ "<permissions>\n",
libraryTag,
libNameAttr,
filePathAttr,
@@ -3290,8 +3372,9 @@ func (module *sdkLibraryXml) permissionsContents(ctx android.ModuleContext) stri
minSdkAttr,
maxSdkAttr,
dependenciesAttr,
- ` />\n`,
- `</permissions>\n`}, "")
+ " />\n",
+ "</permissions>\n",
+ }, "")
}
func (module *sdkLibraryXml) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -3303,14 +3386,10 @@ func (module *sdkLibraryXml) GenerateAndroidBuildActions(ctx android.ModuleConte
xmlContent := module.permissionsContents(ctx)
module.outputFilePath = android.PathForModuleOut(ctx, libName+".xml").OutputPath
- rule := android.NewRuleBuilder(pctx, ctx)
- rule.Command().
- Text("/bin/bash -c \"echo -e '" + xmlContent + "'\" > ").
- Output(module.outputFilePath)
-
- rule.Build("java_sdk_xml", "Permission XML")
+ android.WriteFileRuleVerbatim(ctx, module.outputFilePath, xmlContent)
module.installDirPath = android.PathForModuleInstall(ctx, "etc", module.SubDir())
+ ctx.PackageFile(module.installDirPath, libName+".xml", module.outputFilePath)
}
func (module *sdkLibraryXml) AndroidMkEntries() []android.AndroidMkEntries {
@@ -3554,7 +3633,8 @@ func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMembe
s.Min_device_sdk = sdk.commonSdkLibraryProperties.Min_device_sdk
s.Max_device_sdk = sdk.commonSdkLibraryProperties.Max_device_sdk
- if sdk.dexpreopter.dexpreoptProperties.Dex_preopt_result.Profile_guided {
+ implLibrary := sdk.getImplLibraryModule()
+ if implLibrary != nil && implLibrary.dexpreopter.dexpreoptProperties.Dex_preopt_result.Profile_guided {
s.DexPreoptProfileGuided = proptools.BoolPtr(true)
}
}
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index 93ef40872..d240e701b 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -139,10 +139,10 @@ func TestJavaSdkLibrary(t *testing.T) {
exportedComponentsInfo, _ := android.SingletonModuleProvider(result, foo.Module(), android.ExportedComponentsInfoProvider)
expectedFooExportedComponents := []string{
- "foo-removed.api.public.latest",
- "foo-removed.api.system.latest",
- "foo.api.public.latest",
- "foo.api.system.latest",
+ "foo-removed.api.combined.public.latest",
+ "foo-removed.api.combined.system.latest",
+ "foo.api.combined.public.latest",
+ "foo.api.combined.system.latest",
"foo.stubs",
"foo.stubs.exportable",
"foo.stubs.exportable.system",
@@ -186,13 +186,13 @@ func TestJavaSdkLibrary(t *testing.T) {
// test if quuz have created the api_contribution module
result.ModuleForTests(apiScopePublic.stubsSourceModuleName("quuz")+".api.contribution", "")
- fooDexJar := result.ModuleForTests("foo", "android_common").Rule("d8")
- // tests if kotlinc generated files are NOT excluded from output of foo.
- android.AssertStringDoesNotContain(t, "foo dex", fooDexJar.BuildParams.Args["mergeZipsFlags"], "-stripFile META-INF/*.kotlin_module")
+ fooImplDexJar := result.ModuleForTests("foo.impl", "android_common").Rule("d8")
+ // tests if kotlinc generated files are NOT excluded from output of foo.impl.
+ android.AssertStringDoesNotContain(t, "foo.impl dex", fooImplDexJar.BuildParams.Args["mergeZipsFlags"], "-stripFile META-INF/*.kotlin_module")
- barDexJar := result.ModuleForTests("bar", "android_common").Rule("d8")
- // tests if kotlinc generated files are excluded from output of bar.
- android.AssertStringDoesContain(t, "bar dex", barDexJar.BuildParams.Args["mergeZipsFlags"], "-stripFile META-INF/*.kotlin_module")
+ barImplDexJar := result.ModuleForTests("bar.impl", "android_common").Rule("d8")
+ // tests if kotlinc generated files are excluded from output of bar.impl.
+ android.AssertStringDoesContain(t, "bar.impl dex", barImplDexJar.BuildParams.Args["mergeZipsFlags"], "-stripFile META-INF/*.kotlin_module")
}
func TestJavaSdkLibrary_UpdatableLibrary(t *testing.T) {
@@ -227,19 +227,21 @@ func TestJavaSdkLibrary_UpdatableLibrary(t *testing.T) {
`)
// test that updatability attributes are passed on correctly
- fooUpdatable := result.ModuleForTests("fooUpdatable.xml", "android_common").Rule("java_sdk_xml")
- android.AssertStringDoesContain(t, "fooUpdatable.xml java_sdk_xml command", fooUpdatable.RuleParams.Command, `on-bootclasspath-since=\"U\"`)
- android.AssertStringDoesContain(t, "fooUpdatable.xml java_sdk_xml command", fooUpdatable.RuleParams.Command, `on-bootclasspath-before=\"V\"`)
- android.AssertStringDoesContain(t, "fooUpdatable.xml java_sdk_xml command", fooUpdatable.RuleParams.Command, `min-device-sdk=\"W\"`)
- android.AssertStringDoesContain(t, "fooUpdatable.xml java_sdk_xml command", fooUpdatable.RuleParams.Command, `max-device-sdk=\"X\"`)
+ fooUpdatable := result.ModuleForTests("fooUpdatable.xml", "android_common").Output("fooUpdatable.xml")
+ fooUpdatableContents := android.ContentFromFileRuleForTests(t, result.TestContext, fooUpdatable)
+ android.AssertStringDoesContain(t, "fooUpdatable.xml contents", fooUpdatableContents, `on-bootclasspath-since="U"`)
+ android.AssertStringDoesContain(t, "fooUpdatable.xml contents", fooUpdatableContents, `on-bootclasspath-before="V"`)
+ android.AssertStringDoesContain(t, "fooUpdatable.xml contents", fooUpdatableContents, `min-device-sdk="W"`)
+ android.AssertStringDoesContain(t, "fooUpdatable.xml contents", fooUpdatableContents, `max-device-sdk="X"`)
// double check that updatability attributes are not written if they don't exist in the bp file
// the permissions file for the foo library defined above
- fooPermissions := result.ModuleForTests("foo.xml", "android_common").Rule("java_sdk_xml")
- android.AssertStringDoesNotContain(t, "foo.xml java_sdk_xml command", fooPermissions.RuleParams.Command, `on-bootclasspath-since`)
- android.AssertStringDoesNotContain(t, "foo.xml java_sdk_xml command", fooPermissions.RuleParams.Command, `on-bootclasspath-before`)
- android.AssertStringDoesNotContain(t, "foo.xml java_sdk_xml command", fooPermissions.RuleParams.Command, `min-device-sdk`)
- android.AssertStringDoesNotContain(t, "foo.xml java_sdk_xml command", fooPermissions.RuleParams.Command, `max-device-sdk`)
+ fooPermissions := result.ModuleForTests("foo.xml", "android_common").Output("foo.xml")
+ fooPermissionsContents := android.ContentFromFileRuleForTests(t, result.TestContext, fooPermissions)
+ android.AssertStringDoesNotContain(t, "foo.xml contents", fooPermissionsContents, `on-bootclasspath-since`)
+ android.AssertStringDoesNotContain(t, "foo.xml contents", fooPermissionsContents, `on-bootclasspath-before`)
+ android.AssertStringDoesNotContain(t, "foo.xml contents", fooPermissionsContents, `min-device-sdk`)
+ android.AssertStringDoesNotContain(t, "foo.xml contents", fooPermissionsContents, `max-device-sdk`)
}
func TestJavaSdkLibrary_UpdatableLibrary_Validation_ValidVersion(t *testing.T) {
@@ -370,9 +372,10 @@ func TestJavaSdkLibrary_UpdatableLibrary_usesNewTag(t *testing.T) {
}
`)
// test that updatability attributes are passed on correctly
- fooUpdatable := result.ModuleForTests("foo.xml", "android_common").Rule("java_sdk_xml")
- android.AssertStringDoesContain(t, "foo.xml java_sdk_xml command", fooUpdatable.RuleParams.Command, `<apex-library`)
- android.AssertStringDoesNotContain(t, "foo.xml java_sdk_xml command", fooUpdatable.RuleParams.Command, `<library`)
+ fooUpdatable := result.ModuleForTests("foo.xml", "android_common").Output("foo.xml")
+ fooUpdatableContents := android.ContentFromFileRuleForTests(t, result.TestContext, fooUpdatable)
+ android.AssertStringDoesContain(t, "foo.xml contents", fooUpdatableContents, `<apex-library`)
+ android.AssertStringDoesNotContain(t, "foo.xml contents", fooUpdatableContents, `<library`)
}
func TestJavaSdkLibrary_StubOrImplOnlyLibs(t *testing.T) {
@@ -556,8 +559,8 @@ func TestJavaSdkLibrary_Deps(t *testing.T) {
CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{
`dex2oatd`,
- `sdklib-removed.api.public.latest`,
- `sdklib.api.public.latest`,
+ `sdklib-removed.api.combined.public.latest`,
+ `sdklib.api.combined.public.latest`,
`sdklib.impl`,
`sdklib.stubs`,
`sdklib.stubs.exportable`,
@@ -960,8 +963,8 @@ func TestJavaSdkLibraryImport_WithSource(t *testing.T) {
CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{
`dex2oatd`,
`prebuilt_sdklib`,
- `sdklib-removed.api.public.latest`,
- `sdklib.api.public.latest`,
+ `sdklib-removed.api.combined.public.latest`,
+ `sdklib.api.combined.public.latest`,
`sdklib.impl`,
`sdklib.stubs`,
`sdklib.stubs.exportable`,
@@ -1039,8 +1042,8 @@ func testJavaSdkLibraryImport_Preferred(t *testing.T, prefer string, preparer an
CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{
`prebuilt_sdklib`,
- `sdklib-removed.api.public.latest`,
- `sdklib.api.public.latest`,
+ `sdklib-removed.api.combined.public.latest`,
+ `sdklib.api.combined.public.latest`,
`sdklib.impl`,
`sdklib.stubs`,
`sdklib.stubs.exportable`,
@@ -1082,18 +1085,6 @@ func TestJavaSdkLibraryImport_Preferred(t *testing.T) {
t.Run("prefer", func(t *testing.T) {
testJavaSdkLibraryImport_Preferred(t, "prefer: true,", android.NullFixturePreparer)
})
-
- t.Run("use_source_config_var", func(t *testing.T) {
- testJavaSdkLibraryImport_Preferred(t,
- "use_source_config_var: {config_namespace: \"acme\", var_name: \"use_source\"},",
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.VendorVars = map[string]map[string]string{
- "acme": {
- "use_source": "false",
- },
- }
- }))
- })
}
// If a module is listed in `mainline_module_contributions, it should be used
@@ -1239,7 +1230,6 @@ func TestJavaSdkLibraryEnforce(t *testing.T) {
libraryType string
fromPartition string
toPartition string
- enforceVendorInterface bool
enforceProductInterface bool
enforceJavaSdkLibraryCheck bool
allowList []string
@@ -1274,9 +1264,6 @@ func TestJavaSdkLibraryEnforce(t *testing.T) {
android.FixtureWithRootAndroidBp(bpFile),
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.EnforceProductPartitionInterface = proptools.BoolPtr(info.enforceProductInterface)
- if info.enforceVendorInterface {
- variables.DeviceVndkVersion = proptools.StringPtr("current")
- }
variables.EnforceInterPartitionJavaSdkLibrary = proptools.BoolPtr(info.enforceJavaSdkLibraryCheck)
variables.InterPartitionJavaLibraryAllowList = info.allowList
}),
@@ -1304,7 +1291,6 @@ func TestJavaSdkLibraryEnforce(t *testing.T) {
libraryType: "java_library",
fromPartition: "product",
toPartition: "system",
- enforceVendorInterface: true,
enforceProductInterface: true,
enforceJavaSdkLibraryCheck: false,
}, "")
@@ -1313,7 +1299,6 @@ func TestJavaSdkLibraryEnforce(t *testing.T) {
libraryType: "java_library",
fromPartition: "product",
toPartition: "system",
- enforceVendorInterface: true,
enforceProductInterface: false,
enforceJavaSdkLibraryCheck: true,
}, "")
@@ -1322,7 +1307,6 @@ func TestJavaSdkLibraryEnforce(t *testing.T) {
libraryType: "java_library",
fromPartition: "product",
toPartition: "system",
- enforceVendorInterface: true,
enforceProductInterface: true,
enforceJavaSdkLibraryCheck: true,
}, errorMessage)
@@ -1331,7 +1315,6 @@ func TestJavaSdkLibraryEnforce(t *testing.T) {
libraryType: "java_library",
fromPartition: "vendor",
toPartition: "system",
- enforceVendorInterface: true,
enforceProductInterface: true,
enforceJavaSdkLibraryCheck: true,
}, errorMessage)
@@ -1340,7 +1323,6 @@ func TestJavaSdkLibraryEnforce(t *testing.T) {
libraryType: "java_library",
fromPartition: "vendor",
toPartition: "system",
- enforceVendorInterface: true,
enforceProductInterface: true,
enforceJavaSdkLibraryCheck: true,
allowList: []string{"bar"},
@@ -1350,7 +1332,6 @@ func TestJavaSdkLibraryEnforce(t *testing.T) {
libraryType: "java_library",
fromPartition: "vendor",
toPartition: "product",
- enforceVendorInterface: true,
enforceProductInterface: true,
enforceJavaSdkLibraryCheck: true,
}, errorMessage)
@@ -1359,7 +1340,6 @@ func TestJavaSdkLibraryEnforce(t *testing.T) {
libraryType: "java_sdk_library",
fromPartition: "product",
toPartition: "system",
- enforceVendorInterface: true,
enforceProductInterface: true,
enforceJavaSdkLibraryCheck: true,
}, "")
@@ -1368,7 +1348,6 @@ func TestJavaSdkLibraryEnforce(t *testing.T) {
libraryType: "java_sdk_library",
fromPartition: "vendor",
toPartition: "system",
- enforceVendorInterface: true,
enforceProductInterface: true,
enforceJavaSdkLibraryCheck: true,
}, "")
@@ -1377,7 +1356,6 @@ func TestJavaSdkLibraryEnforce(t *testing.T) {
libraryType: "java_sdk_library",
fromPartition: "vendor",
toPartition: "product",
- enforceVendorInterface: true,
enforceProductInterface: true,
enforceJavaSdkLibraryCheck: true,
}, "")
@@ -1393,6 +1371,11 @@ func TestJavaSdkLibraryDist(t *testing.T) {
"sdklib_group_foo",
"sdklib_owner_foo",
"foo"),
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.BuildFlags = map[string]string{
+ "RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true",
+ }
+ }),
).RunTestWithBp(t, `
java_sdk_library {
name: "sdklib_no_group",
@@ -1474,11 +1457,11 @@ func TestSdkLibrary_CheckMinSdkVersion(t *testing.T) {
preparer.RunTestWithBp(t, `
java_sdk_library {
name: "sdklib",
- srcs: ["a.java"],
- static_libs: ["util"],
- min_sdk_version: "30",
+ srcs: ["a.java"],
+ static_libs: ["util"],
+ min_sdk_version: "30",
unsafe_ignore_missing_latest_api: true,
- }
+ }
java_library {
name: "util",
@@ -1715,9 +1698,9 @@ func TestSdkLibraryDependency(t *testing.T) {
}
`)
- barPermissions := result.ModuleForTests("bar.xml", "android_common").Rule("java_sdk_xml")
-
- android.AssertStringDoesContain(t, "bar.xml java_sdk_xml command", barPermissions.RuleParams.Command, `dependency=\"foo\"`)
+ barPermissions := result.ModuleForTests("bar.xml", "android_common").Output("bar.xml")
+ barContents := android.ContentFromFileRuleForTests(t, result.TestContext, barPermissions)
+ android.AssertStringDoesContain(t, "bar.xml java_sdk_xml command", barContents, `dependency="foo"`)
}
func TestSdkLibraryExportableStubsLibrary(t *testing.T) {
@@ -1732,6 +1715,7 @@ func TestSdkLibraryExportableStubsLibrary(t *testing.T) {
aconfig_declarations {
name: "bar",
package: "com.example.package",
+ container: "com.android.foo",
srcs: [
"bar.aconfig",
],
diff --git a/java/system_modules.go b/java/system_modules.go
index 92e31cdf9..8e2d5d8ff 100644
--- a/java/system_modules.go
+++ b/java/system_modules.go
@@ -64,6 +64,7 @@ var (
// useful on Android, and (b) it causes errors with later versions of jlink
// when the jdk.internal.module is absent from java.base (as it is here).
` --disable-plugin system-modules && ` +
+ `rm -rf ${workDir} && ` +
`cp ${config.JrtFsJar} ${outDir}/lib/`,
CommandDeps: []string{
"${moduleInfoJavaPath}",
diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go
index 59c546634..bad2cf1cf 100644
--- a/java/systemserver_classpath_fragment.go
+++ b/java/systemserver_classpath_fragment.go
@@ -69,6 +69,7 @@ func (p *platformSystemServerClasspathModule) GenerateAndroidBuildActions(ctx an
configuredJars = configuredJars.AppendList(&standaloneConfiguredJars)
classpathJars = append(classpathJars, standaloneClasspathJars...)
p.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, configuredJars, classpathJars)
+ p.classpathFragmentBase().installClasspathProto(ctx)
}
func (p *platformSystemServerClasspathModule) configuredJars(ctx android.ModuleContext) android.ConfiguredJarList {
@@ -189,7 +190,7 @@ func (b systemServerClasspathFragmentContentDependencyTag) SdkMemberType(child a
return javaSdkLibrarySdkMemberType
}
- return javaSystemserverLibsSdkMemberType
+ return JavaSystemserverLibsSdkMemberType
}
func (b systemServerClasspathFragmentContentDependencyTag) ExportMember() bool {
diff --git a/java/testing.go b/java/testing.go
index 631d51662..5ae326d93 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -711,7 +711,7 @@ var PrepareForTestWithFakeApexMutator = android.GroupFixturePreparers(
func registerFakeApexMutator(ctx android.RegistrationContext) {
ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.BottomUp("apex", fakeApexMutator).Parallel()
+ ctx.Transition("apex", &fakeApexMutator{})
})
}
@@ -726,16 +726,30 @@ var _ apexModuleBase = (*SdkLibrary)(nil)
// `apex_available`. It helps us avoid a dependency on the real mutator defined in "soong-apex",
// which will cause a cyclic dependency, and it provides an easy way to create an APEX variant for
// testing without dealing with all the complexities in the real mutator.
-func fakeApexMutator(mctx android.BottomUpMutatorContext) {
- switch mctx.Module().(type) {
+type fakeApexMutator struct{}
+
+func (f *fakeApexMutator) Split(ctx android.BaseModuleContext) []string {
+ switch ctx.Module().(type) {
case *Library, *SdkLibrary:
- if len(mctx.Module().(apexModuleBase).ApexAvailable()) > 0 {
- modules := mctx.CreateVariations("", "apex1000")
- apexInfo := android.ApexInfo{
- ApexVariationName: "apex1000",
- }
- mctx.SetVariationProvider(modules[1], android.ApexInfoProvider, apexInfo)
+ return []string{"", "apex1000"}
+ }
+ return []string{""}
+}
+
+func (f *fakeApexMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
+ return sourceVariation
+}
+
+func (f *fakeApexMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
+ return incomingVariation
+}
+
+func (f *fakeApexMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
+ if variation != "" {
+ apexInfo := android.ApexInfo{
+ ApexVariationName: "apex1000",
}
+ android.SetProvider(ctx, android.ApexInfoProvider, apexInfo)
}
}