Merge "Allowlist java.lang.constant in libcore"
diff --git a/android/module.go b/android/module.go
index 681f724..97c9706 100644
--- a/android/module.go
+++ b/android/module.go
@@ -502,6 +502,7 @@
 	InstallInRoot() bool
 	InstallInVendor() bool
 	InstallForceOS() (*OsType, *ArchType)
+	PartitionTag(DeviceConfig) string
 	HideFromMake()
 	IsHideFromMake() bool
 	IsSkipInstall() bool
diff --git a/apex/apex.go b/apex/apex.go
index 8a8b19d..b77568d 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -514,6 +514,7 @@
 	// buildFile is put in the installDir inside the APEX.
 	builtFile  android.Path
 	installDir string
+	partition  string
 	customStem string
 	symlinks   []string // additional symlinks
 
@@ -553,6 +554,7 @@
 	}
 	if module != nil {
 		ret.moduleDir = ctx.OtherModuleDir(module)
+		ret.partition = module.PartitionTag(ctx.DeviceConfig())
 		ret.requiredModuleNames = module.RequiredModuleNames()
 		ret.targetRequiredModuleNames = module.TargetRequiredModuleNames()
 		ret.hostRequiredModuleNames = module.HostRequiredModuleNames()
diff --git a/apex/apex_test.go b/apex/apex_test.go
index eec24b0..faf82b3 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -7122,7 +7122,10 @@
 		cc_library {
 			name: "mylib",
 			srcs: ["mylib.cpp"],
-			shared_libs: ["myotherlib"],
+			shared_libs: [
+				"myotherlib",
+				"myotherlib_ext",
+			],
 			system_shared_libs: [],
 			stl: "none",
 			apex_available: [
@@ -7146,6 +7149,20 @@
 			min_sdk_version: "current",
 		}
 
+		cc_library {
+			name: "myotherlib_ext",
+			srcs: ["mylib.cpp"],
+			system_shared_libs: [],
+			system_ext_specific: true,
+			stl: "none",
+			apex_available: [
+				"myapex",
+				"myapex.updatable",
+				"//apex_available:platform",
+			],
+			min_sdk_version: "current",
+		}
+
 		java_library {
 			name: "myjar",
 			srcs: ["foo/bar/MyClass.java"],
@@ -7186,12 +7203,15 @@
 		t.Errorf("%q is not found", file)
 	}
 
-	ensureSymlinkExists := func(t *testing.T, files []fileInApex, file string) {
+	ensureSymlinkExists := func(t *testing.T, files []fileInApex, file string, target string) {
 		for _, f := range files {
 			if f.path == file {
 				if !f.isLink {
 					t.Errorf("%q is not a symlink", file)
 				}
+				if f.src != target {
+					t.Errorf("expected symlink target to be %q, got %q", target, f.src)
+				}
 				return
 			}
 		}
@@ -7205,23 +7225,27 @@
 	ensureRealfileExists(t, files, "javalib/myjar.jar")
 	ensureRealfileExists(t, files, "lib64/mylib.so")
 	ensureRealfileExists(t, files, "lib64/myotherlib.so")
+	ensureRealfileExists(t, files, "lib64/myotherlib_ext.so")
 
 	files = getFiles(t, ctx, "myapex.updatable", "android_common_myapex.updatable_image")
 	ensureRealfileExists(t, files, "javalib/myjar.jar")
 	ensureRealfileExists(t, files, "lib64/mylib.so")
 	ensureRealfileExists(t, files, "lib64/myotherlib.so")
+	ensureRealfileExists(t, files, "lib64/myotherlib_ext.so")
 
 	// For bundled build, symlink to the system for the non-updatable APEXes only
 	ctx = testApex(t, bp)
 	files = getFiles(t, ctx, "myapex", "android_common_myapex_image")
 	ensureRealfileExists(t, files, "javalib/myjar.jar")
 	ensureRealfileExists(t, files, "lib64/mylib.so")
-	ensureSymlinkExists(t, files, "lib64/myotherlib.so") // this is symlink
+	ensureSymlinkExists(t, files, "lib64/myotherlib.so", "/system/lib64/myotherlib.so")             // this is symlink
+	ensureSymlinkExists(t, files, "lib64/myotherlib_ext.so", "/system_ext/lib64/myotherlib_ext.so") // this is symlink
 
 	files = getFiles(t, ctx, "myapex.updatable", "android_common_myapex.updatable_image")
 	ensureRealfileExists(t, files, "javalib/myjar.jar")
 	ensureRealfileExists(t, files, "lib64/mylib.so")
-	ensureRealfileExists(t, files, "lib64/myotherlib.so") // this is a real file
+	ensureRealfileExists(t, files, "lib64/myotherlib.so")     // this is a real file
+	ensureRealfileExists(t, files, "lib64/myotherlib_ext.so") // this is a real file
 }
 
 func TestSymlinksFromApexToSystemRequiredModuleNames(t *testing.T) {
diff --git a/apex/builder.go b/apex/builder.go
index 93ff80d..a62f63c 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -476,8 +476,7 @@
 		// Copy the built file to the directory. But if the symlink optimization is turned
 		// on, place a symlink to the corresponding file in /system partition instead.
 		if a.linkToSystemLib && fi.transitiveDep && fi.availableToPlatform() {
-			// TODO(jiyong): pathOnDevice should come from fi.module, not being calculated here
-			pathOnDevice := filepath.Join("/system", fi.path())
+			pathOnDevice := filepath.Join("/", fi.partition, fi.path())
 			copyCommands = append(copyCommands, "ln -sfn "+pathOnDevice+" "+destPath)
 		} else {
 			// Copy the file into APEX
@@ -941,8 +940,7 @@
 			dir := filepath.Join("apex", bundleName, fi.installDir)
 			installDir := android.PathForModuleInstall(ctx, dir)
 			if a.linkToSystemLib && fi.transitiveDep && fi.availableToPlatform() {
-				// TODO(jiyong): pathOnDevice should come from fi.module, not being calculated here
-				pathOnDevice := filepath.Join("/system", fi.path())
+				pathOnDevice := filepath.Join("/", fi.partition, fi.path())
 				installedSymlinks = append(installedSymlinks,
 					ctx.InstallAbsoluteSymlink(installDir, fi.stem(), pathOnDevice))
 			} else {
diff --git a/cmd/multiproduct_kati/main.go b/cmd/multiproduct_kati/main.go
index 0115f4a..0212075 100644
--- a/cmd/multiproduct_kati/main.go
+++ b/cmd/multiproduct_kati/main.go
@@ -515,7 +515,8 @@
 		"TARGET_BUILD_VARIANT="+*buildVariant,
 		"TARGET_BUILD_TYPE=release",
 		"TARGET_BUILD_APPS=",
-		"TARGET_BUILD_UNBUNDLED=")
+		"TARGET_BUILD_UNBUNDLED=",
+		"USE_RBE=false") // Disabling RBE saves ~10 secs per product
 
 	if *alternateResultDir {
 		cmd.Env = append(cmd.Env,
diff --git a/ui/build/config.go b/ui/build/config.go
index cb7fe1e..73e2c45 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -369,6 +369,7 @@
 		"CDPATH",
 		"DISPLAY",
 		"GREP_OPTIONS",
+		"JAVAC",
 		"NDK_ROOT",
 		"POSIXLY_CORRECT",
 
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index 1e3e547..a9c298f 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -84,6 +84,14 @@
 	ctx.BeginTrace(metrics.RunKati, "dumpvars")
 	defer ctx.EndTrace()
 
+	tool := ctx.Status.StartTool()
+	if write_soong_vars {
+		// only print this when write_soong_vars is true so that it's not printed when using
+		// the get_build_var command.
+		tool.Status("Running product configuration...")
+	}
+	defer tool.Finish()
+
 	cmd := Command(ctx, config, "dumpvars",
 		config.PrebuiltBuildTool("ckati"),
 		"-f", "build/make/core/config.mk",
@@ -108,7 +116,7 @@
 	}
 	cmd.StartOrFatal()
 	// TODO: error out when Stderr contains any content
-	status.KatiReader(ctx.Status.StartTool(), pipe)
+	status.KatiReader(tool, pipe)
 	cmd.WaitOrFatal()
 
 	ret := make(map[string]string, len(vars))
diff --git a/ui/build/rbe.go b/ui/build/rbe.go
index 3c844c1..1d17216 100644
--- a/ui/build/rbe.go
+++ b/ui/build/rbe.go
@@ -100,6 +100,8 @@
 	ctx.BeginTrace(metrics.RunSetupTool, "rbe_bootstrap")
 	defer ctx.EndTrace()
 
+	ctx.Status.Status("Starting rbe...")
+
 	if u := ulimitOrFatal(ctx, config, "-u"); u < rbeLeastNProcs {
 		ctx.Fatalf("max user processes is insufficient: %d; want >= %d.\n", u, rbeLeastNProcs)
 	}
@@ -180,6 +182,8 @@
 		return
 	}
 
+	ctx.Status.Status("Dumping rbe metrics...")
+
 	outputDir := config.rbeProxyLogsDir()
 	if outputDir == "" {
 		ctx.Fatal("RBE output dir variable not defined. Aborting metrics dumping.")