Merge "Build product/odm build.prop with Soong" into main
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index 5e46bab..20a13c3 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -43,9 +43,9 @@
 		},
 		"abis", "allow-prereleased", "sdk-version", "skip-sdk-check")
 	decompressApex = pctx.StaticRule("decompressApex", blueprint.RuleParams{
-		Command:     `${deapexer} decompress --copy-if-uncompressed --input ${in} --output ${out}`,
+		Command:     `rm -rf $out && ${deapexer} decompress --copy-if-uncompressed --input ${in} --output ${out}`,
 		CommandDeps: []string{"${deapexer}"},
-		Description: "decompress",
+		Description: "decompress $out",
 	})
 )
 
diff --git a/cc/afdo.go b/cc/afdo.go
index 6921edf..14d105e 100644
--- a/cc/afdo.go
+++ b/cc/afdo.go
@@ -47,6 +47,10 @@
 	if ctx.Config().Eng() {
 		afdo.Properties.Afdo = false
 	}
+	// Disable for native coverage builds.
+	if ctx.DeviceConfig().NativeCoverageEnabled() {
+		afdo.Properties.Afdo = false
+	}
 }
 
 // afdoEnabled returns true for binaries and shared libraries
@@ -76,6 +80,8 @@
 	}
 
 	if afdo.Properties.Afdo || afdo.Properties.AfdoDep {
+		// Emit additional debug info for AutoFDO
+		flags.Local.CFlags = append([]string{"-fdebug-info-for-profiling"}, flags.Local.CFlags...)
 		// We use `-funique-internal-linkage-names` to associate profiles to the right internal
 		// functions. This option should be used before generating a profile. Because a profile
 		// generated for a binary without unique names doesn't work well building a binary with
diff --git a/cc/config/global.go b/cc/config/global.go
index 66196c2..9e39190 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -144,9 +144,6 @@
 
 		// Make paths in deps files relative.
 		"-no-canonical-prefixes",
-
-		// http://b/315250603 temporarily disabled
-		"-Wno-error=format",
 	}
 
 	commonGlobalConlyflags = []string{}
@@ -176,9 +173,6 @@
 		"-Werror=sequence-point",
 		"-Werror=format-security",
 		"-nostdlibinc",
-
-		// Emit additional debug info for AutoFDO
-		"-fdebug-info-for-profiling",
 	}
 
 	commonGlobalLldflags = []string{
@@ -345,6 +339,9 @@
 
 		"-Wno-unused",
 		"-Wno-deprecated",
+
+		// http://b/315250603 temporarily disabled
+		"-Wno-error=format",
 	}
 
 	// Similar to noOverrideGlobalCflags, but applies only to third-party code
