Merge "Remove host_snapshot module" into main
diff --git a/Android.bp b/Android.bp
index 8d1280c..432c7fc 100644
--- a/Android.bp
+++ b/Android.bp
@@ -149,3 +149,21 @@
     relative_install_path: "etc", // system_ext/etc/build.prop
     visibility: ["//visibility:private"],
 }
+
+build_prop {
+    name: "product-build.prop",
+    stem: "build.prop",
+    product_specific: true,
+    product_config: ":product_config",
+    relative_install_path: "etc", // product/etc/build.prop
+    visibility: ["//visibility:private"],
+}
+
+build_prop {
+    name: "odm-build.prop",
+    stem: "build.prop",
+    device_specific: true,
+    product_config: ":product_config",
+    relative_install_path: "etc", // odm/etc/build.prop
+    visibility: ["//visibility:private"],
+}
diff --git a/android/build_prop.go b/android/build_prop.go
index d48d94d..b127755 100644
--- a/android/build_prop.go
+++ b/android/build_prop.go
@@ -61,6 +61,8 @@
 		return ctx.Config().SystemPropFiles(ctx)
 	} else if partition == "system_ext" {
 		return ctx.Config().SystemExtPropFiles(ctx)
+	} else if partition == "product" {
+		return ctx.Config().ProductPropFiles(ctx)
 	}
 	return nil
 }
@@ -80,6 +82,28 @@
 	return false
 }
 
+// Can't use PartitionTag() because PartitionTag() returns the partition this module is actually
+// installed (e.g. odm module's partition tag can be either "odm" or "vendor")
+func (p *buildPropModule) partition(config DeviceConfig) string {
+	if p.SocSpecific() {
+		return "vendor"
+	} else if p.DeviceSpecific() {
+		return "odm"
+	} else if p.ProductSpecific() {
+		return "product"
+	} else if p.SystemExtSpecific() {
+		return "system_ext"
+	}
+	return "system"
+}
+
+var validPartitions = []string{
+	"system",
+	"system_ext",
+	"product",
+	"odm",
+}
+
 func (p *buildPropModule) GenerateAndroidBuildActions(ctx ModuleContext) {
 	p.outputFilePath = PathForModuleOut(ctx, "build.prop").OutputPath
 	if !ctx.Config().KatiEnabled() {
@@ -88,9 +112,9 @@
 		return
 	}
 
-	partition := p.PartitionTag(ctx.DeviceConfig())
-	if partition != "system" && partition != "system_ext" {
-		ctx.PropertyErrorf("partition", "unsupported partition %q: only \"system\" and \"system_ext\" are supported", partition)
+	partition := p.partition(ctx.DeviceConfig())
+	if !InList(partition, validPartitions) {
+		ctx.PropertyErrorf("partition", "unsupported partition %q: only %q are supported", partition, validPartitions)
 		return
 	}
 
@@ -118,7 +142,7 @@
 	cmd.FlagWithInput("--platform-preview-sdk-fingerprint-file=", ApiFingerprintPath(ctx))
 	cmd.FlagWithInput("--product-config=", PathForModuleSrc(ctx, proptools.String(p.properties.Product_config)))
 	cmd.FlagWithArg("--partition=", partition)
-	cmd.FlagForEachInput("--prop-files=", ctx.Config().SystemPropFiles(ctx))
+	cmd.FlagForEachInput("--prop-files=", p.propFiles(ctx))
 	cmd.FlagWithOutput("--out=", p.outputFilePath)
 
 	postProcessCmd := rule.Command().BuiltTool("post_process_props")
diff --git a/android/config.go b/android/config.go
index 3b30af8..d13e5ab 100644
--- a/android/config.go
+++ b/android/config.go
@@ -2046,6 +2046,10 @@
 	return PathsForSource(ctx, c.productVariables.SystemExtPropFiles)
 }
 
+func (c *config) ProductPropFiles(ctx PathContext) Paths {
+	return PathsForSource(ctx, c.productVariables.ProductPropFiles)
+}
+
 func (c *config) EnableUffdGc() string {
 	return String(c.productVariables.EnableUffdGc)
 }
diff --git a/android/variable.go b/android/variable.go
index c9b29f1..4025607 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -510,6 +510,7 @@
 
 	SystemPropFiles    []string `json:",omitempty"`
 	SystemExtPropFiles []string `json:",omitempty"`
+	ProductPropFiles   []string `json:",omitempty"`
 
 	EnableUffdGc *string `json:",omitempty"`
 }
