java_sdk_library: Delegate component module to naming scheme

Adds a naming scheme abstraction to which the java_sdk_library/import
will delegate the task of creating the names of their component
modules. The naming scheme can be selected in a module definition but
for now the only supported option is "default".

Test: m nothing
Bug: 155480189
Change-Id: I708657661188ea4a14a4dd8c6bc4b46237bbe5e0
diff --git a/java/sdk_library.go b/java/sdk_library.go
index dfda612..68623e9 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -474,6 +474,15 @@
 }
 
 type commonToSdkLibraryAndImportProperties struct {
+	// The naming scheme to use for the components that this module creates.
+	//
+	// If not specified then it defaults to "default", which is currently the only
+	// allowable value.
+	//
+	// This is a temporary mechanism to simplify conversion from separate modules for each
+	// component that follow a different naming pattern to the default one.
+	//
+	// TODO(b/155480189) - Remove once naming inconsistencies have been resolved.
 	Naming_scheme *string
 }
 
@@ -482,27 +491,46 @@
 	moduleBase *android.ModuleBase
 
 	scopePaths map[*apiScope]*scopePaths
+
+	namingScheme sdkLibraryComponentNamingScheme
+
+	commonProperties commonToSdkLibraryAndImportProperties
 }
 
 func (c *commonToSdkLibraryAndImport) initCommon(moduleBase *android.ModuleBase) {
 	c.moduleBase = moduleBase
+
+	moduleBase.AddProperties(&c.commonProperties)
+}
+
+func (c *commonToSdkLibraryAndImport) initCommonAfterDefaultsApplied(ctx android.DefaultableHookContext) bool {
+	schemeProperty := proptools.StringDefault(c.commonProperties.Naming_scheme, "default")
+	switch schemeProperty {
+	case "default":
+		c.namingScheme = &defaultNamingScheme{}
+	default:
+		ctx.PropertyErrorf("naming_scheme", "expected 'default' but was %q", schemeProperty)
+		return false
+	}
+
+	return true
 }
 
 // Name of the java_library module that compiles the stubs source.
 func (c *commonToSdkLibraryAndImport) stubsLibraryModuleName(apiScope *apiScope) string {
-	return apiScope.stubsLibraryModuleName(c.moduleBase.BaseModuleName())
+	return c.namingScheme.stubsLibraryModuleName(apiScope, c.moduleBase.BaseModuleName())
 }
 
 // Name of the droidstubs module that generates the stubs source and may also
 // generate/check the API.
 func (c *commonToSdkLibraryAndImport) stubsSourceModuleName(apiScope *apiScope) string {
-	return apiScope.stubsSourceModuleName(c.moduleBase.BaseModuleName())
+	return c.namingScheme.stubsSourceModuleName(apiScope, c.moduleBase.BaseModuleName())
 }
 
 // Name of the droidstubs module that generates/checks the API. Only used if it
 // requires different arts to the stubs source generating module.
 func (c *commonToSdkLibraryAndImport) apiModuleName(apiScope *apiScope) string {
-	return apiScope.apiModuleName(c.moduleBase.BaseModuleName())
+	return c.namingScheme.apiModuleName(apiScope, c.moduleBase.BaseModuleName())
 }
 
 func (c *commonToSdkLibraryAndImport) getScopePaths(scope *apiScope) *scopePaths {
@@ -1149,6 +1177,32 @@
 	module.Library.Module.deviceProperties.IsSDKLibrary = true
 }
 
+// Defines how to name the individual component modules the sdk library creates.
+type sdkLibraryComponentNamingScheme interface {
+	stubsLibraryModuleName(scope *apiScope, baseName string) string
+
+	stubsSourceModuleName(scope *apiScope, baseName string) string
+
+	apiModuleName(scope *apiScope, baseName string) string
+}
+
+type defaultNamingScheme struct {
+}
+
+func (s *defaultNamingScheme) stubsLibraryModuleName(scope *apiScope, baseName string) string {
+	return scope.stubsLibraryModuleName(baseName)
+}
+
+func (s *defaultNamingScheme) stubsSourceModuleName(scope *apiScope, baseName string) string {
+	return scope.stubsSourceModuleName(baseName)
+}
+
+func (s *defaultNamingScheme) apiModuleName(scope *apiScope, baseName string) string {
+	return scope.apiModuleName(baseName)
+}
+
+var _ sdkLibraryComponentNamingScheme = (*defaultNamingScheme)(nil)
+
 // java_sdk_library is a special Java library that provides optional platform APIs to apps.
 // In practice, it can be viewed as a combination of several modules: 1) stubs library that clients
 // are linked against to, 2) droiddoc module that internally generates API stubs source files,
@@ -1175,7 +1229,11 @@
 	android.AddVisibilityProperty(module, "stubs_library_visibility", &module.sdkLibraryProperties.Stubs_library_visibility)
 	android.AddVisibilityProperty(module, "stubs_source_visibility", &module.sdkLibraryProperties.Stubs_source_visibility)
 
-	module.SetDefaultableHook(func(ctx android.DefaultableHookContext) { module.CreateInternalModules(ctx) })
+	module.SetDefaultableHook(func(ctx android.DefaultableHookContext) {
+		if module.initCommonAfterDefaultsApplied(ctx) {
+			module.CreateInternalModules(ctx)
+		}
+	})
 	return module
 }
 
@@ -1279,7 +1337,11 @@
 	android.InitSdkAwareModule(module)
 	InitJavaModule(module, android.HostAndDeviceSupported)
 
-	module.SetDefaultableHook(func(mctx android.DefaultableHookContext) { module.createInternalModules(mctx) })
+	module.SetDefaultableHook(func(mctx android.DefaultableHookContext) {
+		if module.initCommonAfterDefaultsApplied(mctx) {
+			module.createInternalModules(mctx)
+		}
+	})
 	return module
 }