Merge "Convert container and sh_binary to use ModuleProxy." into main
diff --git a/Android.bp b/Android.bp
index 98552a7..523f55c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -177,11 +177,10 @@
     ],
     // Currently, only microdroid, Ravenwood, and cf system image can refer to system-build.prop
     visibility: [
-        "//build/make/target/product/generic",
-        "//build/make/target/product/gsi",
         "//build/soong/fsgen",
         "//packages/modules/Virtualization/build/microdroid",
         "//frameworks/base/ravenwood",
+        "//visibility:any_system_partition",
     ],
 }
 
diff --git a/aconfig/Android.bp b/aconfig/Android.bp
index 1505ba5..3484b97 100644
--- a/aconfig/Android.bp
+++ b/aconfig/Android.bp
@@ -29,12 +29,17 @@
     pluginFor: ["soong_build"],
 }
 
+// All FlaggedApi flags associated with platform API.
+// By default this uses the platform APIs associated with android.jar
+// but other verticals/platforms can override via soong config setting.
 all_aconfig_declarations {
     name: "all_aconfig_declarations",
-    api_files: [
-        ":frameworks-base-api-current.txt",
-        ":frameworks-base-api-system-current.txt",
-        ":frameworks-base-api-system-server-current.txt",
-        ":frameworks-base-api-module-lib-current.txt",
-    ],
+    api_files: select(soong_config_variable("android_aconfig", "opt_platform_api_srcs"), {
+        default: [
+            ":frameworks-base-api-current.txt",
+            ":frameworks-base-api-system-current.txt",
+            ":frameworks-base-api-system-server-current.txt",
+            ":frameworks-base-api-module-lib-current.txt",
+        ],
+    }),
 }
diff --git a/android/module.go b/android/module.go
index c81380e..da75416 100644
--- a/android/module.go
+++ b/android/module.go
@@ -2145,6 +2145,22 @@
 			}
 		}
 
+		// M(C)TS supports a full test suite and partial per-module MTS test suites, with naming mts-${MODULE}.
+		// To reduce repetition, if we find a partial M(C)TS test suite without an full M(C)TS test suite,
+		// we add the full test suite to our list. This was inherited from
+		// AndroidMkEntries.AddCompatibilityTestSuites.
+		suites := ctx.moduleInfoJSON.CompatibilitySuites
+		if PrefixInList(suites, "mts-") && !InList("mts", suites) {
+			suites = append(suites, "mts")
+		}
+		if PrefixInList(suites, "mcts-") && !InList("mcts", suites) {
+			suites = append(suites, "mcts")
+		}
+		ctx.moduleInfoJSON.CompatibilitySuites = suites
+
+		required := append(m.RequiredModuleNames(ctx), m.VintfFragmentModuleNames(ctx)...)
+		required = append(required, ctx.moduleInfoJSON.ExtraRequired...)
+
 		ctx.moduleInfoJSON.core = CoreModuleInfoJSON{
 			RegisterName:       m.moduleInfoRegisterName(ctx, ctx.moduleInfoJSON.SubName),
 			Path:               []string{ctx.ModuleDir()},
@@ -2154,7 +2170,7 @@
 			TargetDependencies: targetRequired,
 			HostDependencies:   hostRequired,
 			Data:               data,
-			Required:           append(m.RequiredModuleNames(ctx), m.VintfFragmentModuleNames(ctx)...),
+			Required:           required,
 		}
 		SetProvider(ctx, ModuleInfoJSONProvider, ctx.moduleInfoJSON)
 	}
@@ -2266,7 +2282,7 @@
 	arches = slices.DeleteFunc(arches, func(target Target) bool {
 		return target.NativeBridge != ctx.Target().NativeBridge
 	})
