summaryrefslogtreecommitdiff
path: root/java/base.go
diff options
context:
space:
mode:
Diffstat (limited to 'java/base.go')
-rw-r--r--java/base.go135
1 files changed, 128 insertions, 7 deletions
diff --git a/java/base.go b/java/base.go
index 4e2366f7d..e2c4d327b 100644
--- a/java/base.go
+++ b/java/base.go
@@ -205,6 +205,13 @@ type CommonProperties struct {
// Note that currently not all actions implemented by android_apps are sandboxed, so you
// may only see this being necessary in lint builds.
Compile_data []string `android:"path"`
+
+ // Property signifying whether the module compiles stubs or not.
+ // Should be set to true when srcs of this module are stub files.
+ // This property does not need to be set to true when the module depends on
+ // the stubs via libs, but should be set to true when the module depends on
+ // the stubs via static libs.
+ Is_stubs_module *bool
}
// Properties that are specific to device modules. Host module factories should not add these when
@@ -532,6 +539,8 @@ type Module struct {
// Values that will be set in the JarJarProvider data for jarjar repackaging,
// and merged with our dependencies' rules.
jarjarRenameRules map[string]string
+
+ stubsLinkType StubsLinkType
}
func (j *Module) CheckStableSdkVersion(ctx android.BaseModuleContext) error {
@@ -1212,6 +1221,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
ExportedPlugins: j.exportedPluginJars,
ExportedPluginClasses: j.exportedPluginClasses,
ExportedPluginDisableTurbine: j.exportedDisableTurbine,
+ StubsLinkType: j.stubsLinkType,
})
j.outputFile = j.headerJarFile
@@ -1729,6 +1739,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
ExportedPluginClasses: j.exportedPluginClasses,
ExportedPluginDisableTurbine: j.exportedDisableTurbine,
JacocoReportClassesFile: j.jacocoReportClassesFile,
+ StubsLinkType: j.stubsLinkType,
})
// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
@@ -2372,11 +2383,26 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
// classes until a module with jarjar_prefix is reached, and all as yet unrenamed classes will then
// be renamed from that module.
// TODO: Add another property to suppress the forwarding of
+type DependencyUse int
+
+const (
+ RenameUseInvalid DependencyUse = iota
+ RenameUseInclude
+ RenameUseExclude
+)
+
+type RenameUseElement struct {
+ DepName string
+ RenameUse DependencyUse
+ Why string // token for determining where in the logic the decision was made.
+}
+
type JarJarProviderData struct {
// Mapping of class names: original --> renamed. If the value is "", the class will be
// renamed by the next rdep that has the jarjar_prefix attribute (or this module if it has
// attribute). Rdeps of that module will inherit the renaming.
- Rename map[string]string
+ Rename map[string]string
+ RenameUse []RenameUseElement
}
func (this JarJarProviderData) GetDebugString() string {
@@ -2440,17 +2466,112 @@ func (module *Module) addJarJarRenameRule(original string, renamed string) {
func collectDirectDepsProviders(ctx android.ModuleContext) (result *JarJarProviderData) {
// Gather repackage information from deps
// If the dep jas a JarJarProvider, it is used. Otherwise, any BaseJarJarProvider is used.
+
+ module := ctx.Module()
+ moduleName := module.Name()
+
ctx.VisitDirectDepsIgnoreBlueprint(func(m android.Module) {
- if ctx.OtherModuleDependencyTag(m) == proguardRaiseTag {
+ tag := ctx.OtherModuleDependencyTag(m)
+ // This logic mirrors that in (*Module).collectDeps above. There are several places
+ // where we explicitly return RenameUseExclude, even though it is the default, to
+ // indicate that it has been verified to be the case.
+ //
+ // Note well: there are probably cases that are getting to the unconditional return
+ // and are therefore wrong.
+ shouldIncludeRenames := func() (DependencyUse, string) {
+ if moduleName == m.Name() {
+ return RenameUseInclude, "name" // If we have the same module name, include the renames.
+ }
+ if sc, ok := module.(android.SdkContext); ok {
+ if ctx.Device() {
+ sdkDep := decodeSdkDep(ctx, sc)
+ if !sdkDep.invalidVersion && sdkDep.useFiles {
+ return RenameUseExclude, "useFiles"
+ }
+ }
+ }
+ if IsJniDepTag(tag) || tag == certificateTag || tag == proguardRaiseTag {
+ return RenameUseExclude, "tags"
+ }
+ if _, ok := m.(SdkLibraryDependency); ok {
+ switch tag {
+ case sdkLibTag, libTag:
+ return RenameUseExclude, "sdklibdep" // matches collectDeps()
+ }
+ return RenameUseInvalid, "sdklibdep" // dep is not used in collectDeps()
+ } else if ji, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
+ switch ji.StubsLinkType {
+ case Stubs:
+ return RenameUseExclude, "info"
+ case Implementation:
+ return RenameUseInclude, "info"
+ default:
+ //fmt.Printf("LJ: %v -> %v StubsLinkType unknown\n", module, m)
+ // Fall through to the heuristic logic.
+ }
+ switch reflect.TypeOf(m).String() {
+ case "*java.GeneratedJavaLibraryModule":
+ // Probably a java_aconfig_library module.
+ // TODO: make this check better.
+ return RenameUseInclude, "reflect"
+ }
+ switch tag {
+ case bootClasspathTag:
+ return RenameUseExclude, "tagswitch"
+ case sdkLibTag, libTag, instrumentationForTag:
+ return RenameUseInclude, "tagswitch"
+ case java9LibTag:
+ return RenameUseExclude, "tagswitch"
+ case staticLibTag:
+ return RenameUseInclude, "tagswitch"
+ case pluginTag:
+ return RenameUseInclude, "tagswitch"
+ case errorpronePluginTag:
+ return RenameUseInclude, "tagswitch"
+ case exportedPluginTag:
+ return RenameUseInclude, "tagswitch"
+ case kotlinStdlibTag, kotlinAnnotationsTag:
+ return RenameUseExclude, "tagswitch"
+ case kotlinPluginTag:
+ return RenameUseInclude, "tagswitch"
+ default:
+ return RenameUseExclude, "tagswitch"
+ }
+ } else if _, ok := m.(android.SourceFileProducer); ok {
+ switch tag {
+ case sdkLibTag, libTag, staticLibTag:
+ return RenameUseInclude, "srcfile"
+ default:
+ return RenameUseExclude, "srcfile"
+ }
+ } else {
+ switch tag {
+ case bootClasspathTag:
+ return RenameUseExclude, "else"
+ case systemModulesTag:
+ return RenameUseInclude, "else"
+ }
+ }
+ // If we got here, choose the safer option, which may lead to a build failure, rather
+ // than runtime failures on the device.
+ return RenameUseExclude, "end"
+ }
+
+ if result == nil {
+ result = &JarJarProviderData{
+ Rename: make(map[string]string),
+ RenameUse: make([]RenameUseElement, 0),
+ }
+ }
+ how, why := shouldIncludeRenames()
+ result.RenameUse = append(result.RenameUse, RenameUseElement{DepName: m.Name(), RenameUse: how, Why: why})
+ if how != RenameUseInclude {
+ // Nothing to merge.
return
}
+
merge := func(theirs *JarJarProviderData) {
for orig, renamed := range theirs.Rename {
- if result == nil {
- result = &JarJarProviderData{
- Rename: make(map[string]string),
- }
- }
if preexisting, exists := (*result).Rename[orig]; !exists || preexisting == "" {
result.Rename[orig] = renamed
} else if preexisting != "" && renamed != "" && preexisting != renamed {