Restrict SdkMemberTypes that can be used with sdk/sdk_snapshot

By default SdkMemberTypes are only supported on module_exports module
type. Support for sdk module type has to be explicitly specified.

The java_header_libs, native_shared_libs and stubs_sources are
supported on sdk. The latter is required to provide the stubs source
for an API specified in java_header_libs as they should be kept in
sync.

Bug: 146341462
Test: m nothing
Change-Id: I19b9e60792780a797458d4a9e489506602b13144
diff --git a/android/sdk.go b/android/sdk.go
index 7956434..9e6ad16 100644
--- a/android/sdk.go
+++ b/android/sdk.go
@@ -237,6 +237,9 @@
 	// The name of the member type property on an sdk module.
 	SdkPropertyName() string
 
+	// True if the member type supports the sdk/sdk_snapshot, false otherwise.
+	UsableWithSdkAndSdkSnapshot() bool
+
 	// Add dependencies from the SDK module to all the variants the member
 	// contributes to the SDK. The exact set of variants required is determined
 	// by the SDK and its properties. The dependencies must be added with the
@@ -262,14 +265,20 @@
 	BuildSnapshot(sdkModuleContext ModuleContext, builder SnapshotBuilder, member SdkMember)
 }
 
+// Base type for SdkMemberType implementations.
 type SdkMemberTypeBase struct {
 	PropertyName string
+	SupportsSdk  bool
 }
 
 func (b *SdkMemberTypeBase) SdkPropertyName() string {
 	return b.PropertyName
 }
 
+func (b *SdkMemberTypeBase) UsableWithSdkAndSdkSnapshot() bool {
+	return b.SupportsSdk
+}
+
 // Encapsulates the information about registered SdkMemberTypes.
 type SdkMemberTypesRegistry struct {
 	// The list of types sorted by property name.
@@ -279,22 +288,8 @@
 	key OnceKey
 }
 
