Merge "Some tweaks to the aconfig flag collection logic" into main
diff --git a/cc/cc.go b/cc/cc.go
index 39024aa..2770fb2 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -3361,7 +3361,7 @@
 					c.sabi.Properties.ReexportedIncludes, depExporterInfo.IncludeDirs.Strings()...)
 			}
 
-			makeLibName := MakeLibName(ctx, c, ccDep, depName) + libDepTag.makeSuffix
+			makeLibName := MakeLibName(ctx, c, ccDep, ccDep.BaseModuleName()) + libDepTag.makeSuffix
 			switch {
 			case libDepTag.header():
 				c.Properties.AndroidMkHeaderLibs = append(
@@ -3402,7 +3402,7 @@
 			switch depTag {
 			case runtimeDepTag:
 				c.Properties.AndroidMkRuntimeLibs = append(
-					c.Properties.AndroidMkRuntimeLibs, MakeLibName(ctx, c, ccDep, depName)+libDepTag.makeSuffix)
+					c.Properties.AndroidMkRuntimeLibs, MakeLibName(ctx, c, ccDep, ccDep.BaseModuleName())+libDepTag.makeSuffix)
 				// Record BaseLibName for snapshots.
 				c.Properties.SnapshotRuntimeLibs = append(c.Properties.SnapshotRuntimeLibs, BaseLibName(depName))
 			case objDepTag:
diff --git a/cc/config/riscv64_device.go b/cc/config/riscv64_device.go
index deb922b..6a84fee 100644
--- a/cc/config/riscv64_device.go
+++ b/cc/config/riscv64_device.go
@@ -26,9 +26,7 @@
 		// Help catch common 32/64-bit errors.
 		"-Werror=implicit-function-declaration",
 		"-march=rv64gcv_zba_zbb_zbs",
-		// Equivalent to "-munaligned-access", but our clang doesn't have that yet.
-		"-Xclang -target-feature -Xclang +unaligned-scalar-mem",
-		"-Xclang -target-feature -Xclang +unaligned-vector-mem",
+		"-munaligned-access",
 		// Until https://gitlab.com/qemu-project/qemu/-/issues/1976 is fixed...
 		"-mno-implicit-float",
 		// (https://github.com/google/android-riscv64/issues/124)
@@ -40,9 +38,7 @@
 	riscv64Ldflags = []string{
 		"-Wl,--hash-style=gnu",
 		"-march=rv64gcv_zba_zbb_zbs",
-		// Equivalent to "-munaligned-access", but our clang doesn't have that yet.
-		"-Xclang -target-feature -Xclang +unaligned-scalar-mem",
-		"-Xclang -target-feature -Xclang +unaligned-vector-mem",
+		"-munaligned-access",
 		// We should change the default for this in clang, but for now...
 		// (https://github.com/google/android-riscv64/issues/124)
 		"-Wl,-mllvm -Wl,-jump-is-expensive=false",
diff --git a/cc/prebuilt_test.go b/cc/prebuilt_test.go
index 95fb7ed..f6b5ed5 100644
--- a/cc/prebuilt_test.go
+++ b/cc/prebuilt_test.go
@@ -595,6 +595,9 @@
 		libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
 		expectedDependency := ctx.ModuleForTests(tc.expectedDependencyName, "android_arm64_armv8-a_shared").Module()
 		android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", libfoo.Name(), tc.expectedDependencyName), true, hasDep(ctx, libfoo, expectedDependency))
+		// check that LOCAL_SHARED_LIBRARIES contains libbar and not libbar.v<N>
+		entries := android.AndroidMkEntriesForTest(t, ctx, libfoo)[0]
+		android.AssertStringListContains(t, "Version should not be present in LOCAL_SHARED_LIBRARIES", entries.EntryMap["LOCAL_SHARED_LIBRARIES"], "libbar")
 
 		// check installation rules
 		// the selected soong module should be exported to make
@@ -603,7 +606,7 @@
 
 		// check LOCAL_MODULE of the selected module name
 		// the prebuilt should have the same LOCAL_MODULE when exported to make
-		entries := android.AndroidMkEntriesForTest(t, ctx, libbar)[0]
+		entries = android.AndroidMkEntriesForTest(t, ctx, libbar)[0]
 		android.AssertStringEquals(t, "unexpected LOCAL_MODULE", "libbar", entries.EntryMap["LOCAL_MODULE"][0])
 	}
 }
diff --git a/java/app_import.go b/java/app_import.go
index 8c90e4c..dc84fc2 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -145,6 +145,11 @@
 	// Whether or not to skip checking the preprocessed apk for proper alignment and uncompressed
 	// JNI libs and dex files. Default is false
 	Skip_preprocessed_apk_checks *bool
+
+	// Name of the source soong module that gets shadowed by this prebuilt
+	// If unspecified, follows the naming convention that the source module of
+	// the prebuilt is Name() without "prebuilt_" prefix
+	Source_module_name *string
 }
 
 func (a *AndroidAppImport) IsInstallable() bool {
@@ -274,6 +279,10 @@
 	return a.BaseModuleName()
 }
 
