summaryrefslogtreecommitdiff
path: root/java/java.go
diff options
context:
space:
mode:
Diffstat (limited to 'java/java.go')
-rw-r--r--java/java.go322
1 files changed, 273 insertions, 49 deletions
diff --git a/java/java.go b/java/java.go
index 9c0fcbaa0..4c6a5a5ac 100644
--- a/java/java.go
+++ b/java/java.go
@@ -34,24 +34,53 @@ import (
)
func init() {
- android.RegisterModuleType("java_defaults", defaultsFactory)
-
- android.RegisterModuleType("java_library", LibraryFactory)
- android.RegisterModuleType("java_library_static", LibraryStaticFactory)
- android.RegisterModuleType("java_library_host", LibraryHostFactory)
- android.RegisterModuleType("java_binary", BinaryFactory)
- android.RegisterModuleType("java_binary_host", BinaryHostFactory)
- android.RegisterModuleType("java_test", TestFactory)
- android.RegisterModuleType("java_test_helper_library", TestHelperLibraryFactory)
- android.RegisterModuleType("java_test_host", TestHostFactory)
- android.RegisterModuleType("java_import", ImportFactory)
- android.RegisterModuleType("java_import_host", ImportFactoryHost)
- android.RegisterModuleType("java_device_for_host", DeviceForHostFactory)
- android.RegisterModuleType("java_host_for_device", HostForDeviceFactory)
- android.RegisterModuleType("dex_import", DexImportFactory)
-
- android.RegisterSingletonType("logtags", LogtagsSingleton)
- android.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory)
+ RegisterJavaBuildComponents(android.InitRegistrationContext)
+
+ // Register sdk member types.
+ android.RegisterSdkMemberType(&headerLibrarySdkMemberType{
+ librarySdkMemberType{
+ android.SdkMemberTypeBase{
+ PropertyName: "java_header_libs",
+ SupportsSdk: true,
+ },
+ },
+ })
+
+ android.RegisterSdkMemberType(&implLibrarySdkMemberType{
+ librarySdkMemberType{
+ android.SdkMemberTypeBase{
+ PropertyName: "java_libs",
+ },
+ },
+ })
+
+ android.RegisterSdkMemberType(&testSdkMemberType{
+ SdkMemberTypeBase: android.SdkMemberTypeBase{
+ PropertyName: "java_tests",
+ },
+ })
+}
+
+func RegisterJavaBuildComponents(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("java_defaults", DefaultsFactory)
+
+ ctx.RegisterModuleType("java_library", LibraryFactory)
+ ctx.RegisterModuleType("java_library_static", LibraryStaticFactory)
+ ctx.RegisterModuleType("java_library_host", LibraryHostFactory)
+ ctx.RegisterModuleType("java_binary", BinaryFactory)
+ ctx.RegisterModuleType("java_binary_host", BinaryHostFactory)
+ ctx.RegisterModuleType("java_test", TestFactory)
+ ctx.RegisterModuleType("java_test_helper_library", TestHelperLibraryFactory)
+ ctx.RegisterModuleType("java_test_host", TestHostFactory)
+ ctx.RegisterModuleType("java_test_import", JavaTestImportFactory)
+ ctx.RegisterModuleType("java_import", ImportFactory)
+ ctx.RegisterModuleType("java_import_host", ImportFactoryHost)
+ ctx.RegisterModuleType("java_device_for_host", DeviceForHostFactory)
+ ctx.RegisterModuleType("java_host_for_device", HostForDeviceFactory)
+ ctx.RegisterModuleType("dex_import", DexImportFactory)
+
+ ctx.RegisterSingletonType("logtags", LogtagsSingleton)
+ ctx.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory)
}
func (j *Module) checkSdkVersion(ctx android.ModuleContext) {
@@ -405,10 +434,6 @@ func (j *Module) OutputFiles(tag string) (android.Paths, error) {
}
}
-func (j *Module) DexJarFile() android.Path {
- return j.dexJarFile
-}
-
var _ android.OutputFileProducer = (*Module)(nil)
type Dependency interface {
@@ -422,6 +447,7 @@ type Dependency interface {
ExportedPlugins() (android.Paths, []string)
SrcJarArgs() ([]string, android.Paths)
BaseModuleName() string
+ JacocoReportClassesFile() android.Path
}
type SdkLibraryDependency interface {
@@ -449,7 +475,6 @@ type dependencyTag struct {
type jniDependencyTag struct {
blueprint.BaseDependencyTag
- target android.Target
}
func IsJniDepTag(depTag blueprint.DependencyTag) bool {
@@ -475,6 +500,14 @@ var (
usesLibTag = dependencyTag{name: "uses-library"}
)
+func IsLibDepTag(depTag blueprint.DependencyTag) bool {
+ return depTag == libTag
+}
+
+func IsStaticLibDepTag(depTag blueprint.DependencyTag) bool {
+ return depTag == staticLibTag
+}
+
type sdkDep struct {
useModule, useFiles, useDefaultLibs, invalidVersion bool
@@ -542,6 +575,16 @@ func (j *Module) targetSdkVersion() string {
return j.sdkVersion()
}
+func (j *Module) AvailableFor(what string) bool {
+ if what == android.AvailableToPlatform && Bool(j.deviceProperties.Hostdex) {
+ // Exception: for hostdex: true libraries, the platform variant is created
+ // even if it's not marked as available to platform. In that case, the platform
+ // variant is used only for the hostdex and not installed to the device.
+ return true
+ }
+ return j.ApexModuleBase.AvailableFor(what)
+}
+
func (j *Module) deps(ctx android.BottomUpMutatorContext) {
if ctx.Device() {
sdkDep := decodeSdkDep(ctx, sdkContext(j))
@@ -568,8 +611,33 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) {
}
}
- ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
- ctx.AddVariationDependencies(nil, staticLibTag, j.properties.Static_libs...)
+ syspropPublicStubs := syspropPublicStubs(ctx.Config())
+
+ // rewriteSyspropLibs validates if a java module can link against platform's sysprop_library,
+ // and redirects dependency to public stub depending on the link type.
+ rewriteSyspropLibs := func(libs []string, prop string) []string {
+ // make a copy
+ ret := android.CopyOf(libs)
+
+ for idx, lib := range libs {
+ stub, ok := syspropPublicStubs[lib]
+
+ if !ok {
+ continue
+ }
+
+ linkType, _ := j.getLinkType(ctx.ModuleName())
+ // only platform modules can use internal props
+ if linkType != javaPlatform {
+ ret[idx] = stub
+ }
+ }
+
+ return ret
+ }
+
+ ctx.AddVariationDependencies(nil, libTag, rewriteSyspropLibs(j.properties.Libs, "libs")...)
+ ctx.AddVariationDependencies(nil, staticLibTag, rewriteSyspropLibs(j.properties.Static_libs, "static_libs")...)
ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), pluginTag, j.properties.Plugins...)
ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), exportedPluginTag, j.properties.Exported_plugins...)
@@ -589,7 +657,14 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) {
}
}
- if j.shouldInstrumentStatic(ctx) {
+ // Framework libraries need special handling in static coverage builds: they should not have
+ // static dependency on jacoco, otherwise there would be multiple conflicting definitions of
+ // the same jacoco classes coming from different bootclasspath jars.
+ if inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
+ if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
+ j.properties.Instrument = true
+ }
+ } else if j.shouldInstrumentStatic(ctx) {
ctx.AddVariationDependencies(nil, staticLibTag, "jacocoagent")
}
}
@@ -792,8 +867,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
return
}
switch module.(type) {
- case *Library:
- case *AndroidLibrary:
+ case *Library, *AndroidLibrary:
if to, ok := module.(linkTypeContext); ok {
switch tag {
case bootClasspathTag, libTag, staticLibTag:
@@ -1393,12 +1467,6 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
j.headerJarFile = j.implementationJarFile
}
- if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
- if inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
- j.properties.Instrument = true
- }
- }
-
if j.shouldInstrument(ctx) {
outputFile = j.instrument(ctx, flags, outputFile, jarName)
}
@@ -1658,6 +1726,10 @@ func (j *Module) Stem() string {
return proptools.StringDefault(j.deviceProperties.Stem, j.Name())
}
+func (j *Module) JacocoReportClassesFile() android.Path {
+ return j.jacocoReportClassesFile
+}
+
//
// Java libraries (.jar file)
//
@@ -1711,23 +1783,53 @@ func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
}
const (
- aidlIncludeDir = "aidl"
- javaStubDir = "java"
- javaStubFileSuffix = ".jar"
+ aidlIncludeDir = "aidl"
+ javaDir = "java"
+ jarFileSuffix = ".jar"
+ testConfigSuffix = "-AndroidTest.xml"
)
-// path to the stub file of a java library. Relative to <sdk_root>/<api_dir>
-func (j *Library) javaStubFilePathFor() string {
- return filepath.Join(javaStubDir, j.Name()+javaStubFileSuffix)
+// path to the jar file of a java library. Relative to <sdk_root>/<api_dir>
+func sdkSnapshotFilePathForJar(member android.SdkMember) string {
+ return sdkSnapshotFilePathForMember(member, jarFileSuffix)
+}
+
+func sdkSnapshotFilePathForMember(member android.SdkMember, suffix string) string {
+ return filepath.Join(javaDir, member.Name()+suffix)
+}
+
+type librarySdkMemberType struct {
+ android.SdkMemberTypeBase
+}
+
+func (mt *librarySdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
+ mctx.AddVariationDependencies(nil, dependencyTag, names...)
+}
+
+func (mt *librarySdkMemberType) IsInstance(module android.Module) bool {
+ _, ok := module.(*Library)
+ return ok
}
-func (j *Library) BuildSnapshot(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder) {
- headerJars := j.HeaderJars()
- if len(headerJars) != 1 {
- panic(fmt.Errorf("there must be only one header jar from %q", j.Name()))
+func (mt *librarySdkMemberType) buildSnapshot(
+ sdkModuleContext android.ModuleContext,
+ builder android.SnapshotBuilder,
+ member android.SdkMember,
+ jarToExportGetter func(j *Library) android.Path) {
+
+ variants := member.Variants()
+ if len(variants) != 1 {
+ sdkModuleContext.ModuleErrorf("sdk contains %d variants of member %q but only one is allowed", len(variants), member.Name())
+ for _, variant := range variants {
+ sdkModuleContext.ModuleErrorf(" %q", variant)
+ }
}
- snapshotRelativeJavaLibPath := j.javaStubFilePathFor()
- builder.CopyToSnapshot(headerJars[0], snapshotRelativeJavaLibPath)
+ variant := variants[0]
+ j := variant.(*Library)
+
+ exportedJar := jarToExportGetter(j)
+ snapshotRelativeJavaLibPath := sdkSnapshotFilePathForJar(member)
+ builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath)
for _, dir := range j.AidlIncludeDirs() {
// TODO(jiyong): copy parcelable declarations only
@@ -1737,10 +1839,40 @@ func (j *Library) BuildSnapshot(sdkModuleContext android.ModuleContext, builder
}
}
- module := builder.AddPrebuiltModule(sdkModuleContext.OtherModuleName(j), "java_import")
+ module := builder.AddPrebuiltModule(member, "java_import")
module.AddProperty("jars", []string{snapshotRelativeJavaLibPath})
}
+type headerLibrarySdkMemberType struct {
+ librarySdkMemberType
+}
+
+func (mt *headerLibrarySdkMemberType) BuildSnapshot(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, member android.SdkMember) {
+ mt.librarySdkMemberType.buildSnapshot(sdkModuleContext, builder, member, func(j *Library) android.Path {
+ headerJars := j.HeaderJars()
+ if len(headerJars) != 1 {
+ panic(fmt.Errorf("there must be only one header jar from %q", j.Name()))
+ }
+
+ return headerJars[0]
+ })
+}
+
+type implLibrarySdkMemberType struct {
+ librarySdkMemberType
+}
+
+func (mt *implLibrarySdkMemberType) BuildSnapshot(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, member android.SdkMember) {
+ mt.librarySdkMemberType.buildSnapshot(sdkModuleContext, builder, member, func(j *Library) android.Path {
+ implementationJars := j.ImplementationJars()
+ if len(implementationJars) != 1 {
+ panic(fmt.Errorf("there must be only one implementation jar from %q", j.Name()))
+ }
+
+ return implementationJars[0]
+ })
+}
+
// java_library builds and links sources into a `.jar` file for the device, and possibly for the host as well.
//
// By default, a java_library has a single variant that produces a `.jar` file containing `.class` files that were
@@ -1823,6 +1955,16 @@ type testHelperLibraryProperties struct {
Test_suites []string `android:"arch_variant"`
}
+type prebuiltTestProperties struct {
+ // list of compatibility suites (for example "cts", "vts") that the module should be
+ // installed into.
+ Test_suites []string `android:"arch_variant"`
+
+ // the name of the test configuration (for example "AndroidTest.xml") that should be
+ // installed with the module.
+ Test_config *string `android:"path,arch_variant"`
+}
+
type Test struct {
Library
@@ -1838,6 +1980,14 @@ type TestHelperLibrary struct {
testHelperLibraryProperties testHelperLibraryProperties
}
+type JavaTestImport struct {
+ Import
+
+ prebuiltTestProperties prebuiltTestProperties
+
+ testConfig android.Path
+}
+
func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template,
j.testProperties.Test_suites, j.testProperties.Auto_gen_config)
@@ -1850,6 +2000,53 @@ func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContex
j.Library.GenerateAndroidBuildActions(ctx)
}
+func (j *JavaTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.prebuiltTestProperties.Test_config, nil,
+ j.prebuiltTestProperties.Test_suites, nil)
+
+ j.Import.GenerateAndroidBuildActions(ctx)
+}
+
+type testSdkMemberType struct {
+ android.SdkMemberTypeBase
+}
+
+func (mt *testSdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
+ mctx.AddVariationDependencies(nil, dependencyTag, names...)
+}
+
+func (mt *testSdkMemberType) IsInstance(module android.Module) bool {
+ _, ok := module.(*Test)
+ return ok
+}
+
+func (mt *testSdkMemberType) BuildSnapshot(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, member android.SdkMember) {
+ variants := member.Variants()
+ if len(variants) != 1 {
+ sdkModuleContext.ModuleErrorf("sdk contains %d variants of member %q but only one is allowed", len(variants), member.Name())
+ for _, variant := range variants {
+ sdkModuleContext.ModuleErrorf(" %q", variant)
+ }
+ }
+ variant := variants[0]
+ j := variant.(*Test)
+
+ implementationJars := j.ImplementationJars()
+ if len(implementationJars) != 1 {
+ panic(fmt.Errorf("there must be only one implementation jar from %q", j.Name()))
+ }
+
+ snapshotRelativeJavaLibPath := sdkSnapshotFilePathForJar(member)
+ builder.CopyToSnapshot(implementationJars[0], snapshotRelativeJavaLibPath)
+
+ snapshotRelativeTestConfigPath := sdkSnapshotFilePathForMember(member, testConfigSuffix)
+ builder.CopyToSnapshot(j.testConfig, snapshotRelativeTestConfigPath)
+
+ module := builder.AddPrebuiltModule(member, "java_test_import")
+ module.AddProperty("jars", []string{snapshotRelativeJavaLibPath})
+ module.AddProperty("test_config", snapshotRelativeTestConfigPath)
+}
+
// java_test builds a and links sources into a `.jar` file for the device, and possibly for the host as well, and
// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
//
@@ -1893,6 +2090,30 @@ func TestHelperLibraryFactory() android.Module {
return module
}
+// java_test_import imports one or more `.jar` files into the build graph as if they were built by a java_test module
+// and makes sure that it is added to the appropriate test suite.
+//
+// By default, a java_test_import has a single variant that expects a `.jar` file containing `.class` files that were
+// compiled against an Android classpath.
+//
+// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
+// for host modules.
+func JavaTestImportFactory() android.Module {
+ module := &JavaTestImport{}
+
+ module.AddProperties(
+ &module.Import.properties,
+ &module.prebuiltTestProperties)
+
+ module.Import.properties.Installable = proptools.BoolPtr(true)
+
+ android.InitPrebuiltModule(module, &module.properties.Jars)
+ android.InitApexModule(module)
+ android.InitSdkAwareModule(module)
+ InitJavaModule(module, android.HostAndDeviceSupported)
+ return module
+}
+
// java_test_host builds a and links sources into a `.jar` file for the host, and creates an `AndroidTest.xml` file to
// allow running the test with `atest` or a `TEST_MAPPING` file.
//
@@ -2085,6 +2306,10 @@ func (j *Import) Stem() string {
return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name())
}
+func (a *Import) JacocoReportClassesFile() android.Path {
+ return nil
+}
+
func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {
ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
}
@@ -2394,10 +2619,9 @@ func defaultsFactory() android.Module {
return DefaultsFactory()
}
-func DefaultsFactory(props ...interface{}) android.Module {
+func DefaultsFactory() android.Module {
module := &Defaults{}
- module.AddProperties(props...)
module.AddProperties(
&CompilerProperties{},
&CompilerDeviceProperties{},