-	if len(arches) > 0 && ctx.Arch().ArchType != arches[0].Arch.ArchType {
+	if len(arches) > 0 && ctx.Arch().ArchType != arches[0].Arch.ArchType && ctx.Arch().ArchType != Common {
 		if ctx.Arch().ArchType.Multilib == "lib32" {
 			suffix = "_32"
 		} else {
diff --git a/android/module_context.go b/android/module_context.go
index 1620390..fd804d0 100644
--- a/android/module_context.go
+++ b/android/module_context.go
@@ -655,19 +655,21 @@
 			orderOnlyDeps = InstallPaths(deps).Paths()
 		}
 
-		if m.Config().KatiEnabled() {
-			// When creating the install rule in Soong but embedding in Make, write the rule to a
-			// makefile instead of directly to the ninja file so that main.mk can add the
-			// dependencies from the `required` property that are hard to resolve in Soong.
-			m.katiInstalls = append(m.katiInstalls, katiInstall{
-				from:          srcPath,
-				to:            fullInstallPath,
-				implicitDeps:  implicitDeps,
-				orderOnlyDeps: orderOnlyDeps,
-				executable:    executable,
-				extraFiles:    extraZip,
-			})
-		} else {
+		// When creating the install rule in Soong but embedding in Make, write the rule to a
+		// makefile instead of directly to the ninja file so that main.mk can add the
+		// dependencies from the `required` property that are hard to resolve in Soong.
+		// In soong-only builds, the katiInstall will still be created for semi-legacy code paths
+		// such as module-info.json or compliance, but it will not be used for actually installing
+		// the file.
+		m.katiInstalls = append(m.katiInstalls, katiInstall{
+			from:          srcPath,
+			to:            fullInstallPath,
+			implicitDeps:  implicitDeps,
+			orderOnlyDeps: orderOnlyDeps,
+			executable:    executable,
+			extraFiles:    extraZip,
+		})
+		if !m.Config().KatiEnabled() {
 			rule := CpWithBash
 			if executable {
 				rule = CpExecutableWithBash
@@ -717,15 +719,17 @@
 	}
 	if m.requiresFullInstall() {
 
-		if m.Config().KatiEnabled() {
-			// When creating the symlink rule in Soong but embedding in Make, write the rule to a
-			// makefile instead of directly to the ninja file so that main.mk can add the
-			// dependencies from the `required` property that are hard to resolve in Soong.
-			m.katiSymlinks = append(m.katiSymlinks, katiInstall{
-				from: srcPath,
-				to:   fullInstallPath,
-			})
-		} else {
+		// When creating the symlink rule in Soong but embedding in Make, write the rule to a
+		// makefile instead of directly to the ninja file so that main.mk can add the
+		// dependencies from the `required` property that are hard to resolve in Soong.
+		// In soong-only builds, the katiInstall will still be created for semi-legacy code paths
+		// such as module-info.json or compliance, but it will not be used for actually installing
+		// the file.
+		m.katiSymlinks = append(m.katiSymlinks, katiInstall{
+			from: srcPath,
+			to:   fullInstallPath,
+		})
+		if !m.Config().KatiEnabled() {
 			// The symlink doesn't need updating when the target is modified, but we sometimes
 			// have a dependency on a symlink to a binary instead of to the binary directly, and
 			// the mtime of the symlink must be updated when the binary is modified, so use a
@@ -768,15 +772,17 @@
 	m.module.base().hooks.runInstallHooks(m, nil, fullInstallPath, true)
 
 	if m.requiresFullInstall() {
-		if m.Config().KatiEnabled() {
-			// When creating the symlink rule in Soong but embedding in Make, write the rule to a
-			// makefile instead of directly to the ninja file so that main.mk can add the
-			// dependencies from the `required` property that are hard to resolve in Soong.
-			m.katiSymlinks = append(m.katiSymlinks, katiInstall{
-				absFrom: absPath,
-				to:      fullInstallPath,
-			})
-		} else {
+		// When creating the symlink rule in Soong but embedding in Make, write the rule to a
+		// makefile instead of directly to the ninja file so that main.mk can add the
+		// dependencies from the `required` property that are hard to resolve in Soong.
+		// In soong-only builds, the katiInstall will still be created for semi-legacy code paths
+		// such as module-info.json or compliance, but it will not be used for actually installing
+		// the file.
+		m.katiSymlinks = append(m.katiSymlinks, katiInstall{
+			absFrom: absPath,
+			to:      fullInstallPath,
+		})
+		if !m.Config().KatiEnabled() {
 			m.Build(pctx, BuildParams{
 				Rule:        Symlink,
 				Description: "install symlink " + fullInstallPath.Base() + " -> " + absPath,
diff --git a/android/module_info_json.go b/android/module_info_json.go
index d102dd2..27120ef 100644
--- a/android/module_info_json.go
+++ b/android/module_info_json.go
@@ -43,6 +43,7 @@
 	CompatibilitySuites []string `json:"compatibility_suites,omitempty"` // $(sort $(ALL_MODULES.$(m).COMPATIBILITY_SUITES))
 	AutoTestConfig      []string `json:"auto_test_config,omitempty"`     // $(ALL_MODULES.$(m).auto_test_config)
 	TestConfig          []string `json:"test_config,omitempty"`          // $(strip $(ALL_MODULES.$(m).TEST_CONFIG) $(ALL_MODULES.$(m).EXTRA_TEST_CONFIGS)
+	ExtraRequired       []string `json:"-"`
 }
 
 type ModuleInfoJSON struct {
diff --git a/cc/config/global.go b/cc/config/global.go
index a309dc0..4407967 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -292,7 +292,6 @@
 		"-Wno-error=deprecated",          // in external/googletest/googletest
 		// New warnings to be fixed after clang-r522817
 		"-Wno-error=invalid-offsetof",
-		"-Wno-error=thread-safety-reference-return",
 
 		// Allow using VLA CXX extension.
 		"-Wno-vla-cxx-extension",
diff --git a/compliance/Android.bp b/compliance/Android.bp
index 6662970..a1f2015 100644
--- a/compliance/Android.bp
+++ b/compliance/Android.bp
@@ -34,7 +34,6 @@
     name: "notice_xml_system",
     partition_name: "system",
     visibility: [
-        "//build/make/target/product/generic",
-        "//build/make/target/product/gsi",
+        "//visibility:any_system_partition",
     ],
 }
diff --git a/java/app.go b/java/app.go
index 557ba28..17c7b22 100644
--- a/java/app.go
+++ b/java/app.go
@@ -405,6 +405,14 @@
 		Updatable:     Bool(a.appProperties.Updatable),
 		TestHelperApp: true,
 	})
+
+	moduleInfoJSON := ctx.ModuleInfoJSON()
+	moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests")
+	if len(a.appTestHelperAppProperties.Test_suites) > 0 {
+		moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, a.appTestHelperAppProperties.Test_suites...)
+	} else {
+		moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
+	}
 }
 
 func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -1086,6 +1094,14 @@
 		android.SetProvider(ctx, JavaInfoProvider, javaInfo)
 	}
 
+	moduleInfoJSON := ctx.ModuleInfoJSON()
+	moduleInfoJSON.Class = []string{"APPS"}
+	if !a.embeddedJniLibs {
+		for _, jniLib := range a.jniLibs {
+			moduleInfoJSON.ExtraRequired = append(moduleInfoJSON.ExtraRequired, jniLib.name)
+		}
+	}
+
 	a.setOutputFiles(ctx)
 }
 
@@ -1617,6 +1633,22 @@
 		TopLevelTarget: true,
 	})
 
+	moduleInfoJSON := ctx.ModuleInfoJSON()
+	moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests")
+	if a.testConfig != nil {
+		moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, a.testConfig.String())
+	}
+	moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, a.extraTestConfigs.Strings()...)
+	if len(a.testProperties.Test_suites) > 0 {
+		moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, a.testProperties.Test_suites...)
+	} else {
+		moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
+	}
+
+	if _, ok := testConfig.(android.WritablePath); ok {
+		moduleInfoJSON.AutoTestConfig = []string{"true"}
+	}
+	moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, a.testProperties.Test_mainline_modules...)
 }
 
 func testcaseRel(paths android.Paths) []string {
diff --git a/rust/rust.go b/rust/rust.go
index 35253d6..c0df9f3 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -1769,6 +1769,7 @@
 	depPaths.depClangFlags = android.FirstUniqueStrings(depPaths.depClangFlags)
 	depPaths.depIncludePaths = android.FirstUniquePaths(depPaths.depIncludePaths)
 	depPaths.depSystemIncludePaths = android.FirstUniquePaths(depPaths.depSystemIncludePaths)
+	depPaths.depLinkFlags = android.FirstUniqueStrings(depPaths.depLinkFlags)
 
 	return depPaths
 }