diff --git a/cc/ndk_abi.go b/cc/ndk_abi.go
index 5beeab1..8202cc0 100644
--- a/cc/ndk_abi.go
+++ b/cc/ndk_abi.go
@@ -46,7 +46,7 @@
 
 		if m, ok := module.(*Module); ok {
 			if installer, ok := m.installer.(*stubDecorator); ok {
-				if canDumpAbi(ctx.Config()) {
+				if canDumpAbi(ctx.Config(), ctx.ModuleDir(module)) {
 					depPaths = append(depPaths, installer.abiDumpPath)
 				}
 			}
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index b822e5c..3e35ef5 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -321,10 +321,19 @@
 }
 
 // Feature flag.
-func canDumpAbi(config android.Config) bool {
+func canDumpAbi(config android.Config, moduleDir string) bool {
 	if runtime.GOOS == "darwin" {
 		return false
 	}
+	if strings.HasPrefix(moduleDir, "bionic/") {
+		// Bionic has enough uncommon implementation details like ifuncs and asm
+		// code that the ABI tracking here has a ton of false positives. That's
+		// causing pretty extreme friction for development there, so disabling
+		// it until the workflow can be improved.
+		//
+		// http://b/358653811
+		return false
+	}
 	// http://b/156513478
 	return config.ReleaseNdkAbiMonitored()
 }
@@ -460,7 +469,7 @@
 	nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile, c.apiLevel, "")
 	objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
 	c.versionScriptPath = nativeAbiResult.versionScript
-	if canDumpAbi(ctx.Config()) {
+	if canDumpAbi(ctx.Config(), ctx.ModuleDir()) {
 		c.dumpAbi(ctx, nativeAbiResult.symbolList)
 		if canDiffAbi(ctx.Config()) {
 			c.diffAbi(ctx)
diff --git a/java/aar.go b/java/aar.go
index 23561da..c8563c8 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -1448,3 +1448,7 @@
 	InitJavaModuleMultiTargets(module, android.DeviceSupported)
 	return module
 }
+
+func (a *AARImport) IDEInfo(dpInfo *android.IdeInfo) {
+	dpInfo.Jars = append(dpInfo.Jars, a.headerJarFile.String(), a.rJar.String())
+}
diff --git a/java/base.go b/java/base.go
index 65a8b30..f820629 100644
--- a/java/base.go
+++ b/java/base.go
@@ -1211,6 +1211,7 @@
 
 	var kotlinJars android.Paths
 	var kotlinHeaderJars android.Paths
+	var kotlinExtraJars android.Paths
 
 	// Prepend extraClasspathJars to classpath so that the resource processor R.jar comes before
 	// any dependencies so that it can override any non-final R classes from dependencies with the
@@ -1321,17 +1322,8 @@
 
 		kotlinJars = append(kotlinJars, kotlinJarPath)
 		kotlinHeaderJars = append(kotlinHeaderJars, kotlinHeaderJar)
-
-		// Jar kotlin classes into the final jar after javac
-		if BoolDefault(j.properties.Static_kotlin_stdlib, true) {
-			kotlinJars = append(kotlinJars, deps.kotlinStdlib...)
-			kotlinJars = append(kotlinJars, deps.kotlinAnnotations...)
-			kotlinHeaderJars = append(kotlinHeaderJars, deps.kotlinStdlib...)
-			kotlinHeaderJars = append(kotlinHeaderJars, deps.kotlinAnnotations...)
-		} else {
-			flags.dexClasspath = append(flags.dexClasspath, deps.kotlinStdlib...)
-			flags.dexClasspath = append(flags.dexClasspath, deps.kotlinAnnotations...)
-		}
+		kotlinExtraJars = append(kotlinExtraJars, deps.kotlinStdlib...)
+		kotlinExtraJars = append(kotlinExtraJars, deps.kotlinAnnotations...)
 	}
 
 	jars := slices.Clone(kotlinJars)
@@ -1349,7 +1341,11 @@
 			// allow for the use of annotation processors that do function correctly
 			// with sharding enabled. See: b/77284273.
 		}
-		extraJars := append(slices.Clone(kotlinHeaderJars), extraCombinedJars...)
+		extraJars := slices.Clone(kotlinHeaderJars)
+		if BoolDefault(j.properties.Static_kotlin_stdlib, true) {
+			extraJars = append(extraJars, kotlinExtraJars...)
+		}
+		extraJars = append(extraJars, extraCombinedJars...)
 		var combinedHeaderJarFile android.Path
 		headerJarFileWithoutDepsOrJarjar, combinedHeaderJarFile =
 			j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, extraJars)
@@ -1427,6 +1423,13 @@
 		}
 	}
 
+	// Jar kotlin classes into the final jar after javac
+	if BoolDefault(j.properties.Static_kotlin_stdlib, true) {
+		jars = append(jars, kotlinExtraJars...)
+	} else {
+		flags.dexClasspath = append(flags.dexClasspath, kotlinExtraJars...)
+	}
+
 	jars = append(jars, extraCombinedJars...)
 
 	j.srcJarArgs, j.srcJarDeps = resourcePathsToJarArgs(srcFiles), srcFiles
