summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/aar.go11
-rwxr-xr-xjava/app.go7
-rw-r--r--java/app_builder.go2
-rw-r--r--java/app_test.go66
-rw-r--r--java/builder.go2
-rw-r--r--java/dexpreopt_bootjars.go65
-rw-r--r--java/hiddenapi_singleton.go7
-rw-r--r--java/java.go41
8 files changed, 157 insertions, 44 deletions
diff --git a/java/aar.go b/java/aar.go
index 1940d7f7b..3b6b34e27 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -407,6 +407,7 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext, classLoaderConte
ctx.VisitDirectDeps(func(module android.Module) {
depName := ctx.OtherModuleName(module)
+ depTag := ctx.OtherModuleDependencyTag(module)
var exportPackage android.Path
aarDep, _ := module.(AndroidLibraryDependency)
@@ -414,7 +415,7 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext, classLoaderConte
exportPackage = aarDep.ExportPackage()
}
- switch ctx.OtherModuleDependencyTag(module) {
+ switch depTag {
case instrumentationForTag:
// Nothing, instrumentationForTag is treated as libTag for javac but not for aapt2.
case libTag:
@@ -439,7 +440,6 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext, classLoaderConte
transitiveStaticLibs = append(transitiveStaticLibs, aarDep.ExportedStaticPackages()...)
transitiveStaticLibs = append(transitiveStaticLibs, exportPackage)
transitiveStaticLibManifests = append(transitiveStaticLibManifests, aarDep.ExportedManifests()...)
- classLoaderContexts.AddContextMap(aarDep.ClassLoaderContexts(), depName)
if aarDep.ExportedAssets().Valid() {
assets = append(assets, aarDep.ExportedAssets().Path())
}
@@ -458,11 +458,8 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext, classLoaderConte
}
}
- // Add nested dependencies after processing the direct dependency: if it is a <uses-library>,
- // nested context is added as its subcontext, and should not be re-added at the top-level.
- if dep, ok := module.(Dependency); ok {
- classLoaderContexts.AddContextMap(dep.ClassLoaderContexts(), depName)
- }
+ // Merge dep's CLC after processing the dep itself (which may add its own <uses-library>).
+ maybeAddCLCFromDep(module, depTag, depName, classLoaderContexts)
})
deps = append(deps, sharedLibs...)
diff --git a/java/app.go b/java/app.go
index 4bf9d33ea..e6d9550ec 100755
--- a/java/app.go
+++ b/java/app.go
@@ -1400,6 +1400,13 @@ func (a *AndroidAppImport) processVariants(ctx android.LoadHookContext) {
archProps := reflect.ValueOf(a.archVariants).Elem().FieldByName("Arch")
archType := ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType
MergePropertiesFromVariant(ctx, &a.properties, archProps, archType.Name)
+
+ if String(a.properties.Apk) == "" {
+ // Disable this module since the apk property is still empty after processing all matching
+ // variants. This likely means there is no matching variant, and the default variant doesn't
+ // have an apk property value either.
+ a.Disable()
+ }
}
func MergePropertiesFromVariant(ctx android.EarlyModuleContext,
diff --git a/java/app_builder.go b/java/app_builder.go
index 69e462c3d..b53c15ab4 100644
--- a/java/app_builder.go
+++ b/java/app_builder.go
@@ -32,7 +32,7 @@ import (
var (
Signapk, SignapkRE = remoteexec.StaticRules(pctx, "signapk",
blueprint.RuleParams{
- Command: `$reTemplate${config.JavaCmd} ${config.JavaVmFlags} -Djava.library.path=$$(dirname ${config.SignapkJniLibrary}) ` +
+ Command: `rm -f $out && $reTemplate${config.JavaCmd} ${config.JavaVmFlags} -Djava.library.path=$$(dirname ${config.SignapkJniLibrary}) ` +
`-jar ${config.SignapkCmd} $flags $certificates $in $out`,
CommandDeps: []string{"${config.SignapkCmd}", "${config.SignapkJniLibrary}"},
},
diff --git a/java/app_test.go b/java/app_test.go
index 6efb0dcb3..e13c6b9f0 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -2524,6 +2524,24 @@ func TestAndroidAppImport_ArchVariants(t *testing.T) {
`,
expected: "prebuilts/apk/app.apk",
},
+ {
+ name: "no matching arch without default",
+ bp: `
+ android_app_import {
+ name: "foo",
+ arch: {
+ arm: {
+ apk: "prebuilts/apk/app_arm.apk",
+ },
+ },
+ presigned: true,
+ dex_preopt: {
+ enabled: true,
+ },
+ }
+ `,
+ expected: "",
+ },
}
jniRuleRe := regexp.MustCompile("^if \\(zipinfo (\\S+)")
@@ -2531,6 +2549,12 @@ func TestAndroidAppImport_ArchVariants(t *testing.T) {
ctx, _ := testJava(t, test.bp)
variant := ctx.ModuleForTests("foo", "android_common")
+ if test.expected == "" {
+ if variant.Module().Enabled() {
+ t.Error("module should have been disabled, but wasn't")
+ }
+ continue
+ }
jniRuleCommand := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
matches := jniRuleRe.FindStringSubmatch(jniRuleCommand)
if len(matches) != 2 {
@@ -2542,6 +2566,34 @@ func TestAndroidAppImport_ArchVariants(t *testing.T) {
}
}
+func TestAndroidAppImport_overridesDisabledAndroidApp(t *testing.T) {
+ ctx, _ := testJava(t, `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ enabled: false,
+ }
+
+ android_app_import {
+ name: "foo",
+ apk: "prebuilts/apk/app.apk",
+ certificate: "platform",
+ prefer: true,
+ }
+ `)
+
+ variant := ctx.ModuleForTests("prebuilt_foo", "android_common")
+ a := variant.Module().(*AndroidAppImport)
+ // The prebuilt module should still be enabled and active even if the source-based counterpart
+ // is disabled.
+ if !a.prebuilt.UsePrebuilt() {
+ t.Errorf("prebuilt foo module is not active")
+ }
+ if !a.Enabled() {
+ t.Errorf("prebuilt foo module is disabled")
+ }
+}
+
func TestAndroidTestImport(t *testing.T) {
ctx, config := testJava(t, `
android_test_import {
@@ -2730,6 +2782,13 @@ func TestUsesLibraries(t *testing.T) {
}
java_sdk_library {
+ name: "fred",
+ srcs: ["a.java"],
+ api_packages: ["fred"],
+ sdk_version: "current",
+ }
+
+ java_sdk_library {
name: "bar",
srcs: ["a.java"],
api_packages: ["bar"],
@@ -2753,7 +2812,12 @@ func TestUsesLibraries(t *testing.T) {
name: "app",
srcs: ["a.java"],
libs: ["qux", "quuz.stubs"],
- static_libs: ["static-runtime-helper"],
+ static_libs: [
+ "static-runtime-helper",
+ // statically linked component libraries should not pull their SDK libraries,
+ // so "fred" should not be added to class loader context
+ "fred.stubs",
+ ],
uses_libs: ["foo"],
sdk_version: "current",
optional_uses_libs: [
diff --git a/java/builder.go b/java/builder.go
index cd3524542..995160d0e 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -42,7 +42,7 @@ var (
// TODO(b/143658984): goma can't handle the --system argument to javac.
javac, javacRE = remoteexec.MultiCommandStaticRules(pctx, "javac",
blueprint.RuleParams{
- Command: `rm -rf "$outDir" "$annoDir" "$srcJarDir" && mkdir -p "$outDir" "$annoDir" "$srcJarDir" && ` +
+ Command: `rm -rf "$outDir" "$annoDir" "$srcJarDir" "$out" && mkdir -p "$outDir" "$annoDir" "$srcJarDir" && ` +
`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
`(if [ -s $srcJarDir/list ] || [ -s $out.rsp ] ; then ` +
`${config.SoongJavacWrapper} $javaTemplate${config.JavacCmd} ` +
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index f16ddf1df..062005b5b 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -418,43 +418,53 @@ func (d *dexpreoptBootJars) GenerateBuildActions(ctx android.SingletonContext) {
dumpOatRules(ctx, d.defaultBootImage)
}
-func isHostdex(module android.Module) bool {
- if lib, ok := module.(*Library); ok {
- return Bool(lib.deviceProperties.Hostdex)
- }
- return false
-}
-
// Inspect this module to see if it contains a bootclasspath dex jar.
// Note that the same jar may occur in multiple modules.
// This logic is tested in the apex package to avoid import cycle apex <-> java.
func getBootImageJar(ctx android.SingletonContext, image *bootImageConfig, module android.Module) (int, android.Path) {
- // All apex Java libraries have non-installable platform variants, skip them.
- if module.IsSkipInstall() {
+ // Ignore any module that is not listed in the boot image configuration.
+ name := ctx.ModuleName(module)
+ index := image.modules.IndexOfJar(name)
+ if index == -1 {
return -1, nil
}
+ // It is an error if a module configured in the boot image does not support
+ // accessing the dex jar. This is safe because every module that has the same
+ // name has to have the same module type.
jar, hasJar := module.(interface{ DexJarBuildPath() android.Path })
if !hasJar {
+ ctx.Errorf("module %q configured in boot image %q does not support accessing dex jar", module, image.name)
return -1, nil
}
- name := ctx.ModuleName(module)
- index := image.modules.IndexOfJar(name)
- if index == -1 {
+ // It is also an error if the module is not an ApexModule.
+ if _, ok := module.(android.ApexModule); !ok {
+ ctx.Errorf("module %q configured in boot image %q does not support being added to an apex", module, image.name)
return -1, nil
}
- // Check that this module satisfies constraints for a particular boot image.
- _, isApexModule := module.(android.ApexModule)
apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
- fromUpdatableApex := isApexModule && apexInfo.Updatable
- if image.name == artBootImageName {
- if isApexModule && len(apexInfo.InApexes) > 0 && allHavePrefix(apexInfo.InApexes, "com.android.art") {
- // ok: found the jar in the ART apex
- } else if isApexModule && apexInfo.IsForPlatform() && isHostdex(module) {
- // exception (skip and continue): special "hostdex" platform variant
+
+ // Now match the apex part of the boot image configuration.
+ requiredApex := image.modules.Apex(index)
+ if requiredApex == "platform" {
+ if len(apexInfo.InApexes) != 0 {
+ // A platform variant is required but this is for an apex so ignore it.
return -1, nil
+ }
+ } else if !android.InList(requiredApex, apexInfo.InApexes) {
+ // An apex variant for a specific apex is required but this is the wrong apex.
+ return -1, nil
+ }
+
+ // Check that this module satisfies any boot image specific constraints.
+ fromUpdatableApex := apexInfo.Updatable
+
+ switch image.name {
+ case artBootImageName:
+ if len(apexInfo.InApexes) > 0 && allHavePrefix(apexInfo.InApexes, "com.android.art") {
+ // ok: found the jar in the ART apex
} else if name == "jacocoagent" && ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
// exception (skip and continue): Jacoco platform variant for a coverage build
return -1, nil
@@ -465,14 +475,15 @@ func getBootImageJar(ctx android.SingletonContext, image *bootImageConfig, modul
// error: this jar is part of the platform or a non-updatable apex
ctx.Errorf("module %q is not allowed in the ART boot image", name)
}
- } else if image.name == frameworkBootImageName {
+
+ case frameworkBootImageName:
if !fromUpdatableApex {
// ok: this jar is part of the platform or a non-updatable apex
} else {
// error: this jar is part of an updatable apex
ctx.Errorf("module %q from updatable apexes %q is not allowed in the framework boot image", name, apexInfo.InApexes)
}
- } else {
+ default:
panic("unknown boot image: " + image.name)
}
@@ -495,6 +506,12 @@ func buildBootImage(ctx android.SingletonContext, image *bootImageConfig) *bootI
bootDexJars := make(android.Paths, image.modules.Len())
ctx.VisitAllModules(func(module android.Module) {
if i, j := getBootImageJar(ctx, image, module); i != -1 {
+ if existing := bootDexJars[i]; existing != nil {
+ ctx.Errorf("Multiple dex jars found for %s:%s - %s and %s",
+ image.modules.Apex(i), image.modules.Jar(i), existing, j)
+ return
+ }
+
bootDexJars[i] = j
}
})
@@ -506,7 +523,7 @@ func buildBootImage(ctx android.SingletonContext, image *bootImageConfig) *bootI
m := image.modules.Jar(i)
if ctx.Config().AllowMissingDependencies() {
missingDeps = append(missingDeps, m)
- bootDexJars[i] = android.PathForOutput(ctx, "missing")
+ bootDexJars[i] = android.PathForOutput(ctx, "missing/module", m, "from/apex", image.modules.Apex(i))
} else {
ctx.Errorf("failed to find a dex jar path for module '%s'"+
", note that some jars may be filtered out by module constraints", m)
@@ -779,7 +796,7 @@ func bootFrameworkProfileRule(ctx android.SingletonContext, image *bootImageConf
bootFrameworkProfile = path.Path()
} else {
missingDeps = append(missingDeps, defaultProfile)
- bootFrameworkProfile = android.PathForOutput(ctx, "missing")
+ bootFrameworkProfile = android.PathForOutput(ctx, "missing", defaultProfile)
}
profile := image.dir.Join(ctx, "boot.bprof")
diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go
index ce8410ed4..419dc3424 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -177,12 +177,13 @@ func stubFlagsRule(ctx android.SingletonContext) {
for moduleList, pathList := range moduleListToPathList {
for i := range pathList {
if pathList[i] == nil {
- pathList[i] = android.PathForOutput(ctx, "missing")
+ moduleName := (*moduleList)[i]
+ pathList[i] = android.PathForOutput(ctx, "missing/module", moduleName)
if ctx.Config().AllowMissingDependencies() {
- missingDeps = append(missingDeps, (*moduleList)[i])
+ missingDeps = append(missingDeps, moduleName)
} else {
ctx.Errorf("failed to find dex jar path for module %q",
- (*moduleList)[i])
+ moduleName)
}
}
}
diff --git a/java/java.go b/java/java.go
index 3d121ccea..d44719e99 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1081,7 +1081,6 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
switch tag {
case libTag:
deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...)
- // names of sdk libs that are directly depended are exported
j.classLoaderContexts.MaybeAddContext(ctx, dep.OptionalImplicitSdkLibrary(),
dep.DexJarBuildPath(), dep.DexJarInstallPath())
case staticLibTag:
@@ -1093,7 +1092,6 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars()...)
case libTag, instrumentationForTag:
deps.classpath = append(deps.classpath, dep.HeaderJars()...)
- // sdk lib names from dependencies are re-exported
j.classLoaderContexts.AddContextMap(dep.ClassLoaderContexts(), otherName)
deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
pluginJars, pluginClasses, disableTurbine := dep.ExportedPlugins()
@@ -1106,8 +1104,6 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
deps.staticJars = append(deps.staticJars, dep.ImplementationJars()...)
deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars()...)
deps.staticResourceJars = append(deps.staticResourceJars, dep.ResourceJars()...)
- // sdk lib names from dependencies are re-exported
- j.classLoaderContexts.AddContextMap(dep.ClassLoaderContexts(), otherName)
deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
pluginJars, pluginClasses, disableTurbine := dep.ExportedPlugins()
addPlugins(&deps, pluginJars, pluginClasses...)
@@ -1182,6 +1178,9 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
deps.systemModules = &systemModules{outputDir, outputDeps}
}
}
+
+ // Merge dep's CLC after processing the dep itself (which may add its own <uses-library>).
+ maybeAddCLCFromDep(module, tag, otherName, j.classLoaderContexts)
})
return deps
@@ -2815,8 +2814,6 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
switch tag {
case libTag, staticLibTag:
flags.classpath = append(flags.classpath, dep.HeaderJars()...)
- // sdk lib names from dependencies are re-exported
- j.classLoaderContexts.AddContextMap(dep.ClassLoaderContexts(), otherName)
case bootClasspathTag:
flags.bootClasspath = append(flags.bootClasspath, dep.HeaderJars()...)
}
@@ -2824,10 +2821,12 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
switch tag {
case libTag:
flags.classpath = append(flags.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...)
- // names of sdk libs that are directly depended are exported
j.classLoaderContexts.AddContext(ctx, otherName, dep.DexJarBuildPath(), dep.DexJarInstallPath())
}
}
+
+ // Merge dep's CLC after processing the dep itself (which may add its own <uses-library>).
+ maybeAddCLCFromDep(module, tag, otherName, j.classLoaderContexts)
})
var installFile android.Path
@@ -3248,3 +3247,31 @@ var Bool = proptools.Bool
var BoolDefault = proptools.BoolDefault
var String = proptools.String
var inList = android.InList
+
+// Add class loader context of a given dependency to the given class loader context, provided that
+// all the necessary conditions are met.
+func maybeAddCLCFromDep(depModule android.Module, depTag blueprint.DependencyTag,
+ depName string, clcMap dexpreopt.ClassLoaderContextMap) {
+
+ if dep, ok := depModule.(Dependency); ok {
+ if depTag == libTag {
+ // Ok, propagate <uses-library> through non-static library dependencies.
+ } else if depTag == staticLibTag {
+ // Propagate <uses-library> through static library dependencies, unless it is a
+ // component library (such as stubs). Component libraries have a dependency on their
+ // SDK library, which should not be pulled just because of a static component library.
+ if comp, isComp := depModule.(SdkLibraryComponentDependency); isComp {
+ if compName := comp.OptionalImplicitSdkLibrary(); compName != nil {
+ dep = nil
+ }
+ }
+ } else {
+ // Don't propagate <uses-library> for other dependency tags.
+ dep = nil
+ }
+
+ if dep != nil {
+ clcMap.AddContextMap(dep.ClassLoaderContexts(), depName)
+ }
+ }
+}