+func (a *AndroidAppImport) BaseModuleName() string {
+	return proptools.StringDefault(a.properties.Source_module_name, a.ModuleBase.Name())
+}
+
 func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext) {
 	if a.Name() == "prebuilt_framework-res" {
 		ctx.ModuleErrorf("prebuilt_framework-res found. This used to have special handling in soong, but was removed due to prebuilt_framework-res no longer existing. This check is to ensure it doesn't come back without readding the special handling.")
diff --git a/java/base.go b/java/base.go
index 7f4ea08..2b499e2 100644
--- a/java/base.go
+++ b/java/base.go
@@ -2408,7 +2408,8 @@
 
 func (this JarJarProviderData) GetDebugString() string {
 	result := ""
-	for k, v := range this.Rename {
+	for _, k := range android.SortedKeys(this.Rename) {
+		v := this.Rename[k]
 		if strings.Contains(k, "android.companion.virtual.flags.FakeFeatureFlagsImpl") {
 			result += k + "--&gt;" + v + ";"
 		}
@@ -2664,7 +2665,8 @@
 // to "" won't be in this list because they shouldn't be renamed yet.
 func getJarJarRuleText(provider *JarJarProviderData) string {
 	result := ""
-	for orig, renamed := range provider.Rename {
+	for _, orig := range android.SortedKeys(provider.Rename) {
+		renamed := provider.Rename[orig]
 		if renamed != "" {
 			result += "rule " + orig + " " + renamed + "\n"
 		}
diff --git a/java/core-libraries/Android.bp b/java/core-libraries/Android.bp
index 8ffe511..ab72e8b 100644
--- a/java/core-libraries/Android.bp
+++ b/java/core-libraries/Android.bp
@@ -64,6 +64,7 @@
         "stub-annotations",
     ],
     enable_validation: false,
+    stubs_type: "everything",
 }
 
 java_library {
@@ -248,6 +249,7 @@
         "stub-annotations",
     ],
     visibility: ["//visibility:private"],
+    stubs_type: "everything",
 }
 
 // Produces a dist file that is used by the
@@ -358,6 +360,7 @@
     libs: [
         "stub-annotations",
     ],
+    stubs_type: "everything",
 }
 
 java_library {
@@ -446,6 +449,7 @@
     libs: [
         "stub-annotations",
     ],
+    stubs_type: "everything",
 }
 
 java_library {
diff --git a/java/droidstubs.go b/java/droidstubs.go
index b112614..f4bcaca 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -52,6 +52,19 @@
 	}
 }
 
+func StringToStubsType(s string) StubsType {
+	switch strings.ToLower(s) {
+	case Everything.String():
+		return Everything
+	case Runtime.String():
+		return Runtime
+	case Exportable.String():
+		return Exportable
+	default:
+		return Unavailable
+	}
+}
+
 func init() {
 	RegisterStubsBuildComponents(android.InitRegistrationContext)
 }
@@ -731,7 +744,7 @@
 // defined for a module, simply revert all flagged apis annotations. If aconfig_declarations
 // property is defined, apply transformations and only revert the flagged apis that are not
 // enabled via release configurations and are not specified in aconfig_declarations
-func (d *Droidstubs) generateRevertAnnotationArgs(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, aconfigFlagsPaths android.Paths) {
+func generateRevertAnnotationArgs(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, aconfigFlagsPaths android.Paths) {
 
 	if len(aconfigFlagsPaths) == 0 {
 		cmd.Flag("--revert-annotation android.annotation.FlaggedApi")
@@ -1106,7 +1119,7 @@
 
 	cmd := d.commonMetalavaStubCmd(ctx, rule, params)
 
-	d.generateRevertAnnotationArgs(ctx, cmd, params.stubConfig.stubsType, params.stubConfig.deps.aconfigProtoFiles)
+	generateRevertAnnotationArgs(ctx, cmd, params.stubConfig.stubsType, params.stubConfig.deps.aconfigProtoFiles)
 
 	if params.stubConfig.doApiLint {
 		// Pass the lint baseline file as an input to resolve the lint errors.
diff --git a/java/droidstubs_test.go b/java/droidstubs_test.go
index ca34e0e..c86e8bf 100644
--- a/java/droidstubs_test.go
+++ b/java/droidstubs_test.go
@@ -337,6 +337,7 @@
 			name: "bar",
 			api_surface: "public",
 			api_contributions: ["foo.api.contribution"],
+			stubs_type: "everything",
 		}
 	`
 	ctx, _ := testJavaWithFS(t, `
diff --git a/java/java.go b/java/java.go
index af4c3be..794020d 100644
--- a/java/java.go
+++ b/java/java.go
@@ -24,6 +24,7 @@
 	"sort"
 	"strings"
 
+	"android/soong/aconfig"
 	"android/soong/remoteexec"
 	"android/soong/testing"
 
@@ -1863,6 +1864,10 @@
 	dexJarFile OptionalDexJarPath
 
 	validationPaths android.Paths
+
+	stubsType StubsType
+
+	aconfigProtoFiles android.Paths
 }
 
 type JavaApiLibraryProperties struct {
@@ -1904,6 +1909,20 @@
 	// in sync with the source Java files. However, the environment variable
 	// DISABLE_STUB_VALIDATION has precedence over this property.
 	Enable_validation *bool
+
+	// Type of stubs the module should generate. Must be one of "everything", "runtime" or
+	// "exportable". Defaults to "everything".
+	// - "everything" stubs include all non-flagged apis and flagged apis, regardless of the state
+	// of the flag.
+	// - "runtime" stubs include all non-flagged apis and flagged apis that are ENABLED or
+	// READ_WRITE, and all other flagged apis are stripped.
+	// - "exportable" stubs include all non-flagged apis and flagged apis that are ENABLED and
+	// READ_ONLY, and all other flagged apis are stripped.
+	Stubs_type *string
+
+	// List of aconfig_declarations module names that the stubs generated in this module
+	// depend on.
+	Aconfig_declarations []string
 }
 
 func ApiLibraryFactory() android.Module {
@@ -2067,6 +2086,9 @@
 	if al.properties.System_modules != nil {
 		ctx.AddVariationDependencies(nil, systemModulesTag, String(al.properties.System_modules))
 	}
+	for _, aconfigDeclarationsName := range al.properties.Aconfig_declarations {
+		ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfigDeclarationsName)
+	}
 }
 
 // Map where key is the api scope name and value is the int value
@@ -2087,7 +2109,23 @@
 	return srcFilesInfo
 }
 
+var validstubsType = []StubsType{Everything, Runtime, Exportable}
+
+func (al *ApiLibrary) validateProperties(ctx android.ModuleContext) {
+	if al.properties.Stubs_type == nil {
+		ctx.ModuleErrorf("java_api_library module type must specify stubs_type property.")
+	} else {
+		al.stubsType = StringToStubsType(proptools.String(al.properties.Stubs_type))
+	}
+
+	if !android.InList(al.stubsType, validstubsType) {
+		ctx.PropertyErrorf("stubs_type", "%s is not a valid stubs_type property value. "+
+			"Must be one of %s.", proptools.String(al.properties.Stubs_type), validstubsType)
+	}
+}
+
 func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	al.validateProperties(ctx)
 
 	rule := android.NewRuleBuilder(pctx, ctx)
 
@@ -2131,6 +2169,18 @@
 			if currentApiTimestampProvider, ok := dep.(currentApiTimestampProvider); ok {
 				al.validationPaths = append(al.validationPaths, currentApiTimestampProvider.CurrentApiTimestamp())
 			}
+		case aconfigDeclarationTag:
+			if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
+				al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.IntermediateCacheOutputPath)
+			} else if provider, ok := android.OtherModuleProvider(ctx, dep, aconfig.CodegenInfoProvider); ok {
+				al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.IntermediateCacheOutputPaths...)
+			} else {
+				ctx.ModuleErrorf("Only aconfig_declarations and aconfig_declarations_group "+
+					"module type is allowed for flags_packages property, but %s is neither "+
+					"of these supported module types",
+					dep.Name(),
+				)
+			}
 		}
 	})
 