@@ -2226,6 +2229,11 @@
 			deps.classpath = append(deps.classpath, sdkDep.jars...)
 			deps.dexClasspath = append(deps.dexClasspath, sdkDep.jars...)
 			deps.aidlPreprocess = sdkDep.aidl
+			// Add the sdk module dependency to `compileDepNames`.
+			// This ensures that the dependency is reported in `module_bp_java_deps.json`
+			// TODO (b/358608607): Move this to decodeSdkDep
+			sdkSpec := android.SdkContext(j).SdkVersion(ctx)
+			j.compileDepNames = append(j.compileDepNames, fmt.Sprintf("sdk_%s_%s_android", sdkSpec.Kind.String(), sdkSpec.ApiLevel.String()))
 		} else {
 			deps.aidlPreprocess = sdkDep.aidl
 		}
diff --git a/java/device_host_converter.go b/java/device_host_converter.go
index 90aeb4e..63b69d0 100644
--- a/java/device_host_converter.go
+++ b/java/device_host_converter.go
@@ -188,3 +188,11 @@
 		},
 	}
 }
+
+// implement the following interface for IDE completion.
+var _ android.IDEInfo = (*DeviceHostConverter)(nil)
+
+func (d *DeviceHostConverter) IDEInfo(ideInfo *android.IdeInfo) {
+	ideInfo.Deps = append(ideInfo.Deps, d.properties.Libs...)
+	ideInfo.Libs = append(ideInfo.Libs, d.properties.Libs...)
+}
diff --git a/java/java.go b/java/java.go
index ebc4425..be3f90b 100644
--- a/java/java.go
+++ b/java/java.go
@@ -2910,7 +2910,7 @@
 // Collect information for opening IDE project files in java/jdeps.go.
 
 func (j *Import) IDEInfo(dpInfo *android.IdeInfo) {
-	dpInfo.Jars = append(dpInfo.Jars, j.PrebuiltSrcs()...)
+	dpInfo.Jars = append(dpInfo.Jars, j.combinedHeaderFile.String())
 }
 
 func (j *Import) IDECustomizedModuleName() string {
diff --git a/java/jdeps_test.go b/java/jdeps_test.go
index e180224..47bfac1 100644
--- a/java/jdeps_test.go
+++ b/java/jdeps_test.go
@@ -103,3 +103,23 @@
 		t.Errorf("Library.IDEInfo() Jarjar_rules = %v, want %v", dpInfo.Jarjar_rules[0], expected)
 	}
 }
+
+func TestCollectJavaLibraryLinkingAgainstVersionedSdk(t *testing.T) {
+	ctx := android.GroupFixturePreparers(
+		prepareForJavaTest,
+		FixtureWithPrebuiltApis(map[string][]string{
+			"29": {},
+		})).RunTestWithBp(t,
+		`
+		java_library {
+			name: "javalib",
+			srcs: ["foo.java"],
+			sdk_version: "29",
+		}
+	`)
+	module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
+	dpInfo := &android.IdeInfo{}
+
+	module.IDEInfo(dpInfo)
+	android.AssertStringListContains(t, "IdeInfo.Deps should contain versioned sdk module", dpInfo.Deps, "sdk_public_29_android")
+}
diff --git a/java/kotlin.go b/java/kotlin.go
index aa2db0e..c28bc3f 100644
--- a/java/kotlin.go
+++ b/java/kotlin.go
@@ -101,6 +101,10 @@
 		commonSrcFilesArg = "--common_srcs " + commonSrcsList.String()
 	}
 
