Remove duplicate component from sdk snapshot

Previously, an sdk snapshot could contain the following:
* A java_sdk_library_import module, e.g. "foo" which creates component
  modules "foo.stubs", etc.
* A corresponding versioned module, e.g. "sdk_foo@current" which
  created component modules "sdk_foo@current.stubs", etc.
* An internal (to the sdk snapshot) java_import for one of "foo"'s
  components, e.g. "sdk_foo.stubs"
* A corresponding versioned module, e.g. "sdk_foo.stubs@current".

That causes a few problems:
1. The "foo.stubs" is duplicated.
2. The names of the components created by the versioned
   java_sdk_library_import are invalid, as they append the component's
   suffix to the version and not the name before the version.

The latter causes problems when building against prebuilts and fixing
that causes the generated snapshot to be invalid because it contains
duplicate definitions of the "sdk_foo.stubs@current" module. One
explicitly in the Android.bp file and one created by the
"sdk_foo@current" module.

Removing the duplicates from the snapshot causes errors as the name
generated by the snapshot for the component module, i.e.
"sdk_foo.stubs@current" does not match the name generated by the
"sdk_foo@current", i.e. "sdk_foo@current.stubs".

This change fixes them together.

Bug: 179354495
Test: m nothing
Merged-In: I515f235fe21755b5275af12366e96c24c94c0273
Change-Id: I515f235fe21755b5275af12366e96c24c94c0273
(cherry picked from commit a1aa7387f74a49c8c974ba2198def0e081488624)
diff --git a/android/sdk.go b/android/sdk.go
index 93beb6e..5c58612 100644
--- a/android/sdk.go
+++ b/android/sdk.go
@@ -38,6 +38,36 @@
 type sdkAwareWithoutModule interface {
 	RequiredSdks
 
+	// SdkMemberComponentName will return the name to use for a component of this module based on the
+	// base name of this module.
+	//
+	// The baseName is the name returned by ModuleBase.BaseModuleName(), i.e. the name specified in
+	// the name property in the .bp file so will not include the prebuilt_ prefix.
+	//
+	// The componentNameCreator is a func for creating the name of a component from the base name of
+	// the module, e.g. it could just append ".component" to the name passed in.
+	//
+	// This is intended to be called by prebuilt modules that create component models. It is because
+	// prebuilt module base names come in a variety of different forms:
+	// * unversioned - this is the same as the source module.
+	// * internal to an sdk - this is the unversioned name prefixed by the base name of the sdk
+	//   module.
+	// * versioned - this is the same as the internal with the addition of an "@<version>" suffix.
+	//
+	// While this can be called from a source module in that case it will behave the same way as the
+	// unversioned name and return the result of calling the componentNameCreator func on the supplied
+	// base name.
+	//
+	// e.g. Assuming the componentNameCreator func simply appends ".component" to the name passed in
+	// then this will work as follows:
+	// * An unversioned name of "foo" will return "foo.component".
+	// * An internal to the sdk name of "sdk_foo" will return "sdk_foo.component".
+	// * A versioned name of "sdk_foo@current" will return "sdk_foo.component@current".
+	//
+	// Note that in the latter case the ".component" suffix is added before the version. Adding it
+	// after would change the version.
+	SdkMemberComponentName(baseName string, componentNameCreator func(string) string) string
+
 	sdkBase() *SdkBase
 	MakeMemberOf(sdk SdkRef)
 	IsInAnySdk() bool
@@ -135,6 +165,18 @@
 	return s
 }
 
+func (s *SdkBase) SdkMemberComponentName(baseName string, componentNameCreator func(string) string) string {
+	if s.MemberName() == "" {
+		return componentNameCreator(baseName)
+	} else {
+		index := strings.LastIndex(baseName, "@")
+		unversionedName := baseName[:index]
+		unversionedComponentName := componentNameCreator(unversionedName)
+		versionSuffix := baseName[index:]
+		return unversionedComponentName + versionSuffix
+	}
+}
+
 // MakeMemberOf sets this module to be a member of a specific SDK
 func (s *SdkBase) MakeMemberOf(sdk SdkRef) {
 	s.properties.ContainingSdk = &sdk
@@ -659,3 +701,30 @@
 	// into which to copy the prebuilt files.
 	Name() string
 }
+
+// ExportedComponentsInfo contains information about the components that this module exports to an
+// sdk snapshot.
+//
+// A component of a module is a child module that the module creates and which forms an integral
+// part of the functionality that the creating module provides. A component module is essentially
+// owned by its creator and is tightly coupled to the creator and other components.
+//
+// e.g. the child modules created by prebuilt_apis are not components because they are not tightly
+// coupled to the prebuilt_apis module. Once they are created the prebuilt_apis ignores them. The
+// child impl and stub library created by java_sdk_library (and corresponding import) are components
+// because the creating module depends upon them in order to provide some of its own functionality.
+//
+// A component is exported if it is part of an sdk snapshot. e.g. The xml and impl child modules are
+// components but they are not exported as they are not part of an sdk snapshot.
+//
+// This information is used by the sdk snapshot generation code to ensure that it does not create
+// an sdk snapshot that contains a declaration of the component module and the module that creates
+// it as that would result in duplicate modules when attempting to use the snapshot. e.g. a snapshot
+// that included the java_sdk_library_import "foo" and also a java_import "foo.stubs" would fail
+// as there would be two modules called "foo.stubs".
+type ExportedComponentsInfo struct {
+	// The names of the exported components.
+	Components []string
+}
+
+var ExportedComponentsInfoProvider = blueprint.NewProvider(ExportedComponentsInfo{})