@@ -2156,6 +2206,8 @@
 
 	al.addValidation(ctx, cmd, al.validationPaths)
 
+	generateRevertAnnotationArgs(ctx, cmd, al.stubsType, al.aconfigProtoFiles)
+
 	al.stubsSrcJar = android.PathForModuleOut(ctx, "metalava", ctx.ModuleName()+"-"+"stubs.srcjar")
 	al.stubsJarWithoutStaticLibs = android.PathForModuleOut(ctx, "metalava", "stubs.jar")
 	al.stubsJar = android.PathForModuleOut(ctx, ctx.ModuleName(), fmt.Sprintf("%s.jar", ctx.ModuleName()))
diff --git a/java/java_test.go b/java/java_test.go
index 42301d8..2f3ccb9 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1756,6 +1756,7 @@
 			name: "bar",
 			api_surface: "public",
 			api_contributions: ["foo"],
+			stubs_type: "everything",
 		}
 	`)
 }
@@ -1792,12 +1793,14 @@
 			name: "bar1",
 			api_surface: "public",
 			api_contributions: ["foo1"],
+			stubs_type: "everything",
 		}
 
 		java_api_library {
 			name: "bar2",
 			api_surface: "system",
 			api_contributions: ["foo1", "foo2"],
+			stubs_type: "everything",
 		}
 	`)
 