+	classpathRspFile := android.PathForModuleOut(ctx, "kotlinc", "classpath.rsp")
+	android.WriteFileRule(ctx, classpathRspFile, strings.Join(flags.kotlincClasspath.Strings(), " "))
+	deps = append(deps, classpathRspFile)
+
 	ctx.Build(pctx, android.BuildParams{
 		Rule:           kotlinc,
 		Description:    "kotlinc",
@@ -109,7 +113,7 @@
 		Inputs:         srcFiles,
 		Implicits:      deps,
 		Args: map[string]string{
-			"classpath":         flags.kotlincClasspath.FormJavaClassPath(""),
+			"classpath":         classpathRspFile.String(),
 			"kotlincFlags":      flags.kotlincFlags,
 			"commonSrcFilesArg": commonSrcFilesArg,
 			"srcJars":           strings.Join(srcJars.Strings(), " "),
@@ -205,6 +209,10 @@
 	kotlinName := filepath.Join(ctx.ModuleDir(), ctx.ModuleSubDir(), ctx.ModuleName())
 	kotlinName = strings.ReplaceAll(kotlinName, "/", "__")
 
+	classpathRspFile := android.PathForModuleOut(ctx, "kapt", "classpath.rsp")
+	android.WriteFileRule(ctx, classpathRspFile, strings.Join(flags.kotlincClasspath.Strings(), "\n"))
+	deps = append(deps, classpathRspFile)
+
 	// First run kapt to generate .java stubs from .kt files
 	kaptStubsJar := android.PathForModuleOut(ctx, "kapt", "stubs.jar")
 	ctx.Build(pctx, android.BuildParams{
@@ -214,7 +222,7 @@
 		Inputs:      srcFiles,
 		Implicits:   deps,
 		Args: map[string]string{
-			"classpath":         flags.kotlincClasspath.FormJavaClassPath(""),
+			"classpath":         classpathRspFile.String(),
 			"kotlincFlags":      flags.kotlincFlags,
 			"commonSrcFilesArg": commonSrcFilesArg,
 			"srcJars":           strings.Join(srcJars.Strings(), " "),
diff --git a/java/system_modules.go b/java/system_modules.go
index 500d7fa..48b33ba 100644
--- a/java/system_modules.go
+++ b/java/system_modules.go
@@ -311,3 +311,11 @@
 		propertySet.AddPropertyWithTag("libs", p.Libs, ctx.SnapshotBuilder().SdkMemberReferencePropertyTag(true))
 	}
 }
+
+// implement the following interface for IDE completion.
+var _ android.IDEInfo = (*SystemModules)(nil)
+
+func (s *SystemModules) IDEInfo(ideInfo *android.IdeInfo) {
+	ideInfo.Deps = append(ideInfo.Deps, s.properties.Libs...)
+	ideInfo.Libs = append(ideInfo.Libs, s.properties.Libs...)
+}
diff --git a/rust/bindgen.go b/rust/bindgen.go
index d412ea1..a81024a 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -364,7 +364,7 @@
 		ClangProperties:    cc.RustBindgenClangProperties{},
 	}
 
-	module := NewSourceProviderModule(hod, bindgen, false, true)
+	module := NewSourceProviderModule(hod, bindgen, false, false)
 
 	android.AddLoadHook(module, func(ctx android.LoadHookContext) {
 		type stub_props struct {
diff --git a/scripts/gen-kotlin-build-file.py b/scripts/gen-kotlin-build-file.py
index 99afdca..8b7876f 100644
--- a/scripts/gen-kotlin-build-file.py
+++ b/scripts/gen-kotlin-build-file.py
@@ -37,7 +37,7 @@
   parser.add_argument('--out', dest='out',
                       help='file to which the module.xml contents will be written.')
   parser.add_argument('--classpath', dest='classpath', action='append', default=[],
-                      help='classpath to pass to kotlinc.')
+                      help='file containing classpath to pass to kotlinc.')
   parser.add_argument('--name', dest='name',
                       help='name of the module.')
   parser.add_argument('--out_dir', dest='out_dir',
@@ -65,8 +65,8 @@
     f.write('  <module name="%s" type="java-production" outputDir="%s">\n' % (args.name, args.out_dir or ''))
 
     # Print classpath entries
-    for c in args.classpath:
-      for entry in c.split(':'):
+    for classpath_rsp_file in args.classpath:
+      for entry in NinjaRspFileReader(classpath_rsp_file):
         path = os.path.abspath(entry)
         f.write('    <classpath path="%s"/>\n' % path)