diff options
Diffstat (limited to 'java/java.go')
| -rw-r--r-- | java/java.go | 230 | 
1 files changed, 144 insertions, 86 deletions
| diff --git a/java/java.go b/java/java.go index d49b64f66..69ec2a442 100644 --- a/java/java.go +++ b/java/java.go @@ -40,18 +40,21 @@ func init() {  	// Register sdk member types.  	android.RegisterSdkMemberType(javaHeaderLibsSdkMemberType) +	// Export implementation classes jar as part of the sdk. +	exportImplementationClassesJar := func(_ android.SdkMemberContext, j *Library) android.Path { +		implementationJars := j.ImplementationAndResourcesJars() +		if len(implementationJars) != 1 { +			panic(fmt.Errorf("there must be only one implementation jar from %q", j.Name())) +		} +		return implementationJars[0] +	} +  	// Register java implementation libraries for use only in module_exports (not sdk).  	android.RegisterSdkMemberType(&librarySdkMemberType{  		android.SdkMemberTypeBase{  			PropertyName: "java_libs",  		}, -		func(_ android.SdkMemberContext, j *Library) android.Path { -			implementationJars := j.ImplementationAndResourcesJars() -			if len(implementationJars) != 1 { -				panic(fmt.Errorf("there must be only one implementation jar from %q", j.Name())) -			} -			return implementationJars[0] -		}, +		exportImplementationClassesJar,  		sdkSnapshotFilePathForJar,  		copyEverythingToSnapshot,  	}) @@ -72,19 +75,11 @@ func init() {  			PropertyName: "java_boot_libs",  			SupportsSdk:  true,  		}, -		func(ctx android.SdkMemberContext, j *Library) android.Path { -			// Java boot libs are only provided in the SDK to provide access to their dex implementation -			// jar for use by dexpreopting and boot jars package check. They do not need to provide an -			// actual implementation jar but the java_import will need a file that exists so just copy an -			// empty file. Any attempt to use that file as a jar will cause a build error. -			return ctx.SnapshotBuilder().EmptyFile() -		}, -		func(osPrefix, name string) string { -			// Create a special name for the implementation jar to try and provide some useful information -			// to a developer that attempts to compile against this. -			// TODO(b/175714559): Provide a proper error message in Soong not ninja. -			return filepath.Join(osPrefix, "java_boot_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix) -		}, +		// Temporarily export implementation classes jar for java_boot_libs as it is required for the +		// hiddenapi processing. +		// TODO(b/179354495): Revert once hiddenapi processing has been modularized. +		exportImplementationClassesJar, +		sdkSnapshotFilePathForJar,  		onlyCopyJarToSnapshot,  	}) @@ -303,6 +298,9 @@ type CompilerProperties struct {  	// If true, package the kotlin stdlib into the jar.  Defaults to true.  	Static_kotlin_stdlib *bool `android:"arch_variant"` + +	// A list of java_library instances that provide additional hiddenapi annotations for the library. +	Hiddenapi_additional_annotations []string  }  type CompilerDeviceProperties struct { @@ -538,6 +536,53 @@ func (j *Module) OutputFiles(tag string) (android.Paths, error) {  var _ android.OutputFileProducer = (*Module)(nil) +// JavaInfo contains information about a java module for use by modules that depend on it. +type JavaInfo struct { +	// HeaderJars is a list of jars that can be passed as the javac classpath in order to link +	// against this module.  If empty, ImplementationJars should be used instead. +	HeaderJars android.Paths + +	// ImplementationAndResourceJars is a list of jars that contain the implementations of classes +	// in the module as well as any resources included in the module. +	ImplementationAndResourcesJars android.Paths + +	// ImplementationJars is a list of jars that contain the implementations of classes in the +	//module. +	ImplementationJars android.Paths + +	// ResourceJars is a list of jars that contain the resources included in the module. +	ResourceJars android.Paths + +	// AidlIncludeDirs is a list of directories that should be passed to the aidl tool when +	// depending on this module. +	AidlIncludeDirs android.Paths + +	// SrcJarArgs is a list of arguments to pass to soong_zip to package the sources of this +	// module. +	SrcJarArgs []string + +	// SrcJarDeps is a list of paths to depend on when packaging the sources of this module. +	SrcJarDeps android.Paths + +	// ExportedPlugins is a list of paths that should be used as annotation processors for any +	// module that depends on this module. +	ExportedPlugins android.Paths + +	// ExportedPluginClasses is a list of classes that should be run as annotation processors for +	// any module that depends on this module. +	ExportedPluginClasses []string + +	// ExportedPluginDisableTurbine is true if this module's annotation processors generate APIs, +	// requiring disbling turbine for any modules that depend on it. +	ExportedPluginDisableTurbine bool + +	// JacocoReportClassesFile is the path to a jar containing uninstrumented classes that will be +	// instrumented by jacoco. +	JacocoReportClassesFile android.Path +} + +var JavaInfoProvider = blueprint.NewProvider(JavaInfo{}) +  // Methods that need to be implemented for a module that is added to apex java_libs property.  type ApexDependency interface {  	HeaderJars() android.Paths @@ -551,18 +596,6 @@ type UsesLibraryDependency interface {  	ClassLoaderContexts() dexpreopt.ClassLoaderContextMap  } -type Dependency interface { -	ApexDependency -	UsesLibraryDependency -	ImplementationJars() android.Paths -	ResourceJars() android.Paths -	AidlIncludeDirs() android.Paths -	ExportedPlugins() (android.Paths, []string, bool) -	SrcJarArgs() ([]string, android.Paths) -	BaseModuleName() string -	JacocoReportClassesFile() android.Path -} -  type xref interface {  	XrefJavaFiles() android.Paths  } @@ -810,6 +843,9 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) {  	libDeps := ctx.AddVariationDependencies(nil, libTag, rewriteSyspropLibs(j.properties.Libs, "libs")...)  	ctx.AddVariationDependencies(nil, staticLibTag, rewriteSyspropLibs(j.properties.Static_libs, "static_libs")...) +	// 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() {  		// Require java_sdk_library at inter-partition java dependency to ensure stable  		// interface between partitions. If inter-partition java_library dependency is detected, @@ -1116,44 +1152,42 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {  			return  		} -		switch dep := module.(type) { -		case SdkLibraryDependency: +		if dep, ok := module.(SdkLibraryDependency); ok {  			switch tag {  			case libTag:  				deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...)  			case staticLibTag:  				ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName)  			} -		case Dependency: +		} else if ctx.OtherModuleHasProvider(module, JavaInfoProvider) { +			dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)  			switch tag {  			case bootClasspathTag: -				deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars()...) +				deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars...)  			case libTag, instrumentationForTag: -				deps.classpath = append(deps.classpath, dep.HeaderJars()...) -				deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...) -				pluginJars, pluginClasses, disableTurbine := dep.ExportedPlugins() -				addPlugins(&deps, pluginJars, pluginClasses...) -				deps.disableTurbine = deps.disableTurbine || disableTurbine +				deps.classpath = append(deps.classpath, dep.HeaderJars...) +				deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...) +				addPlugins(&deps, dep.ExportedPlugins, dep.ExportedPluginClasses...) +				deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine  			case java9LibTag: -				deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars()...) +				deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...)  			case staticLibTag: -				deps.classpath = append(deps.classpath, dep.HeaderJars()...) -				deps.staticJars = append(deps.staticJars, dep.ImplementationJars()...) -				deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars()...) -				deps.staticResourceJars = append(deps.staticResourceJars, dep.ResourceJars()...) -				deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...) -				pluginJars, pluginClasses, disableTurbine := dep.ExportedPlugins() -				addPlugins(&deps, pluginJars, pluginClasses...) +				deps.classpath = append(deps.classpath, dep.HeaderJars...) +				deps.staticJars = append(deps.staticJars, dep.ImplementationJars...) +				deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars...) +				deps.staticResourceJars = append(deps.staticResourceJars, dep.ResourceJars...) +				deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...) +				addPlugins(&deps, dep.ExportedPlugins, dep.ExportedPluginClasses...)  				// Turbine doesn't run annotation processors, so any module that uses an  				// annotation processor that generates API is incompatible with the turbine  				// optimization. -				deps.disableTurbine = deps.disableTurbine || disableTurbine +				deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine  			case pluginTag: -				if plugin, ok := dep.(*Plugin); ok { +				if plugin, ok := module.(*Plugin); ok {  					if plugin.pluginProperties.Processor_class != nil { -						addPlugins(&deps, plugin.ImplementationAndResourcesJars(), *plugin.pluginProperties.Processor_class) +						addPlugins(&deps, dep.ImplementationAndResourcesJars, *plugin.pluginProperties.Processor_class)  					} else { -						addPlugins(&deps, plugin.ImplementationAndResourcesJars()) +						addPlugins(&deps, dep.ImplementationAndResourcesJars)  					}  					// Turbine doesn't run annotation processors, so any module that uses an  					// annotation processor that generates API is incompatible with the turbine @@ -1163,14 +1197,14 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {  					ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName)  				}  			case errorpronePluginTag: -				if plugin, ok := dep.(*Plugin); ok { -					deps.errorProneProcessorPath = append(deps.errorProneProcessorPath, plugin.ImplementationAndResourcesJars()...) +				if _, ok := module.(*Plugin); ok { +					deps.errorProneProcessorPath = append(deps.errorProneProcessorPath, dep.ImplementationAndResourcesJars...)  				} else {  					ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName)  				}  			case exportedPluginTag: -				if plugin, ok := dep.(*Plugin); ok { -					j.exportedPluginJars = append(j.exportedPluginJars, plugin.ImplementationAndResourcesJars()...) +				if plugin, ok := module.(*Plugin); ok { +					j.exportedPluginJars = append(j.exportedPluginJars, dep.ImplementationAndResourcesJars...)  					if plugin.pluginProperties.Processor_class != nil {  						j.exportedPluginClasses = append(j.exportedPluginClasses, *plugin.pluginProperties.Processor_class)  					} @@ -1182,12 +1216,11 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {  					ctx.PropertyErrorf("exported_plugins", "%q is not a java_plugin module", otherName)  				}  			case kotlinStdlibTag: -				deps.kotlinStdlib = append(deps.kotlinStdlib, dep.HeaderJars()...) +				deps.kotlinStdlib = append(deps.kotlinStdlib, dep.HeaderJars...)  			case kotlinAnnotationsTag: -				deps.kotlinAnnotations = dep.HeaderJars() +				deps.kotlinAnnotations = dep.HeaderJars  			} - -		case android.SourceFileProducer: +		} else if dep, ok := module.(android.SourceFileProducer); ok {  			switch tag {  			case libTag:  				checkProducesJars(ctx, dep) @@ -1198,7 +1231,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {  				deps.staticJars = append(deps.staticJars, dep.Srcs()...)  				deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs()...)  			} -		default: +		} else {  			switch tag {  			case bootClasspathTag:  				// If a system modules dependency has been added to the bootclasspath @@ -1803,14 +1836,8 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {  			return  		} -		configurationName := j.ConfigurationName() -		primary := configurationName == ctx.ModuleName() -		// If the prebuilt is being used rather than the from source, skip this -		// module to prevent duplicated classes -		primary = primary && !j.IsReplacedByPrebuilt() -  		// Hidden API CSV generation and dex encoding -		dexOutputFile = j.hiddenAPI.hiddenAPI(ctx, configurationName, primary, dexOutputFile, j.implementationJarFile, +		dexOutputFile = j.hiddenAPIExtractAndEncode(ctx, dexOutputFile, j.implementationJarFile,  			proptools.Bool(j.dexProperties.Uncompress_dex))  		// merge dex jar with resources if necessary @@ -1871,6 +1898,20 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {  	ctx.CheckbuildFile(outputFile) +	ctx.SetProvider(JavaInfoProvider, JavaInfo{ +		HeaderJars:                     android.PathsIfNonNil(j.headerJarFile), +		ImplementationAndResourcesJars: android.PathsIfNonNil(j.implementationAndResourcesJar), +		ImplementationJars:             android.PathsIfNonNil(j.implementationJarFile), +		ResourceJars:                   android.PathsIfNonNil(j.resourceJar), +		AidlIncludeDirs:                j.exportAidlIncludeDirs, +		SrcJarArgs:                     j.srcJarArgs, +		SrcJarDeps:                     j.srcJarDeps, +		ExportedPlugins:                j.exportedPluginJars, +		ExportedPluginClasses:          j.exportedPluginClasses, +		ExportedPluginDisableTurbine:   j.exportedDisableTurbine, +		JacocoReportClassesFile:        j.jacocoReportClassesFile, +	}) +  	// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource  	j.outputFile = outputFile.WithoutRel()  } @@ -1978,8 +2019,6 @@ func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags,  	return instrumentedJar  } -var _ Dependency = (*Module)(nil) -  func (j *Module) HeaderJars() android.Paths {  	if j.headerJarFile == nil {  		return nil @@ -2095,6 +2134,11 @@ func (j *Module) Stem() string {  	return proptools.StringDefault(j.deviceProperties.Stem, j.Name())  } +// ConfigurationName returns the name of the module as used in build configuration. +// +// This is usually the same as BaseModuleName() except for the <x>.impl libraries created by +// java_sdk_library in which case this is the BaseModuleName() without the ".impl" suffix, +// i.e. just <x>.  func (j *Module) ConfigurationName() string {  	return proptools.StringDefault(j.deviceProperties.ConfigurationName, j.BaseModuleName())  } @@ -2154,6 +2198,11 @@ func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bo  }  func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { +	// Initialize the hiddenapi structure. Pass in the configuration name rather than the module name +	// so the hidden api will encode the <x>.impl java_ library created by java_sdk_library just as it +	// would the <x> library if <x> was configured as a boot jar. +	j.initHiddenAPI(ctx, j.ConfigurationName()) +  	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)  	if !apexInfo.IsForPlatform() {  		j.hideApexVariantFromMake = true @@ -2687,9 +2736,10 @@ func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) {  }  func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) { -	if ctx.Arch().ArchType == android.Common { +	if ctx.Arch().ArchType == android.Common || ctx.BazelConversionMode() {  		j.deps(ctx) -	} else { +	} +	if ctx.Arch().ArchType != android.Common || ctx.BazelConversionMode() {  		// These dependencies ensure the host installation rules will install the jar file and  		// the jni libraries when the wrapper is installed.  		ctx.AddVariationDependencies(nil, jniInstallTag, j.binaryProperties.Jni_libs...) @@ -2853,6 +2903,9 @@ func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {  }  func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { +	// Initialize the hiddenapi structure. +	j.initHiddenAPI(ctx, j.BaseModuleName()) +  	if !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform() {  		j.hideApexVariantFromMake = true  	} @@ -2877,15 +2930,15 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {  	ctx.VisitDirectDeps(func(module android.Module) {  		tag := ctx.OtherModuleDependencyTag(module) -		switch dep := module.(type) { -		case Dependency: +		if ctx.OtherModuleHasProvider(module, JavaInfoProvider) { +			dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)  			switch tag {  			case libTag, staticLibTag: -				flags.classpath = append(flags.classpath, dep.HeaderJars()...) +				flags.classpath = append(flags.classpath, dep.HeaderJars...)  			case bootClasspathTag: -				flags.bootClasspath = append(flags.bootClasspath, dep.HeaderJars()...) +				flags.bootClasspath = append(flags.bootClasspath, dep.HeaderJars...)  			} -		case SdkLibraryDependency: +		} else if dep, ok := module.(SdkLibraryDependency); ok {  			switch tag {  			case libTag:  				flags.classpath = append(flags.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...) @@ -2921,8 +2974,10 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {  			// Get the path of the dex implementation jar from the `deapexer` module.  			di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo) -			j.dexJarFile = di.PrebuiltExportPath(j.BaseModuleName(), ".dexjar") -			if j.dexJarFile == nil { +			if dexOutputPath := di.PrebuiltExportPath(j.BaseModuleName(), ".dexjar"); dexOutputPath != nil { +				j.dexJarFile = dexOutputPath +				j.hiddenAPIExtractInformation(ctx, dexOutputPath, outputFile) +			} else {  				// This should never happen as a variant for a prebuilt_apex is only created if the  				// prebuilt_apex has been configured to export the java library dex file.  				ctx.ModuleErrorf("internal error: no dex implementation jar available from prebuilt_apex %q", deapexerModule.Name()) @@ -2952,16 +3007,20 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {  				return  			} -			configurationName := j.BaseModuleName() -			primary := j.Prebuilt().UsePrebuilt() -  			// Hidden API CSV generation and dex encoding -			dexOutputFile = j.hiddenAPI.hiddenAPI(ctx, configurationName, primary, dexOutputFile, outputFile, +			dexOutputFile = j.hiddenAPIExtractAndEncode(ctx, dexOutputFile, outputFile,  				proptools.Bool(j.dexProperties.Uncompress_dex))  			j.dexJarFile = dexOutputFile  		}  	} + +	ctx.SetProvider(JavaInfoProvider, JavaInfo{ +		HeaderJars:                     android.PathsIfNonNil(j.combinedClasspathFile), +		ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedClasspathFile), +		ImplementationJars:             android.PathsIfNonNil(j.combinedClasspathFile), +		AidlIncludeDirs:                j.exportAidlIncludeDirs, +	})  }  func (j *Import) OutputFiles(tag string) (android.Paths, error) { @@ -2975,8 +3034,6 @@ func (j *Import) OutputFiles(tag string) (android.Paths, error) {  var _ android.OutputFileProducer = (*Import)(nil) -var _ Dependency = (*Import)(nil) -  func (j *Import) HeaderJars() android.Paths {  	if j.combinedClasspathFile == nil {  		return nil @@ -3322,6 +3379,7 @@ func DefaultsFactory() android.Module {  		&android.ApexProperties{},  		&RuntimeResourceOverlayProperties{},  		&LintProperties{}, +		&appTestHelperAppProperties{},  	)  	android.InitDefaultsModule(module) |