-func (r *SdkMemberTypesRegistry) RegisteredTypes() []SdkMemberType {
-	return r.list
-}
-
-func (r *SdkMemberTypesRegistry) UniqueOnceKey() OnceKey {
-	// Use the pointer to the registry as the unique key.
-	return NewCustomOnceKey(r)
-}
-
-// The set of registered SdkMemberTypes.
-var SdkMemberTypes = &SdkMemberTypesRegistry{}
-
-// Register an SdkMemberType object to allow them to be used in the sdk and sdk_snapshot module
-// types.
-func RegisterSdkMemberType(memberType SdkMemberType) {
-	oldList := SdkMemberTypes.list
+func (r *SdkMemberTypesRegistry) copyAndAppend(memberType SdkMemberType) *SdkMemberTypesRegistry {
+	oldList := r.list
 
 	// Copy the slice just in case this is being read while being modified, e.g. when testing.
 	list := make([]SdkMemberType, 0, len(oldList)+1)
@@ -319,8 +314,33 @@
 	key := NewOnceKey(strings.Join(properties, "|"))
 
 	// Create a new registry so the pointer uniquely identifies the set of registered types.
-	SdkMemberTypes = &SdkMemberTypesRegistry{
+	return &SdkMemberTypesRegistry{
 		list: list,
 		key:  key,
 	}
 }
+
+func (r *SdkMemberTypesRegistry) RegisteredTypes() []SdkMemberType {
+	return r.list
+}
+
+func (r *SdkMemberTypesRegistry) UniqueOnceKey() OnceKey {
+	// Use the pointer to the registry as the unique key.
+	return NewCustomOnceKey(r)
+}
+
+// The set of registered SdkMemberTypes, one for sdk module and one for module_exports.
+var ModuleExportsMemberTypes = &SdkMemberTypesRegistry{}
+var SdkMemberTypes = &SdkMemberTypesRegistry{}
+
+// Register an SdkMemberType object to allow them to be used in the sdk and sdk_snapshot module
+// types.
+func RegisterSdkMemberType(memberType SdkMemberType) {
+	// All member types are usable with module_exports.
+	ModuleExportsMemberTypes = ModuleExportsMemberTypes.copyAndAppend(memberType)
+
+	// Only those that explicitly indicate it are usable with sdk.
+	if memberType.UsableWithSdkAndSdkSnapshot() {
+		SdkMemberTypes = SdkMemberTypes.copyAndAppend(memberType)
+	}
+}
diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go
index 2c18e68..fd5a4da 100644
--- a/cc/library_sdk_member.go
+++ b/cc/library_sdk_member.go
@@ -27,6 +27,7 @@
 var sharedLibrarySdkMemberType = &librarySdkMemberType{
 	SdkMemberTypeBase: android.SdkMemberTypeBase{
 		PropertyName: "native_shared_libs",
+		SupportsSdk:  true,
 	},
 	prebuiltModuleType: "cc_prebuilt_library_shared",
 	linkTypes:          []string{"shared"},
@@ -35,6 +36,7 @@
 var staticLibrarySdkMemberType = &librarySdkMemberType{
 	SdkMemberTypeBase: android.SdkMemberTypeBase{
 		PropertyName: "native_static_libs",
+		SupportsSdk:  true,
 	},
 	prebuiltModuleType: "cc_prebuilt_library_static",
 	linkTypes:          []string{"static"},
diff --git a/java/droiddoc.go b/java/droiddoc.go
index ff3f10a..f62f5f9 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -34,6 +34,9 @@
 	android.RegisterSdkMemberType(&droidStubsSdkMemberType{
 		SdkMemberTypeBase: android.SdkMemberTypeBase{
 			PropertyName: "stubs_sources",
+			// stubs_sources can be used with sdk to provide the source stubs for APIs provided by
+			// the APEX.
+			SupportsSdk: true,
 		},
 	})
 }
diff --git a/java/java.go b/java/java.go
index d0bf9d7..27f69b8 100644
--- a/java/java.go
+++ b/java/java.go
@@ -41,6 +41,7 @@
 		librarySdkMemberType{
 			android.SdkMemberTypeBase{
 				PropertyName: "java_header_libs",
+				SupportsSdk:  true,
 			},
 		},
 	})
diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
index f477445..255ac08 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -500,8 +500,8 @@
 
 func TestSnapshotWithCcStaticLibrary(t *testing.T) {
 	result := testSdkWithCc(t, `
-		sdk {
-			name: "mysdk",
+		module_exports {
+			name: "myexports",
 			native_static_libs: ["mynativelib"],
 		}
 
@@ -520,12 +520,12 @@
 		}
 	`)
 
-	result.CheckSnapshot("mysdk", "android_common", "",
+	result.CheckSnapshot("myexports", "android_common", "",
 		checkAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_static {
-    name: "mysdk_mynativelib@current",
+    name: "myexports_mynativelib@current",
     sdk_member_name: "mynativelib",
     export_include_dirs: ["include/include"],
     arch: {
@@ -560,9 +560,9 @@
     system_shared_libs: [],
 }
 
-sdk_snapshot {
-    name: "mysdk@current",
-    native_static_libs: ["mysdk_mynativelib@current"],
+module_exports_snapshot {
+    name: "myexports@current",
+    native_static_libs: ["myexports_mynativelib@current"],
 }
 `),
 		checkAllCopyRules(`
@@ -584,8 +584,8 @@
 	SkipIfNotLinux(t)
 
 	result := testSdkWithCc(t, `
-		sdk {
-			name: "mysdk",
+		module_exports {
+			name: "myexports",
 			device_supported: false,
 			host_supported: true,
 			native_static_libs: ["mynativelib"],
@@ -608,12 +608,12 @@
 		}
 	`)
 
-	result.CheckSnapshot("mysdk", "linux_glibc_common", "",
+	result.CheckSnapshot("myexports", "linux_glibc_common", "",
 		checkAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_static {
-    name: "mysdk_mynativelib@current",
+    name: "myexports_mynativelib@current",
     sdk_member_name: "mynativelib",
     device_supported: false,
     host_supported: true,
@@ -652,11 +652,11 @@
     system_shared_libs: [],
 }
 
-sdk_snapshot {
-    name: "mysdk@current",
+module_exports_snapshot {
+    name: "myexports@current",
     device_supported: false,
     host_supported: true,
-    native_static_libs: ["mysdk_mynativelib@current"],
+    native_static_libs: ["myexports_mynativelib@current"],
 }
 `),
 		checkAllCopyRules(`
diff --git a/sdk/exports.go b/sdk/exports.go
index c882462..d313057 100644
--- a/sdk/exports.go
+++ b/sdk/exports.go
@@ -24,16 +24,13 @@
 // module_exports defines the exports of a mainline module. The exports are Soong modules
 // which are required by Soong modules that are not part of the mainline module.
 func ModuleExportsFactory() android.Module {
-	s := newSdkModule()
-	s.properties.Module_exports = true
-	return s
+	return newSdkModule(true)
 }
 
 // module_exports_snapshot is a versioned snapshot of prebuilt versions of all the exports
 // of a mainline module.
 func ModuleExportsSnapshotsFactory() android.Module {
-	s := newSdkModule()
+	s := newSdkModule(true)
 	s.properties.Snapshot = true
-	s.properties.Module_exports = true
 	return s
 }
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index 1aa9184..8c72658 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -214,8 +214,8 @@
 
 func TestSnapshotWithJavaImplLibrary(t *testing.T) {
 	result := testSdkWithJava(t, `
-		sdk {
-			name: "mysdk",
+		module_exports {
+			name: "myexports",
 			java_libs: ["myjavalib"],
 		}
 
@@ -232,12 +232,12 @@
 		}
 	`)
 
-	result.CheckSnapshot("mysdk", "android_common", "",
+	result.CheckSnapshot("myexports", "android_common", "",
 		checkAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 java_import {
-    name: "mysdk_myjavalib@current",
+    name: "myexports_myjavalib@current",
     sdk_member_name: "myjavalib",
     jars: ["java/myjavalib.jar"],
 }
@@ -248,9 +248,9 @@
     jars: ["java/myjavalib.jar"],
 }
 
-sdk_snapshot {
-    name: "mysdk@current",
-    java_libs: ["mysdk_myjavalib@current"],
+module_exports_snapshot {
+    name: "myexports@current",
+    java_libs: ["myexports_myjavalib@current"],
 }
 
 `),
@@ -266,8 +266,8 @@
 	SkipIfNotLinux(t)
 
 	result := testSdkWithJava(t, `
-		sdk {
-			name: "mysdk",
+		module_exports {
+			name: "myexports",
 			device_supported: false,
 			host_supported: true,
 			java_libs: ["myjavalib"],
@@ -287,12 +287,12 @@
 		}
 	`)
 
-	result.CheckSnapshot("mysdk", "linux_glibc_common", "",
+	result.CheckSnapshot("myexports", "linux_glibc_common", "",
 		checkAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 java_import {
-    name: "mysdk_myjavalib@current",
+    name: "myexports_myjavalib@current",
     sdk_member_name: "myjavalib",
     device_supported: false,
     host_supported: true,
@@ -307,11 +307,11 @@
     jars: ["java/myjavalib.jar"],
 }
 
-sdk_snapshot {
-    name: "mysdk@current",
+module_exports_snapshot {
+    name: "myexports@current",
     device_supported: false,
     host_supported: true,
-    java_libs: ["mysdk_myjavalib@current"],
+    java_libs: ["myexports_myjavalib@current"],
 }
 `),
 		checkAllCopyRules(`
@@ -366,8 +366,8 @@
 
 func TestSnapshotWithDroidstubs(t *testing.T) {
 	result := testSdkWithDroidstubs(t, `
-		sdk {
-			name: "mysdk",
+		module_exports {
+			name: "myexports",
 			stubs_sources: ["myjavaapistubs"],
 		}
 
@@ -379,12 +379,12 @@
 		}
 	`)
 
-	result.CheckSnapshot("mysdk", "android_common", "",
+	result.CheckSnapshot("myexports", "android_common", "",
 		checkAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 prebuilt_stubs_sources {
-    name: "mysdk_myjavaapistubs@current",
+    name: "myexports_myjavaapistubs@current",
     sdk_member_name: "myjavaapistubs",
     srcs: ["java/myjavaapistubs_stubs_sources"],
 }
@@ -395,14 +395,14 @@
     srcs: ["java/myjavaapistubs_stubs_sources"],
 }
 
-sdk_snapshot {
-    name: "mysdk@current",
-    stubs_sources: ["mysdk_myjavaapistubs@current"],
+module_exports_snapshot {
+    name: "myexports@current",
+    stubs_sources: ["myexports_myjavaapistubs@current"],
 }
 
 `),
 		checkAllCopyRules(""),
-		checkMergeZip(".intermediates/mysdk/android_common/tmp/java/myjavaapistubs_stubs_sources.zip"),
+		checkMergeZip(".intermediates/myexports/android_common/tmp/java/myjavaapistubs_stubs_sources.zip"),
 	)
 }
 
@@ -411,8 +411,8 @@
 	SkipIfNotLinux(t)
 
 	result := testSdkWithDroidstubs(t, `
-		sdk {
-			name: "mysdk",
+		module_exports {
+			name: "myexports",
 			device_supported: false,
 			host_supported: true,
 			stubs_sources: ["myjavaapistubs"],
@@ -428,12 +428,12 @@
 		}
 	`)
 
-	result.CheckSnapshot("mysdk", "linux_glibc_common", "",
+	result.CheckSnapshot("myexports", "linux_glibc_common", "",
 		checkAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 prebuilt_stubs_sources {
-    name: "mysdk_myjavaapistubs@current",
+    name: "myexports_myjavaapistubs@current",
     sdk_member_name: "myjavaapistubs",
     device_supported: false,
     host_supported: true,
@@ -448,14 +448,14 @@
     srcs: ["java/myjavaapistubs_stubs_sources"],
 }
 
-sdk_snapshot {
-    name: "mysdk@current",
+module_exports_snapshot {
+    name: "myexports@current",
     device_supported: false,
     host_supported: true,
-    stubs_sources: ["mysdk_myjavaapistubs@current"],
+    stubs_sources: ["myexports_myjavaapistubs@current"],
 }
 `),
 		checkAllCopyRules(""),
-		checkMergeZip(".intermediates/mysdk/linux_glibc_common/tmp/java/myjavaapistubs_stubs_sources.zip"),
+		checkMergeZip(".intermediates/myexports/linux_glibc_common/tmp/java/myjavaapistubs_stubs_sources.zip"),
 	)
 }
diff --git a/sdk/sdk.go b/sdk/sdk.go
index 42f5503..44e5cbb 100644
--- a/sdk/sdk.go
+++ b/sdk/sdk.go
@@ -133,6 +133,7 @@
 // * a dependency tag that identifies the member type of a resolved dependency.
 //
 func createDynamicSdkMemberTypes(sdkMemberTypes []android.SdkMemberType) *dynamicSdkMemberTypes {
+
 	var listProperties []*sdkMemberListProperty
 	var fields []reflect.StructField
 
@@ -186,13 +187,20 @@
 // sdk defines an SDK which is a logical group of modules (e.g. native libs, headers, java libs, etc.)
 // which Mainline modules like APEX can choose to build with.
 func SdkModuleFactory() android.Module {
-	return newSdkModule()
+	return newSdkModule(false)
 }
 
-func newSdkModule() *sdk {
+func newSdkModule(moduleExports bool) *sdk {
 	s := &sdk{}
+	s.properties.Module_exports = moduleExports
 	// Get the dynamic sdk member type data for the currently registered sdk member types.
-	s.dynamicSdkMemberTypes = getDynamicSdkMemberTypes(android.SdkMemberTypes)
+	var registry *android.SdkMemberTypesRegistry
+	if moduleExports {
+		registry = android.ModuleExportsMemberTypes
+	} else {
+		registry = android.SdkMemberTypes
+	}
+	s.dynamicSdkMemberTypes = getDynamicSdkMemberTypes(registry)
 	// Create an instance of the dynamically created struct that contains all the
 	// properties for the member type specific list properties.
 	s.dynamicMemberTypeListProperties = s.dynamicSdkMemberTypes.createMemberListProperties()
@@ -211,7 +219,7 @@
 
 // sdk_snapshot is a versioned snapshot of an SDK. This is an auto-generated module.
 func SnapshotModuleFactory() android.Module {
-	s := newSdkModule()
+	s := newSdkModule(false)
 	s.properties.Snapshot = true
 	return s
 }