diff options
author | Chris Gross <chrisgross@google.com> | 2021-03-10 23:00:14 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2021-03-10 23:00:14 +0000 |
commit | 5989878a55d2d34a1a8e5e16bb37349c4949758b (patch) | |
tree | 93d8e18c914c88f6555a10a863db4bf72d778ce5 /java/java.go | |
parent | 31143d8dc32e15aeea395b1d467538d46027ce48 (diff) | |
parent | 622eac0b10f516bc59fe0d23db7f7cff52d44173 (diff) |
Merge changes from topic "SP1A.210222.001" into s-keystone-qcom-dev
* changes:
Fix the releax_check flag format verb.
Add non-fatal mode for verify_uses_libraries check.
Merge SP1A.210222.001
Diffstat (limited to 'java/java.go')
-rw-r--r-- | java/java.go | 261 |
1 files changed, 159 insertions, 102 deletions
diff --git a/java/java.go b/java/java.go index bed232b4e..dbfad029b 100644 --- a/java/java.go +++ b/java/java.go @@ -298,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 { @@ -533,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 @@ -546,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 } @@ -805,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, @@ -973,6 +1014,7 @@ type linkType int const ( // TODO(jiyong) rename these for better readability. Make the allowed // and disallowed link types explicit + // order is important here. See rank() javaCore linkType = iota javaSdk javaSystem @@ -981,6 +1023,31 @@ const ( javaPlatform ) +func (lt linkType) String() string { + switch lt { + case javaCore: + return "core Java API" + case javaSdk: + return "Android API" + case javaSystem: + return "system API" + case javaModule: + return "module API" + case javaSystemServer: + return "system server API" + case javaPlatform: + return "private API" + default: + panic(fmt.Errorf("unrecognized linktype: %v", lt)) + } +} + +// rank determins the total order among linkTypes. A link type of rank A can link to another link +// type of rank B only when B <= A +func (lt linkType) rank() int { + return int(lt) +} + type linkTypeContext interface { android.Module getLinkType(name string) (ret linkType, stubs bool) @@ -1040,44 +1107,13 @@ func checkLinkType(ctx android.ModuleContext, from *Module, to linkTypeContext, return } otherLinkType, _ := to.getLinkType(ctx.OtherModuleName(to)) - commonMessage := " In order to fix this, consider adjusting sdk_version: OR platform_apis: " + - "property of the source or target module so that target module is built with the same " + - "or smaller API set when compared to the source." - switch myLinkType { - case javaCore: - if otherLinkType != javaCore { - ctx.ModuleErrorf("compiles against core Java API, but dependency %q is compiling against non-core Java APIs."+commonMessage, - ctx.OtherModuleName(to)) - } - break - case javaSdk: - if otherLinkType != javaCore && otherLinkType != javaSdk { - ctx.ModuleErrorf("compiles against Android API, but dependency %q is compiling against non-public Android API."+commonMessage, - ctx.OtherModuleName(to)) - } - break - case javaSystem: - if otherLinkType == javaPlatform || otherLinkType == javaModule || otherLinkType == javaSystemServer { - ctx.ModuleErrorf("compiles against system API, but dependency %q is compiling against private API."+commonMessage, - ctx.OtherModuleName(to)) - } - break - case javaModule: - if otherLinkType == javaPlatform || otherLinkType == javaSystemServer { - ctx.ModuleErrorf("compiles against module API, but dependency %q is compiling against private API."+commonMessage, - ctx.OtherModuleName(to)) - } - break - case javaSystemServer: - if otherLinkType == javaPlatform { - ctx.ModuleErrorf("compiles against system server API, but dependency %q is compiling against private API."+commonMessage, - ctx.OtherModuleName(to)) - } - break - case javaPlatform: - // no restriction on link-type - break + if myLinkType.rank() < otherLinkType.rank() { + ctx.ModuleErrorf("compiles against %v, but dependency %q is compiling against %v. "+ + "In order to fix this, consider adjusting sdk_version: OR platform_apis: "+ + "property of the source or target module so that target module is built "+ + "with the same or smaller API set when compared to the source.", + myLinkType, ctx.OtherModuleName(to), otherLinkType) } } @@ -1111,44 +1147,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 @@ -1158,14 +1192,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) } @@ -1177,12 +1211,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) @@ -1193,7 +1226,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 @@ -1798,14 +1831,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 @@ -1866,6 +1893,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() } @@ -1973,8 +2014,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 @@ -2090,6 +2129,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()) } @@ -2149,6 +2193,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 @@ -2378,7 +2427,7 @@ type testProperties struct { // list of files or filegroup modules that provide data that should be installed alongside // the test - Data []string `android:"path,arch_variant"` + Data []string `android:"path"` // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true @@ -2849,6 +2898,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 } @@ -2873,15 +2925,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())...) @@ -2917,8 +2969,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()) @@ -2948,16 +3002,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) { @@ -2971,8 +3029,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 @@ -3318,6 +3374,7 @@ func DefaultsFactory() android.Module { &android.ApexProperties{}, &RuntimeResourceOverlayProperties{}, &LintProperties{}, + &appTestHelperAppProperties{}, ) android.InitDefaultsModule(module) |