Improve determination whether to propagate JarJarProvider

Add more explicit checks to not propagate JarJarProvider when we will be
linking against stubs.

Bug: b/310504781
Test: treehugger
Merged-In: I3219d0bf7e84a386b16b248314f11b4e9edcd0fa
Change-Id: I3219d0bf7e84a386b16b248314f11b4e9edcd0fa
This commit is contained in:
LaMont Jones
2024-02-08 14:30:45 -08:00
parent fe914ed17f
commit 63683e40c4

View File

@@ -2383,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 {
@@ -2451,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 {
return
}
merge := func(theirs *JarJarProviderData) {
for orig, renamed := range theirs.Rename {
if result == nil {
result = &JarJarProviderData{
Rename: make(map[string]string),
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 preexisting, exists := (*result).Rename[orig]; !exists || preexisting == "" {
result.Rename[orig] = renamed
} else if preexisting != "" && renamed != "" && preexisting != renamed {