diff --git a/cc/config/global.go b/cc/config/global.go
index fac3388..9e39190 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -339,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
@@ -367,9 +370,6 @@
 		"-Wno-gnu-offsetof-extensions",
 		// TODO: Enable this warning http://b/315245071
 		"-Wno-fortify-source",
-
-		// http://b/315250603 temporarily disabled
-		"-Wno-error=format",
 	}
 
 	llvmNextExtraCommonGlobalCflags = []string{
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/base.go b/java/base.go
index 9c1d8fb..f820629 100644
--- a/java/base.go
+++ b/java/base.go
@@ -2229,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/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/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_build_prop.py b/scripts/gen_build_prop.py
index 2bd246d..c08a3fd 100644
--- a/scripts/gen_build_prop.py
+++ b/scripts/gen_build_prop.py
@@ -472,6 +472,8 @@
   # Add the 16K developer args if it is defined for the product.
   props.append(f"ro.product.build.16k_page.enabled={'true' if config['Product16KDeveloperOption'] else 'false'}")
 
+  props.append(f"ro.product.page_size={16384 if config['TargetBoots16K'] else 4096}")
+
   props.append(f"ro.build.characteristics={config['AAPTCharacteristics']}")
 
   if "AbOtaUpdater" in config and config["AbOtaUpdater"]:
@@ -537,6 +539,7 @@
     ]
 
   build_prop(args, gen_build_info=False, gen_common_build_props=True, variables=variables)
+'''
 
 def build_product_prop(args):
   config = args.config
@@ -547,8 +550,32 @@
     "ADDITIONAL_PRODUCT_PROPERTIES",
     "PRODUCT_PRODUCT_PROPERTIES",
   ]
+
+  gen_common_build_props = True
+
+  # Skip common /product properties generation if device released before R and
+  # has no product partition. This is the first part of the check.
+  if config["Shipping_api_level"] and int(config["Shipping_api_level"]) < 30:
+    gen_common_build_props = False
+
+  # The second part of the check - always generate common properties for the
+  # devices with product partition regardless of shipping level.
+  if config["UsesProductImage"]:
+    gen_common_build_props = True
+
   build_prop(args, gen_build_info=False, gen_common_build_props=True, variables=variables)
-'''
+
+  if config["OemProperties"]:
+    print("####################################")
+    print("# PRODUCT_OEM_PROPERTIES")
+    print("####################################")
+
+    for prop in config["OemProperties"]:
+      print(f"import /oem/oem.prop {prop}")
+
+def build_odm_prop(args):
+  variables = ["ADDITIONAL_ODM_PROPERTIES", "PRODUCT_ODM_PROPERTIES"]
+  build_prop(args, gen_build_info=False, gen_common_build_props=True, variables=variables)
 
 def build_prop(args, gen_build_info, gen_common_build_props, variables):
   config = args.config
@@ -570,18 +597,19 @@
   args = parse_args()
 
   with contextlib.redirect_stdout(args.out):
-    if args.partition == "system":
-      build_system_prop(args)
-    elif args.partition == "system_ext":
-      build_system_ext_prop(args)
-      '''
-    elif args.partition == "vendor":
-      build_vendor_prop(args)
-    elif args.partition == "product":
-      build_product_prop(args)
-      '''
-    else:
-      sys.exit(f"not supported partition {args.partition}")
+    match args.partition:
+      case "system":
+        build_system_prop(args)
+      case "system_ext":
+        build_system_ext_prop(args)
+      case "odm":
+        build_odm_prop(args)
+      case "product":
+        build_product_prop(args)
+      # case "vendor":  # NOT IMPLEMENTED
+      #  build_vendor_prop(args)
+      case _:
+        sys.exit(f"not supported partition {args.partition}")
 
 if __name__ == "__main__":
   main()