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

Commit 539b46b6 authored by Jihoon Kang's avatar Jihoon Kang Committed by Gerrit Code Review
Browse files

Merge "Generate "exportable" stubs library in java_sdk_library" into main

parents 0d2afbbf fa4a90d4
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -1329,7 +1329,9 @@ type PrebuiltStubsSources struct {

func (p *PrebuiltStubsSources) OutputFiles(tag string) (android.Paths, error) {
	switch tag {
	case "":
	// prebuilt droidstubs does not output "exportable" stubs.
	// Output the "everything" stubs srcjar file if the tag is ".exportable".
	case "", ".exportable":
		return android.Paths{p.stubsSrcJar}, nil
	default:
		return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+132 −62
Original line number Diff line number Diff line
@@ -231,6 +231,10 @@ func (scope *apiScope) stubsLibraryModuleNameSuffix() string {
	return ".stubs" + scope.moduleSuffix
}

func (scope *apiScope) exportableStubsLibraryModuleNameSuffix() string {
	return ".stubs.exportable" + scope.moduleSuffix
}

func (scope *apiScope) apiLibraryModuleName(baseName string) string {
	return scope.stubsLibraryModuleName(baseName) + ".from-text"
}
@@ -239,10 +243,18 @@ func (scope *apiScope) sourceStubLibraryModuleName(baseName string) string {
	return scope.stubsLibraryModuleName(baseName) + ".from-source"
}

func (scope *apiScope) exportableSourceStubsLibraryModuleName(baseName string) string {
	return scope.exportableStubsLibraryModuleName(baseName) + ".from-source"
}

func (scope *apiScope) stubsLibraryModuleName(baseName string) string {
	return baseName + scope.stubsLibraryModuleNameSuffix()
}

func (scope *apiScope) exportableStubsLibraryModuleName(baseName string) string {
	return baseName + scope.exportableStubsLibraryModuleNameSuffix()
}

func (scope *apiScope) stubsSourceModuleName(baseName string) string {
	return baseName + ".stubs.source" + scope.moduleSuffix
}
@@ -895,6 +907,12 @@ func (c *commonToSdkLibraryAndImport) stubsLibraryModuleName(apiScope *apiScope)
	return c.namingScheme.stubsLibraryModuleName(apiScope, baseName)
}

// Name of the java_library module that compiles the exportable stubs source.
func (c *commonToSdkLibraryAndImport) exportableStubsLibraryModuleName(apiScope *apiScope) string {
	baseName := c.module.BaseModuleName()
	return c.namingScheme.exportableStubsLibraryModuleName(apiScope, baseName)
}

// Name of the droidstubs module that generates the stubs source and may also
// generate/check the API.
func (c *commonToSdkLibraryAndImport) stubsSourceModuleName(apiScope *apiScope) string {
@@ -911,9 +929,16 @@ func (c *commonToSdkLibraryAndImport) apiLibraryModuleName(apiScope *apiScope) s

// Name of the java_library module that compiles the stubs
// generated from source Java files.
func (c *commonToSdkLibraryAndImport) sourceStubLibraryModuleName(apiScope *apiScope) string {
func (c *commonToSdkLibraryAndImport) sourceStubsLibraryModuleName(apiScope *apiScope) string {
	baseName := c.module.BaseModuleName()
	return c.namingScheme.sourceStubsLibraryModuleName(apiScope, baseName)
}

// Name of the java_library module that compiles the exportable stubs
// generated from source Java files.
func (c *commonToSdkLibraryAndImport) exportableSourceStubsLibraryModuleName(apiScope *apiScope) string {
	baseName := c.module.BaseModuleName()
	return c.namingScheme.sourceStubLibraryModuleName(apiScope, baseName)
	return c.namingScheme.exportableSourceStubsLibraryModuleName(apiScope, baseName)
}

// The component names for different outputs of the java_sdk_library.
@@ -1629,9 +1654,7 @@ func (module *SdkLibrary) createImplLibrary(mctx android.DefaultableHookContext)
	mctx.CreateModule(LibraryFactory, properties...)
}

// Creates a static java library that has API stubs
func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) {
	props := struct {
type libraryProperties struct {
	Name           *string
	Visibility     []string
	Srcs           []string
@@ -1653,12 +1676,12 @@ func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext
		Dir     *string
		Tag     *string
	}
	}{}
}

	props.Name = proptools.StringPtr(module.sourceStubLibraryModuleName(apiScope))
func (module *SdkLibrary) stubsLibraryProps(mctx android.DefaultableHookContext, apiScope *apiScope) libraryProperties {
	props := libraryProperties{}
	props.Visibility = []string{"//visibility:override", "//visibility:private"}
	// sources are generated from the droiddoc
	props.Srcs = []string{":" + module.stubsSourceModuleName(apiScope)}
	sdkVersion := module.sdkVersionForStubsLibrary(mctx, apiScope)
	props.Sdk_version = proptools.StringPtr(sdkVersion)
	props.System_modules = module.deviceProperties.System_modules
@@ -1678,6 +1701,25 @@ func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext
	// interop with older developer tools that don't support 1.9.
	props.Java_version = proptools.StringPtr("1.8")

	return props
}

// Creates a static java library that has API stubs
func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) {

	props := module.stubsLibraryProps(mctx, apiScope)
	props.Name = proptools.StringPtr(module.sourceStubsLibraryModuleName(apiScope))
	props.Srcs = []string{":" + module.stubsSourceModuleName(apiScope)}

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

// Create a static java library that compiles the "exportable" stubs
func (module *SdkLibrary) createExportableStubsLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) {
	props := module.stubsLibraryProps(mctx, apiScope)
	props.Name = proptools.StringPtr(module.exportableSourceStubsLibraryModuleName(apiScope))
	props.Srcs = []string{":" + module.stubsSourceModuleName(apiScope) + "{.exportable}"}

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

@@ -1908,36 +1950,49 @@ func (module *SdkLibrary) createApiLibrary(mctx android.DefaultableHookContext,
	mctx.CreateModule(ApiLibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}

func (module *SdkLibrary) createTopLevelStubsLibrary(
	mctx android.DefaultableHookContext, apiScope *apiScope, contributesToApiSurface bool) {
	props := struct {
		Name           *string
		Visibility     []string
		Sdk_version    *string
		Static_libs    []string
		System_modules *string
		Dist           struct {
			Targets []string
			Dest    *string
			Dir     *string
			Tag     *string
		}
		Compile_dex *bool
	}{}
	props.Name = proptools.StringPtr(module.stubsLibraryModuleName(apiScope))
func (module *SdkLibrary) topLevelStubsLibraryProps(mctx android.DefaultableHookContext, apiScope *apiScope) libraryProperties {
	props := libraryProperties{}

	props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_library_visibility)
	sdkVersion := module.sdkVersionForStubsLibrary(mctx, apiScope)
	props.Sdk_version = proptools.StringPtr(sdkVersion)

	props.System_modules = module.deviceProperties.System_modules

	// The imports need to be compiled to dex if the java_sdk_library requests it.
	compileDex := module.dexProperties.Compile_dex
	if module.stubLibrariesCompiledForDex() {
		compileDex = proptools.BoolPtr(true)
	}
	props.Compile_dex = compileDex

	return props
}

func (module *SdkLibrary) createTopLevelStubsLibrary(
	mctx android.DefaultableHookContext, apiScope *apiScope, contributesToApiSurface bool) {

	props := module.topLevelStubsLibraryProps(mctx, apiScope)
	props.Name = proptools.StringPtr(module.stubsLibraryModuleName(apiScope))

	// Add the stub compiling java_library/java_api_library as static lib based on build config
	staticLib := module.sourceStubLibraryModuleName(apiScope)
	staticLib := module.sourceStubsLibraryModuleName(apiScope)
	if mctx.Config().BuildFromTextStub() && contributesToApiSurface {
		staticLib = module.apiLibraryModuleName(apiScope)
	}
	props.Static_libs = append(props.Static_libs, staticLib)
	props.System_modules = module.deviceProperties.System_modules

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

func (module *SdkLibrary) createTopLevelExportableStubsLibrary(
	mctx android.DefaultableHookContext, apiScope *apiScope) {

	props := module.topLevelStubsLibraryProps(mctx, apiScope)
	props.Name = proptools.StringPtr(module.exportableStubsLibraryModuleName(apiScope))

	// Dist the class jar artifact for sdk builds.
	// "exportable" stubs are copied to dist for sdk builds instead of the "everything" stubs.
	if !Bool(module.sdkLibraryProperties.No_dist) {
		props.Dist.Targets = []string{"sdk", "win_sdk"}
		props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.jar", module.distStem()))
@@ -1945,12 +2000,8 @@ func (module *SdkLibrary) createTopLevelStubsLibrary(
		props.Dist.Tag = proptools.StringPtr(".jar")
	}

	// The imports need to be compiled to dex if the java_sdk_library requests it.
	compileDex := module.dexProperties.Compile_dex
	if module.stubLibrariesCompiledForDex() {
		compileDex = proptools.BoolPtr(true)
	}
	props.Compile_dex = compileDex
	staticLib := module.exportableSourceStubsLibraryModuleName(apiScope)
	props.Static_libs = append(props.Static_libs, staticLib)

	mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}
@@ -2157,6 +2208,7 @@ func (module *SdkLibrary) CreateInternalModules(mctx android.DefaultableHookCont
		module.createStubsSourcesAndApi(mctx, scope, module.stubsSourceModuleName(scope), scope.droidstubsArgs)

		module.createStubsLibrary(mctx, scope)
		module.createExportableStubsLibrary(mctx, scope)

		alternativeFullApiSurfaceStubLib := ""
		if scope == apiScopePublic {
@@ -2168,6 +2220,7 @@ func (module *SdkLibrary) CreateInternalModules(mctx android.DefaultableHookCont
		}

		module.createTopLevelStubsLibrary(mctx, scope, contributesToApiSurface)
		module.createTopLevelExportableStubsLibrary(mctx, scope)
	}

	if module.requiresRuntimeImplementationLibrary() {
@@ -2223,7 +2276,11 @@ type sdkLibraryComponentNamingScheme interface {

	apiLibraryModuleName(scope *apiScope, baseName string) string

	sourceStubLibraryModuleName(scope *apiScope, baseName string) string
	sourceStubsLibraryModuleName(scope *apiScope, baseName string) string

	exportableStubsLibraryModuleName(scope *apiScope, baseName string) string

	exportableSourceStubsLibraryModuleName(scope *apiScope, baseName string) string
}

type defaultNamingScheme struct {
@@ -2241,34 +2298,47 @@ func (s *defaultNamingScheme) apiLibraryModuleName(scope *apiScope, baseName str
	return scope.apiLibraryModuleName(baseName)
}

func (s *defaultNamingScheme) sourceStubLibraryModuleName(scope *apiScope, baseName string) string {
func (s *defaultNamingScheme) sourceStubsLibraryModuleName(scope *apiScope, baseName string) string {
	return scope.sourceStubLibraryModuleName(baseName)
}

func (s *defaultNamingScheme) exportableStubsLibraryModuleName(scope *apiScope, baseName string) string {
	return scope.exportableStubsLibraryModuleName(baseName)
}

func (s *defaultNamingScheme) exportableSourceStubsLibraryModuleName(scope *apiScope, baseName string) string {
	return scope.exportableSourceStubsLibraryModuleName(baseName)
}

var _ sdkLibraryComponentNamingScheme = (*defaultNamingScheme)(nil)

func hasStubsLibrarySuffix(name string, apiScope *apiScope) bool {
	return strings.HasSuffix(name, apiScope.stubsLibraryModuleNameSuffix()) ||
		strings.HasSuffix(name, apiScope.exportableStubsLibraryModuleNameSuffix())
}

func moduleStubLinkType(name string) (stub bool, ret sdkLinkType) {
	name = strings.TrimSuffix(name, ".from-source")

	// This suffix-based approach is fragile and could potentially mis-trigger.
	// TODO(b/155164730): Clean this up when modules no longer reference sdk_lib stubs directly.
	if strings.HasSuffix(name, apiScopePublic.stubsLibraryModuleNameSuffix()) {
	if hasStubsLibrarySuffix(name, apiScopePublic) {
		if name == "hwbinder.stubs" || name == "libcore_private.stubs" {
			// Due to a previous bug, these modules were not considered stubs, so we retain that.
			return false, javaPlatform
		}
		return true, javaSdk
	}
	if strings.HasSuffix(name, apiScopeSystem.stubsLibraryModuleNameSuffix()) {
	if hasStubsLibrarySuffix(name, apiScopeSystem) {
		return true, javaSystem
	}
	if strings.HasSuffix(name, apiScopeModuleLib.stubsLibraryModuleNameSuffix()) {
	if hasStubsLibrarySuffix(name, apiScopeModuleLib) {
		return true, javaModule
	}
	if strings.HasSuffix(name, apiScopeTest.stubsLibraryModuleNameSuffix()) {
	if hasStubsLibrarySuffix(name, apiScopeTest) {
		return true, javaSystem
	}
	if strings.HasSuffix(name, apiScopeSystemServer.stubsLibraryModuleNameSuffix()) {
	if hasStubsLibrarySuffix(name, apiScopeSystemServer) {
		return true, javaSystemServer
	}
	return false, javaPlatform
+54 −1
Original line number Diff line number Diff line
@@ -1423,7 +1423,7 @@ func TestJavaSdkLibraryDist(t *testing.T) {

	for _, tt := range testCases {
		t.Run(tt.module, func(t *testing.T) {
			m := result.ModuleForTests(tt.module+".stubs", "android_common").Module().(*Library)
			m := result.ModuleForTests(apiScopePublic.exportableStubsLibraryModuleName(tt.module), "android_common").Module().(*Library)
			dists := m.Dists()
			if len(dists) != 1 {
				t.Fatalf("expected exactly 1 dist entry, got %d", len(dists))
@@ -1693,3 +1693,56 @@ func TestSdkLibraryDependency(t *testing.T) {

	android.AssertStringDoesContain(t, "bar.xml java_sdk_xml command", barPermissions.RuleParams.Command, `dependency=\"foo\"`)
}

func TestSdkLibraryExportableStubsLibrary(t *testing.T) {
	result := android.GroupFixturePreparers(
		prepareForJavaTest,
		PrepareForTestWithJavaSdkLibraryFiles,
		FixtureWithLastReleaseApis("foo"),
		android.FixtureModifyConfig(func(config android.Config) {
			config.SetApiLibraries([]string{"foo"})
		}),
	).RunTestWithBp(t, `
		aconfig_declarations {
			name: "bar",
			package: "com.example.package",
			srcs: [
				"bar.aconfig",
			],
		}
		java_sdk_library {
			name: "foo",
			srcs: ["a.java", "b.java"],
			api_packages: ["foo"],
			system: {
				enabled: true,
			},
			module_lib: {
				enabled: true,
			},
			test: {
				enabled: true,
			},
			aconfig_declarations: [
				"bar",
			],
		}
	`)

	exportableStubsLibraryModuleName := apiScopePublic.exportableStubsLibraryModuleName("foo")
	exportableSourceStubsLibraryModuleName := apiScopePublic.exportableSourceStubsLibraryModuleName("foo")

	// Check modules generation
	topLevelModule := result.ModuleForTests(exportableStubsLibraryModuleName, "android_common")
	result.ModuleForTests(exportableSourceStubsLibraryModuleName, "android_common")

	// Check static lib dependency
	android.AssertBoolEquals(t, "exportable top level stubs library module depends on the"+
		"exportable source stubs library module", true,
		CheckModuleHasDependency(t, result.TestContext, exportableStubsLibraryModuleName,
			"android_common", exportableSourceStubsLibraryModuleName),
	)
	android.AssertArrayString(t, "exportable source stub library is a static lib of the"+
		"top level exportable stubs library", []string{exportableSourceStubsLibraryModuleName},
		topLevelModule.Module().(*Library).properties.Static_libs)
}