@@ -1885,12 +1888,14 @@
 			name: "bar1",
 			api_surface: "public",
 			api_contributions: ["foo1"],
+			stubs_type: "everything",
 		}
 
 		java_api_library {
 			name: "bar2",
 			api_surface: "public",
 			defaults:["baz1"],
+			stubs_type: "everything",
 		}
 
 		java_api_library {
@@ -1898,6 +1903,7 @@
 			api_surface: "system",
 			defaults:["baz1", "baz2"],
 			api_contributions: ["foo4"],
+			stubs_type: "everything",
 		}
 	`)
 
@@ -1962,12 +1968,14 @@
 			name: "bar1",
 			api_surface: "public",
 			api_contributions: ["foo1"],
+			stubs_type: "everything",
 		}
 
 		java_api_library {
 			name: "bar2",
 			api_surface: "system",
 			api_contributions: ["foo1", "foo2"],
+			stubs_type: "everything",
 		}
 	`)
 
@@ -2044,6 +2052,7 @@
 			api_surface: "public",
 			api_contributions: ["foo1"],
 			libs: ["lib1"],
+			stubs_type: "everything",
 		}
 
 		java_api_library {
@@ -2051,6 +2060,7 @@
 			api_surface: "system",
 			api_contributions: ["foo1", "foo2"],
 			libs: ["lib1", "lib2", "bar1"],
+			stubs_type: "everything",
 		}
 	`)
 
@@ -2130,6 +2140,7 @@
 			api_surface: "public",
 			api_contributions: ["foo1"],
 			static_libs: ["lib1"],
+			stubs_type: "everything",
 		}
 
 		java_api_library {
@@ -2137,6 +2148,7 @@
 			api_surface: "system",
 			api_contributions: ["foo1", "foo2"],
 			static_libs: ["lib1", "lib2", "bar1"],
+			stubs_type: "everything",
 		}
 	`)
 
@@ -2184,6 +2196,7 @@
 		name: "lib1",
 		api_surface: "public",
 		api_contributions: ["foo1", "foo2"],
