Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b45200bd authored by LaMont Jones's avatar LaMont Jones Committed by Gerrit Code Review
Browse files

Merge changes from topic "is_stubs_module" into main

* changes:
  Improve determination whether to propagate JarJarProvider
  Introduce library property is_stubs_module
parents e48bcc2a 63683e40
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import (

	"android/soong/android"
	"android/soong/dexpreopt"

	"github.com/google/blueprint"
	"github.com/google/blueprint/proptools"
)
@@ -1245,6 +1246,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
		TransitiveStaticLibsHeaderJars: a.transitiveStaticLibsHeaderJars,
		ImplementationAndResourcesJars: android.PathsIfNonNil(a.classpathFile),
		ImplementationJars:             android.PathsIfNonNil(a.classpathFile),
		StubsLinkType:                  Implementation,
		// TransitiveAconfigFiles: // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
	})

+128 −7
Original line number Diff line number Diff line
@@ -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
	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 {
			return
		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.
			}
		merge := func(theirs *JarJarProviderData) {
			for orig, renamed := range theirs.Rename {
			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 {
+1 −0
Original line number Diff line number Diff line
@@ -137,6 +137,7 @@ func (d *DeviceHostConverter) GenerateAndroidBuildActions(ctx android.ModuleCont
		ResourceJars:                   d.resourceJars,
		SrcJarArgs:                     d.srcJarArgs,
		SrcJarDeps:                     d.srcJarDeps,
		StubsLinkType:                  Implementation,
		// TODO: Not sure if aconfig flags that have been moved between device and host variants
		// make sense.
	})
+37 −0
Original line number Diff line number Diff line
@@ -87,6 +87,14 @@ func RegisterJavaSdkMemberTypes() {
	android.RegisterSdkMemberType(javaTestSdkMemberType)
}

type StubsLinkType int

const (
	Unknown StubsLinkType = iota
	Stubs
	Implementation
)

var (
	// Supports adding java header libraries to module_exports and sdk.
	javaHeaderLibsSdkMemberType = &librarySdkMemberType{
@@ -296,6 +304,11 @@ type JavaInfo struct {
	// JacocoReportClassesFile is the path to a jar containing uninstrumented classes that will be
	// instrumented by jacoco.
	JacocoReportClassesFile android.Path

	// StubsLinkType provides information about whether the provided jars are stub jars or
	// implementation jars. If the provider is set by java_sdk_library, the link type is "unknown"
	// and selection between the stub jar vs implementation jar is deferred to SdkLibrary.sdkJars(...)
	StubsLinkType StubsLinkType
}

var JavaInfoProvider = blueprint.NewProvider[JavaInfo]()
@@ -694,6 +707,17 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	j.minSdkVersion = j.MinSdkVersion(ctx)
	j.maxSdkVersion = j.MaxSdkVersion(ctx)

	// SdkLibrary.GenerateAndroidBuildActions(ctx) sets the stubsLinkType to Unknown.
	// If the stubsLinkType has already been set to Unknown, the stubsLinkType should
	// not be overridden.
	if j.stubsLinkType != Unknown {
		if proptools.Bool(j.properties.Is_stubs_module) {
			j.stubsLinkType = Stubs
		} else {
			j.stubsLinkType = Implementation
		}
	}

	j.stem = proptools.StringDefault(j.overridableDeviceProperties.Stem, ctx.ModuleName())

	proguardSpecInfo := j.collectProguardSpecInfo(ctx)
@@ -2018,6 +2042,7 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
		ImplementationAndResourcesJars: android.PathsIfNonNil(al.stubsJar),
		ImplementationJars:             android.PathsIfNonNil(al.stubsJar),
		AidlIncludeDirs:                android.Paths{},
		StubsLinkType:                  Stubs,
		// No aconfig libraries on api libraries
	})
}
@@ -2102,6 +2127,9 @@ type ImportProperties struct {
	// The name is the undecorated name of the java_sdk_library as it appears in the blueprint file
	// (without any prebuilt_ prefix)
	Created_by_java_sdk_library_name *string `blueprint:"mutated"`

	// Property signifying whether the module provides stubs jar or not.
	Is_stubs_module *bool
}

type Import struct {
@@ -2132,6 +2160,8 @@ type Import struct {

	sdkVersion    android.SdkSpec
	minSdkVersion android.ApiLevel

	stubsLinkType StubsLinkType
}

var _ PermittedPackagesForUpdatableBootJars = (*Import)(nil)
@@ -2226,6 +2256,12 @@ func (j *Import) commonBuildActions(ctx android.ModuleContext) {
	if ctx.Windows() {
		j.HideFromMake()
	}

	if proptools.Bool(j.properties.Is_stubs_module) {
		j.stubsLinkType = Stubs
	} else {
		j.stubsLinkType = Implementation
	}
}

func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -2359,6 +2395,7 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
		ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedClasspathFile),
		ImplementationJars:             android.PathsIfNonNil(j.combinedClasspathFile),
		AidlIncludeDirs:                j.exportAidlIncludeDirs,
		StubsLinkType:                  j.stubsLinkType,
		// TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
	})
}
+6 −0
Original line number Diff line number Diff line
@@ -1572,6 +1572,8 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)

	// Only build an implementation library if required.
	if module.requiresRuntimeImplementationLibrary() {
		// stubsLinkType must be set before calling Library.GenerateAndroidBuildActions
		module.Library.stubsLinkType = Unknown
		module.Library.GenerateAndroidBuildActions(ctx)
	}

@@ -1797,6 +1799,7 @@ type libraryProperties struct {
		Dir     *string
		Tag     *string
	}
	Is_stubs_module *bool
}

func (module *SdkLibrary) stubsLibraryProps(mctx android.DefaultableHookContext, apiScope *apiScope) libraryProperties {
@@ -1821,6 +1824,7 @@ func (module *SdkLibrary) stubsLibraryProps(mctx android.DefaultableHookContext,
	// We compile the stubs for 1.8 in line with the main android.jar stubs, and potential
	// interop with older developer tools that don't support 1.9.
	props.Java_version = proptools.StringPtr("1.8")
	props.Is_stubs_module = proptools.BoolPtr(true)

	return props
}
@@ -2709,6 +2713,7 @@ func (module *SdkLibraryImport) createJavaImportForStubs(mctx android.Defaultabl
		Libs                             []string
		Jars                             []string
		Compile_dex                      *bool
		Is_stubs_module                  *bool

		android.UserSuppliedPrebuiltProperties
	}{}
@@ -2730,6 +2735,7 @@ func (module *SdkLibraryImport) createJavaImportForStubs(mctx android.Defaultabl
		compileDex = proptools.BoolPtr(true)
	}
	props.Compile_dex = compileDex
	props.Is_stubs_module = proptools.BoolPtr(true)

	mctx.CreateModule(ImportFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}