+		stubs_type: "everything",
 	}
 	`
 
@@ -2207,6 +2220,7 @@
 			api_surface: "public",
 			api_contributions: ["foo1"],
 			full_api_surface_stub: "lib1",
+			stubs_type: "everything",
 		}
 	`)
 
@@ -2368,6 +2382,7 @@
 		java_api_library {
 			name: "foo",
 			api_contributions: ["bar"],
+			stubs_type: "everything",
 		}
 		java_api_contribution_import {
 			name: "bar",
@@ -2394,6 +2409,7 @@
 				"module-lib-api-stubs-docs-non-updatable.api.contribution",
 				"api-stubs-docs-non-updatable.api.contribution",
 			],
+			stubs_type: "everything",
 		}
 	`)
 	m := ctx.ModuleForTests("foo", "android_common")
@@ -2466,6 +2482,7 @@
 				"api-stubs-docs-non-updatable.api.contribution",
 			],
 			enable_validation: true,
+			stubs_type: "everything",
 		}
 		java_api_library {
 			name: "bar",
@@ -2473,6 +2490,7 @@
 				"api-stubs-docs-non-updatable.api.contribution",
 			],
 			enable_validation: false,
+			stubs_type: "everything",
 		}
 	`)
 
@@ -2624,3 +2642,54 @@
 		android.AssertStringEquals(t, "unexpected LOCAL_MODULE", "bar", entries.EntryMap["LOCAL_MODULE"][0])
 	}
 }
+
+func TestApiLibraryAconfigDeclarations(t *testing.T) {
+	result := android.GroupFixturePreparers(
+		prepareForJavaTest,
+		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+		}),
+		android.FixtureMergeMockFs(map[string][]byte{
+			"a/A.java":      nil,
+			"a/current.txt": nil,
+			"a/removed.txt": nil,
+		}),
+	).RunTestWithBp(t, `
+	aconfig_declarations {
+		name: "bar",
+		package: "com.example.package",
+		srcs: [
+			"bar.aconfig",
+		],
+	}
+	java_api_contribution {
+		name: "baz",
+		api_file: "a/current.txt",
+		api_surface: "public",
+	}
+	java_api_library {
+		name: "foo",
+		api_surface: "public",
+		api_contributions: [
+			"baz",
+		],
+		aconfig_declarations: [
+			"bar",
+		],
+		stubs_type: "exportable",
+		enable_validation: false,
+	}
+	`)
+
+	// Check if java_api_library depends on aconfig_declarations
+	android.AssertBoolEquals(t, "foo expected to depend on bar",
+		CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "bar"), true)
+
+	m := result.ModuleForTests("foo", "android_common")
+	android.AssertStringDoesContain(t, "foo generates revert annotations file",
+		strings.Join(m.AllOutputs(), ""), "revert-annotations-exportable.txt")
+
+	// revert-annotations.txt passed to exportable stubs generation metalava command
+	manifest := m.Output("metalava.sbox.textproto")
+	cmdline := String(android.RuleBuilderSboxProtoForTests(t, result.TestContext, manifest).Commands[0].Command)
+	android.AssertStringDoesContain(t, "flagged api hide command not included", cmdline, "revert-annotations-exportable.txt")
+}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index d532aaa..cdd0448 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -2024,6 +2024,7 @@
 		Full_api_surface_stub *string
 		System_modules        *string
 		Enable_validation     *bool
+		Stubs_type            *string
 	}{}
 
 	props.Name = proptools.StringPtr(module.apiLibraryModuleName(apiScope))
@@ -2073,6 +2074,7 @@
 
 	props.System_modules = module.deviceProperties.System_modules
 	props.Enable_validation = proptools.BoolPtr(true)
+	props.Stubs_type = proptools.StringPtr("everything")
 
 	mctx.CreateModule(ApiLibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
 }
diff --git a/java/testing.go b/java/testing.go
index 04e8c73..631d516 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -523,10 +523,11 @@
 
 	for libName, droidstubs := range extraApiLibraryModules {
 		bp += fmt.Sprintf(`
-            java_api_library {
-                name: "%s",
-                api_contributions: ["%s"],
-            }
+		java_api_library {
+			name: "%s",
+			api_contributions: ["%s"],
+			stubs_type: "everything",
+		}
         `, libName, droidstubs.name+".api.contribution")
 	}