Merge "Fix dex2oat symlink now that we generate dex2oat32/dex2oat64."
diff --git a/Android.bp b/Android.bp
index 7cdd928..a9eceb2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -349,6 +349,7 @@
     deps: [
         "blueprint-proptools",
         "soong-android",
+        "soong-remoteexec",
     ],
     srcs: [
         "java/config/config.go",
diff --git a/android/package_ctx.go b/android/package_ctx.go
index 5a43ea9..0de356e 100644
--- a/android/package_ctx.go
+++ b/android/package_ctx.go
@@ -232,30 +232,10 @@
 	}, argNames...)
 }
 
-// RBEExperimentalFlag indicates which flag should be set for the AndroidRemoteStaticRule
-// to use RBE.
-type RBEExperimentalFlag int
-
-const (
-	// RBE_NOT_EXPERIMENTAL indicates the rule should use RBE in every build that has
-	// UseRBE set.
-	RBE_NOT_EXPERIMENTAL RBEExperimentalFlag = iota
-	// RBE_JAVAC indicates the rule should use RBE only if the RBE_JAVAC variable is
-	// set in an RBE enabled build.
-	RBE_JAVAC
-	// RBE_R8 indicates the rule should use RBE only if the RBE_R8 variable is set in
-	// an RBE enabled build.
-	RBE_R8
-	// RBE_D8 indicates the rule should use RBE only if the RBE_D8 variable is set in
-	// an RBE enabled build.
-	RBE_D8
-)
-
 // RemoteRuleSupports configures rules with whether they have Goma and/or RBE support.
 type RemoteRuleSupports struct {
-	Goma    bool
-	RBE     bool
-	RBEFlag RBEExperimentalFlag
+	Goma bool
+	RBE  bool
 }
 
 // AndroidRemoteStaticRule wraps blueprint.StaticRule but uses goma or RBE's parallelism if goma or RBE are enabled
@@ -277,18 +257,6 @@
 			params.Pool = localPool
 		}
 
-		if ctx.Config().UseRBE() && supports.RBE {
-			if supports.RBEFlag == RBE_JAVAC && !ctx.Config().UseRBEJAVAC() {
-				params.Pool = localPool
-			}
-			if supports.RBEFlag == RBE_R8 && !ctx.Config().UseRBER8() {
-				params.Pool = localPool
-			}
-			if supports.RBEFlag == RBE_D8 && !ctx.Config().UseRBED8() {
-				params.Pool = localPool
-			}
-		}
-
 		return params, nil
 	}, argNames...)
 }
diff --git a/apex/apex.go b/apex/apex.go
index 043f1a9..714cf9c 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -62,6 +62,7 @@
 	certificateTag = dependencyTag{name: "certificate"}
 	usesTag        = dependencyTag{name: "uses"}
 	androidAppTag  = dependencyTag{name: "androidApp", payload: true}
+	rroTag         = dependencyTag{name: "rro", payload: true}
 	apexAvailWl    = makeApexAvailableWhitelist()
 
 	inverseApexAvailWl = invertApexWhiteList(apexAvailWl)
@@ -1118,6 +1119,9 @@
 	// List of APKs to package inside APEX
 	Apps []string
 
+	// List of runtime resource overlays (RROs) inside APEX
+	Rros []string
+
 	// Names of modules to be overridden. Listed modules can only be other binaries
 	// (in Make or Soong).
 	// This does not completely prevent installation of the overridden binaries, but if both
@@ -1528,6 +1532,8 @@
 func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
 	ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(),
 		androidAppTag, a.overridableProperties.Apps...)
+	ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(),
+		rroTag, a.overridableProperties.Rros...)
 }
 
 func (a *apexBundle) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
@@ -1745,6 +1751,21 @@
 	return af
 }
 
+func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, rro java.RuntimeResourceOverlayModule) apexFile {
+	rroDir := "overlay"
+	dirInApex := filepath.Join(rroDir, rro.Theme())
+	fileToCopy := rro.OutputFile()
+	af := newApexFile(ctx, fileToCopy, rro.Name(), dirInApex, app, rro)
+	af.certificate = rro.Certificate()
+
+	if a, ok := rro.(interface {
+		OverriddenManifestPackageName() string
+	}); ok {
+		af.overriddenPackageName = a.OverriddenManifestPackageName()
+	}
+	return af
+}
+
 // Context "decorator", overriding the InstallBypassMake method to always reply `true`.
 type flattenedApexContext struct {
 	android.ModuleContext
@@ -2038,6 +2059,12 @@
 				} else {
 					ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
 				}
+			case rroTag:
+				if rro, ok := child.(java.RuntimeResourceOverlayModule); ok {
+					filesInfo = append(filesInfo, apexFileForRuntimeResourceOverlay(ctx, rro))
+				} else {
+					ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay module", depName)
+				}
 			case prebuiltTag:
 				if prebuilt, ok := child.(android.PrebuiltEtcModule); ok {
 					filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
diff --git a/apex/apex_test.go b/apex/apex_test.go
index c4ab0be..dea7a08 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -521,6 +521,7 @@
 			native_shared_libs: ["mylib"],
 			java_libs: ["myjar"],
 			apps: ["AppFoo"],
+			rros: ["rro"],
 		}
 
 		prebuilt_etc {
@@ -561,12 +562,19 @@
 			system_modules: "none",
 			apex_available: [ "myapex" ],
 		}
+
+		runtime_resource_overlay {
+			name: "rro",
+			theme: "blue",
+		}
+
 	`)
 	ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
 		"etc/myetc",
 		"javalib/myjar.jar",
 		"lib64/mylib.so",
 		"app/AppFoo/AppFoo.apk",
+		"overlay/blue/rro.apk",
 	})
 }
 
diff --git a/cc/config/clang.go b/cc/config/clang.go
index bdd9030..24dc6b9 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -48,6 +48,8 @@
 	"-Wunused-but-set-parameter",
 	"-Wunused-but-set-variable",
 	"-fdiagnostics-color",
+	// http://b/153759688
+	"-fuse-init-array",
 
 	// arm + arm64
 	"-fgcse-after-reload",
@@ -113,9 +115,6 @@
 		// color codes if it is not running in a terminal.
 		"-fcolor-diagnostics",
 
-		// http://b/68236239 Allow 0/NULL instead of using nullptr everywhere.
-		"-Wno-zero-as-null-pointer-constant",
-
 		// Warnings from clang-7.0
 		"-Wno-sign-compare",
 
@@ -166,6 +165,17 @@
 		"-Wno-int-in-bool-context",          // http://b/148287349
 		"-Wno-sizeof-array-div",             // http://b/148815709
 		"-Wno-tautological-overlap-compare", // http://b/148815696
+		// New warnings to be fixed after clang-r383902.
+		"-Wno-deprecated-copy",                      // http://b/153746672
+		"-Wno-range-loop-construct",                 // http://b/153747076
+		"-Wno-misleading-indentation",               // http://b/153746954
+		"-Wno-zero-as-null-pointer-constant",        // http://b/68236239
+		"-Wno-deprecated-anon-enum-enum-conversion", // http://b/153746485
+		"-Wno-deprecated-enum-enum-conversion",      // http://b/153746563
+		"-Wno-string-compare",                       // http://b/153764102
+		"-Wno-enum-enum-conversion",                 // http://b/154138986
+		"-Wno-enum-float-conversion",                // http://b/154255917
+		"-Wno-pessimizing-move",                     // http://b/154270751
 	}, " "))
 
 	// Extra cflags for external third-party projects to disable warnings that
diff --git a/cc/config/global.go b/cc/config/global.go
index 39c4c33..923dd29 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -128,8 +128,8 @@
 
 	// prebuilts/clang default settings.
 	ClangDefaultBase         = "prebuilts/clang/host"
-	ClangDefaultVersion      = "clang-r377782d"
-	ClangDefaultShortVersion = "10.0.6"
+	ClangDefaultVersion      = "clang-r383902"
+	ClangDefaultShortVersion = "11.0.1"
 
 	// Directories with warnings from Android.bp files.
 	WarningAllowedProjects = []string{
@@ -257,10 +257,10 @@
 		return ""
 	})
 
-	pctx.VariableFunc("RECXXPool", envOverrideFunc("RBE_CXX_POOL", remoteexec.DefaultPool))
-	pctx.VariableFunc("RECXXLinksPool", envOverrideFunc("RBE_CXX_LINKS_POOL", remoteexec.DefaultPool))
-	pctx.VariableFunc("RECXXLinksExecStrategy", envOverrideFunc("RBE_CXX_LINKS_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
-	pctx.VariableFunc("REAbiDumperExecStrategy", envOverrideFunc("RBE_ABI_DUMPER_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
+	pctx.VariableFunc("RECXXPool", remoteexec.EnvOverrideFunc("RBE_CXX_POOL", remoteexec.DefaultPool))
+	pctx.VariableFunc("RECXXLinksPool", remoteexec.EnvOverrideFunc("RBE_CXX_LINKS_POOL", remoteexec.DefaultPool))
+	pctx.VariableFunc("RECXXLinksExecStrategy", remoteexec.EnvOverrideFunc("RBE_CXX_LINKS_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
+	pctx.VariableFunc("REAbiDumperExecStrategy", remoteexec.EnvOverrideFunc("RBE_ABI_DUMPER_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
 }
 
 var HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", android.Config.PrebuiltOS)
diff --git a/cc/fuzz.go b/cc/fuzz.go
index ebe4252..948595b 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -126,7 +126,7 @@
 func collectAllSharedDependencies(ctx android.SingletonContext, module android.Module) android.Paths {
 	var fringe []android.Module
 
-	seen := make(map[android.Module]bool)
+	seen := make(map[string]bool)
 
 	// Enumerate the first level of dependencies, as we discard all non-library
 	// modules in the BFS loop below.
@@ -140,15 +140,15 @@
 
 	for i := 0; i < len(fringe); i++ {
 		module := fringe[i]
-		if seen[module] {
+		if seen[module.Name()] {
 			continue
 		}
-		seen[module] = true
+		seen[module.Name()] = true
 
 		ccModule := module.(*Module)
 		sharedLibraries = append(sharedLibraries, ccModule.UnstrippedOutputFile())
 		ctx.VisitDirectDeps(module, func(dep android.Module) {
-			if isValidSharedDependency(dep) && !seen[dep] {
+			if isValidSharedDependency(dep) && !seen[dep.Name()] {
 				fringe = append(fringe, dep)
 			}
 		})
@@ -255,13 +255,13 @@
 	}
 
 	// Grab the list of required shared libraries.
-	seen := make(map[android.Module]bool)
+	seen := make(map[string]bool)
 	var sharedLibraries android.Paths
 	ctx.WalkDeps(func(child, parent android.Module) bool {
-		if seen[child] {
+		if seen[child.Name()] {
 			return false
 		}
-		seen[child] = true
+		seen[child.Name()] = true
 
 		if isValidSharedDependency(child) {
 			sharedLibraries = append(sharedLibraries, child.(*Module).UnstrippedOutputFile())
diff --git a/cc/tidy.go b/cc/tidy.go
index cfb5b68..364e56c 100644
--- a/cc/tidy.go
+++ b/cc/tidy.go
@@ -121,6 +121,12 @@
 	// many local projects enable cert-* checks, which
 	// trigger bugprone-reserved-identifier.
 	tidyChecks = tidyChecks + ",-bugprone-reserved-identifier*,-cert-dcl51-cpp,-cert-dcl37-c"
+	// http://b/153757728
+	tidyChecks = tidyChecks + ",-readability-qualified-auto"
+	// http://b/155034563
+	tidyChecks = tidyChecks + ",-bugprone-signed-char-misuse"
+	// http://b/155034972
+	tidyChecks = tidyChecks + ",-bugprone-branch-clone"
 	flags.TidyFlags = append(flags.TidyFlags, tidyChecks)
 
 	if len(tidy.Properties.Tidy_checks_as_errors) > 0 {
diff --git a/java/app.go b/java/app.go
index f296f7b..2fd397a 100755
--- a/java/app.go
+++ b/java/app.go
@@ -45,6 +45,7 @@
 	ctx.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory)
 	ctx.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory)
 	ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory)
+	ctx.RegisterModuleType("override_runtime_resource_overlay", OverrideRuntimeResourceOverlayModuleFactory)
 	ctx.RegisterModuleType("android_app_import", AndroidAppImportFactory)
 	ctx.RegisterModuleType("android_test_import", AndroidTestImportFactory)
 	ctx.RegisterModuleType("runtime_resource_overlay", RuntimeResourceOverlayFactory)
@@ -131,6 +132,15 @@
 	Logging_parent *string
 }
 
+// runtime_resource_overlay properties that can be overridden by override_runtime_resource_overlay
+type OverridableRuntimeResourceOverlayProperties struct {
+	// the package name of this app. The package name in the manifest file is used if one was not given.
+	Package_name *string
+
+	// the target package name of this overlay app. The target package name in the manifest file is used if one was not given.
+	Target_package_name *string
+}
+
 type AndroidApp struct {
 	Library
 	aapt
@@ -753,6 +763,7 @@
 }
 
 type appTestProperties struct {
+	// The name of the android_app module that the tests will run against.
 	Instrumentation_for *string
 
 	// if specified, the instrumentation target package name in the manifest is overwritten by it.
@@ -988,6 +999,27 @@
 	return m
 }
 
+type OverrideRuntimeResourceOverlay struct {
+	android.ModuleBase
+	android.OverrideModuleBase
+}
+
+func (i *OverrideRuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	// All the overrides happen in the base module.
+	// TODO(jungjw): Check the base module type.
+}
+
+// override_runtime_resource_overlay is used to create a module based on another
+// runtime_resource_overlay module by overriding some of its properties.
+func OverrideRuntimeResourceOverlayModuleFactory() android.Module {
+	m := &OverrideRuntimeResourceOverlay{}
+	m.AddProperties(&OverridableRuntimeResourceOverlayProperties{})
+
+	android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
+	android.InitOverrideModule(m)
+	return m
+}
+
 type AndroidAppImport struct {
 	android.ModuleBase
 	android.DefaultableModuleBase
@@ -1383,9 +1415,11 @@
 type RuntimeResourceOverlay struct {
 	android.ModuleBase
 	android.DefaultableModuleBase
+	android.OverridableModuleBase
 	aapt
 
-	properties RuntimeResourceOverlayProperties
+	properties            RuntimeResourceOverlayProperties
+	overridableProperties OverridableRuntimeResourceOverlayProperties
 
 	certificate Certificate
 
@@ -1424,6 +1458,15 @@
 	Overrides []string
 }
 
+// RuntimeResourceOverlayModule interface is used by the apex package to gather information from
+// a RuntimeResourceOverlay module.
+type RuntimeResourceOverlayModule interface {
+	android.Module
+	OutputFile() android.Path
+	Certificate() Certificate
+	Theme() string
+}
+
 func (r *RuntimeResourceOverlay) DepsMutator(ctx android.BottomUpMutatorContext) {
 	sdkDep := decodeSdkDep(ctx, sdkContext(r))
 	if sdkDep.hasFrameworkLibs() {
@@ -1443,7 +1486,21 @@
 	// Compile and link resources
 	r.aapt.hasNoCode = true
 	// Do not remove resources without default values nor dedupe resource configurations with the same value
-	r.aapt.buildActions(ctx, r, "--no-resource-deduping", "--no-resource-removal")
+	aaptLinkFlags := []string{"--no-resource-deduping", "--no-resource-removal"}
+	// Allow the override of "package name" and "overlay target package name"
+	manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName())
+	if overridden || r.overridableProperties.Package_name != nil {
+		// The product override variable has a priority over the package_name property.
+		if !overridden {
+			manifestPackageName = *r.overridableProperties.Package_name
+		}
+		aaptLinkFlags = append(aaptLinkFlags, "--rename-manifest-package "+manifestPackageName)
+	}
+	if r.overridableProperties.Target_package_name != nil {
+		aaptLinkFlags = append(aaptLinkFlags,
+			"--rename-overlay-target-package "+*r.overridableProperties.Target_package_name)
+	}
+	r.aapt.buildActions(ctx, r, aaptLinkFlags...)
 
 	// Sign the built package
 	_, certificates := collectAppDeps(ctx, false, false)
@@ -1476,16 +1533,30 @@
 	return r.sdkVersion()
 }
 
+func (r *RuntimeResourceOverlay) Certificate() Certificate {
+	return r.certificate
+}
+
+func (r *RuntimeResourceOverlay) OutputFile() android.Path {
+	return r.outputFile
+}
+
+func (r *RuntimeResourceOverlay) Theme() string {
+	return String(r.properties.Theme)
+}
+
 // runtime_resource_overlay generates a resource-only apk file that can overlay application and
 // system resources at run time.
 func RuntimeResourceOverlayFactory() android.Module {
 	module := &RuntimeResourceOverlay{}
 	module.AddProperties(
 		&module.properties,
-		&module.aaptProperties)
+		&module.aaptProperties,
+		&module.overridableProperties)
 
-	InitJavaModule(module, android.DeviceSupported)
-
+	android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
+	android.InitDefaultableModule(module)
+	android.InitOverridableModule(module, &module.properties.Overrides)
 	return module
 }
 
diff --git a/java/app_test.go b/java/app_test.go
index c1a0cdd..3360510 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -2566,3 +2566,137 @@
 		t.Errorf("Unexpected LOCAL_OVERRIDES_PACKAGES value: %v, expected: %v", overrides, expectedOverrides)
 	}
 }
+
+func TestOverrideRuntimeResourceOverlay(t *testing.T) {
+	ctx, _ := testJava(t, `
+		runtime_resource_overlay {
+			name: "foo_overlay",
+			certificate: "platform",
+			product_specific: true,
+			sdk_version: "current",
+		}
+
+		override_runtime_resource_overlay {
+			name: "bar_overlay",
+			base: "foo_overlay",
+			package_name: "com.android.bar.overlay",
+			target_package_name: "com.android.bar",
+		}
+		`)
+
+	expectedVariants := []struct {
+		moduleName        string
+		variantName       string
+		apkPath           string
+		overrides         []string
+		targetVariant     string
+		packageFlag       string
+		targetPackageFlag string
+	}{
+		{
+			variantName:       "android_common",
+			apkPath:           "/target/product/test_device/product/overlay/foo_overlay.apk",
+			overrides:         nil,
+			targetVariant:     "android_common",
+			packageFlag:       "",
+			targetPackageFlag: "",
+		},
+		{
+			variantName:       "android_common_bar_overlay",
+			apkPath:           "/target/product/test_device/product/overlay/bar_overlay.apk",
+			overrides:         []string{"foo_overlay"},
+			targetVariant:     "android_common_bar",
+			packageFlag:       "com.android.bar.overlay",
+			targetPackageFlag: "com.android.bar",
+		},
+	}
+	for _, expected := range expectedVariants {
+		variant := ctx.ModuleForTests("foo_overlay", expected.variantName)
+
+		// Check the final apk name
+		outputs := variant.AllOutputs()
+		expectedApkPath := buildDir + expected.apkPath
+		found := false
+		for _, o := range outputs {
+			if o == expectedApkPath {
+				found = true
+				break
+			}
+		}
+		if !found {
+			t.Errorf("Can't find %q in output files.\nAll outputs:%v", expectedApkPath, outputs)
+		}
+
+		// Check if the overrides field values are correctly aggregated.
+		mod := variant.Module().(*RuntimeResourceOverlay)
+		if !reflect.DeepEqual(expected.overrides, mod.properties.Overrides) {
+			t.Errorf("Incorrect overrides property value, expected: %q, got: %q",
+				expected.overrides, mod.properties.Overrides)
+		}
+
+		// Check aapt2 flags.
+		res := variant.Output("package-res.apk")
+		aapt2Flags := res.Args["flags"]
+		checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
+		checkAapt2LinkFlag(t, aapt2Flags, "rename-overlay-target-package", expected.targetPackageFlag)
+	}
+}
+
+func TestRuntimeResourceOverlay_JavaDefaults(t *testing.T) {
+	ctx, config := testJava(t, `
+		java_defaults {
+			name: "rro_defaults",
+			theme: "default_theme",
+			product_specific: true,
+			aaptflags: ["--keep-raw-values"],
+		}
+
+		runtime_resource_overlay {
+			name: "foo_with_defaults",
+			defaults: ["rro_defaults"],
+		}
+
+		runtime_resource_overlay {
+			name: "foo_barebones",
+		}
+		`)
+
+	//
+	// RRO module with defaults
+	//
+	m := ctx.ModuleForTests("foo_with_defaults", "android_common")
+
+	// Check AAPT2 link flags.
+	aapt2Flags := strings.Split(m.Output("package-res.apk").Args["flags"], " ")
+	expectedFlags := []string{"--keep-raw-values", "--no-resource-deduping", "--no-resource-removal"}
+	absentFlags := android.RemoveListFromList(expectedFlags, aapt2Flags)
+	if len(absentFlags) > 0 {
+		t.Errorf("expected values, %q are missing in aapt2 link flags, %q", absentFlags, aapt2Flags)
+	}
+
+	// Check device location.
+	path := android.AndroidMkEntriesForTest(t, config, "", m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
+	expectedPath := []string{"/tmp/target/product/test_device/product/overlay/default_theme"}
+	if !reflect.DeepEqual(path, expectedPath) {
+		t.Errorf("Unexpected LOCAL_MODULE_PATH value: %q, expected: %q", path, expectedPath)
+	}
+
+	//
+	// RRO module without defaults
+	//
+	m = ctx.ModuleForTests("foo_barebones", "android_common")
+
+	// Check AAPT2 link flags.
+	aapt2Flags = strings.Split(m.Output("package-res.apk").Args["flags"], " ")
+	unexpectedFlags := "--keep-raw-values"
+	if inList(unexpectedFlags, aapt2Flags) {
+		t.Errorf("unexpected value, %q is present in aapt2 link flags, %q", unexpectedFlags, aapt2Flags)
+	}
+
+	// Check device location.
+	path = android.AndroidMkEntriesForTest(t, config, "", m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
+	expectedPath = []string{"/tmp/target/product/test_device/system/overlay"}
+	if !reflect.DeepEqual(path, expectedPath) {
+		t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath)
+	}
+}
diff --git a/java/builder.go b/java/builder.go
index 6844809..3a4a10d 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -27,6 +27,7 @@
 	"github.com/google/blueprint/proptools"
 
 	"android/soong/android"
+	"android/soong/remoteexec"
 )
 
 var (
@@ -39,12 +40,12 @@
 	// (if the rule produces .class files) or a .srcjar file (if the rule produces .java files).
 	// .srcjar files are unzipped into a temporary directory when compiled with javac.
 	// TODO(b/143658984): goma can't handle the --system argument to javac.
-	javac = pctx.AndroidRemoteStaticRule("javac", android.RemoteRuleSupports{Goma: false, RBE: true, RBEFlag: android.RBE_JAVAC},
+	javac, javacRE = remoteexec.StaticRules(pctx, "javac",
 		blueprint.RuleParams{
 			Command: `rm -rf "$outDir" "$annoDir" "$srcJarDir" && mkdir -p "$outDir" "$annoDir" "$srcJarDir" && ` +
 				`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
 				`(if [ -s $srcJarDir/list ] || [ -s $out.rsp ] ; then ` +
-				`${config.SoongJavacWrapper} ${config.JavacWrapper}${config.JavacCmd} ` +
+				`${config.SoongJavacWrapper} $reTemplate${config.JavacCmd} ` +
 				`${config.JavacHeapFlags} ${config.JavacVmFlags} ${config.CommonJdkFlags} ` +
 				`$processorpath $processor $javacFlags $bootClasspath $classpath ` +
 				`-source $javaVersion -target $javaVersion ` +
@@ -59,9 +60,12 @@
 			CommandOrderOnly: []string{"${config.SoongJavacWrapper}"},
 			Rspfile:          "$out.rsp",
 			RspfileContent:   "$in",
-		},
-		"javacFlags", "bootClasspath", "classpath", "processorpath", "processor", "srcJars", "srcJarDir",
-		"outDir", "annoDir", "javaVersion")
+		}, &remoteexec.REParams{
+			Labels:       map[string]string{"type": "compile", "lang": "java", "compiler": "javac"},
+			ExecStrategy: "${config.REJavacExecStrategy}",
+			Platform:     map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+		}, []string{"javacFlags", "bootClasspath", "classpath", "processorpath", "processor", "srcJars", "srcJarDir",
+			"outDir", "annoDir", "javaVersion"}, nil)
 
 	_ = pctx.VariableFunc("kytheCorpus",
 		func(ctx android.PackageVarContext) string { return ctx.Config().XrefCorpusName() })
@@ -188,6 +192,7 @@
 func init() {
 	pctx.Import("android/soong/android")
 	pctx.Import("android/soong/java/config")
+	pctx.Import("android/soong/remoteexec")
 }
 
 type javaBuilderFlags struct {
@@ -398,8 +403,12 @@
 		outDir = filepath.Join(shardDir, outDir)
 		annoDir = filepath.Join(shardDir, annoDir)
 	}
+	rule := javac
+	if ctx.Config().IsEnvTrue("RBE_JAVAC") {
+		rule = javacRE
+	}
 	ctx.Build(pctx, android.BuildParams{
-		Rule:        javac,
+		Rule:        rule,
 		Description: desc,
 		Output:      outputFile,
 		Inputs:      srcFiles,
diff --git a/java/config/config.go b/java/config/config.go
index 54c89cd..c4f2363 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -22,6 +22,7 @@
 	_ "github.com/google/blueprint/bootstrap"
 
 	"android/soong/android"
+	"android/soong/remoteexec"
 )
 
 var (
@@ -137,30 +138,16 @@
 	pctx.HostJavaToolVariable("MetalavaJar", "metalava.jar")
 	pctx.HostJavaToolVariable("DokkaJar", "dokka.jar")
 	pctx.HostJavaToolVariable("JetifierJar", "jetifier.jar")
+	pctx.HostJavaToolVariable("R8Jar", "r8-compat-proguard.jar")
+	pctx.HostJavaToolVariable("D8Jar", "d8.jar")
 
 	pctx.HostBinToolVariable("SoongJavacWrapper", "soong_javac_wrapper")
 	pctx.HostBinToolVariable("DexpreoptGen", "dexpreopt_gen")
 
-	pctx.VariableFunc("JavacWrapper", func(ctx android.PackageVarContext) string {
-		if override := ctx.Config().Getenv("JAVAC_WRAPPER"); override != "" {
-			return override + " "
-		}
-		return ""
-	})
-
-	pctx.VariableFunc("R8Wrapper", func(ctx android.PackageVarContext) string {
-		if override := ctx.Config().Getenv("R8_WRAPPER"); override != "" {
-			return override + " "
-		}
-		return ""
-	})
-
-	pctx.VariableFunc("D8Wrapper", func(ctx android.PackageVarContext) string {
-		if override := ctx.Config().Getenv("D8_WRAPPER"); override != "" {
-			return override + " "
-		}
-		return ""
-	})
+	pctx.VariableFunc("REJavaPool", remoteexec.EnvOverrideFunc("RBE_JAVA_POOL", "java16"))
+	pctx.VariableFunc("REJavacExecStrategy", remoteexec.EnvOverrideFunc("RBE_JAVAC_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
+	pctx.VariableFunc("RED8ExecStrategy", remoteexec.EnvOverrideFunc("RBE_D8_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
+	pctx.VariableFunc("RER8ExecStrategy", remoteexec.EnvOverrideFunc("RBE_R8_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
 
 	pctx.HostJavaToolVariable("JacocoCLIJar", "jacoco-cli.jar")
 
diff --git a/java/dex.go b/java/dex.go
index 6afdb6d..27ec6ee 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -20,12 +20,13 @@
 	"github.com/google/blueprint"
 
 	"android/soong/android"
+	"android/soong/remoteexec"
 )
 
-var d8 = pctx.AndroidRemoteStaticRule("d8", android.RemoteRuleSupports{RBE: true, RBEFlag: android.RBE_D8},
+var d8, d8RE = remoteexec.StaticRules(pctx, "d8",
 	blueprint.RuleParams{
 		Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
-			`${config.D8Wrapper}${config.D8Cmd} ${config.DexFlags} --output $outDir $d8Flags $in && ` +
+			`$reTemplate${config.D8Cmd} ${config.DexFlags} --output $outDir $d8Flags $in && ` +
 			`${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` +
 			`${config.MergeZipsCmd} -D -stripFile "**/*.class" $out $outDir/classes.dex.jar $in`,
 		CommandDeps: []string{
@@ -33,14 +34,19 @@
 			"${config.SoongZipCmd}",
 			"${config.MergeZipsCmd}",
 		},
-	},
-	"outDir", "d8Flags", "zipFlags")
+	}, &remoteexec.REParams{
+		Labels:          map[string]string{"type": "compile", "compiler": "d8"},
+		Inputs:          []string{"${config.D8Jar}"},
+		ExecStrategy:    "${config.RED8ExecStrategy}",
+		ToolchainInputs: []string{"${config.JavaCmd}"},
+		Platform:        map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+	}, []string{"outDir", "d8Flags", "zipFlags"}, nil)
 
-var r8 = pctx.AndroidRemoteStaticRule("r8", android.RemoteRuleSupports{RBE: true, RBEFlag: android.RBE_R8},
+var r8, r8RE = remoteexec.StaticRules(pctx, "r8",
 	blueprint.RuleParams{
 		Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
 			`rm -f "$outDict" && ` +
-			`${config.R8Wrapper}${config.R8Cmd} ${config.DexFlags} -injars $in --output $outDir ` +
+			`$reTemplate${config.R8Cmd} ${config.DexFlags} -injars $in --output $outDir ` +
 			`--force-proguard-compatibility ` +
 			`--no-data-resources ` +
 			`-printmapping $outDict ` +
@@ -53,8 +59,13 @@
 			"${config.SoongZipCmd}",
 			"${config.MergeZipsCmd}",
 		},
-	},
-	"outDir", "outDict", "r8Flags", "zipFlags")
+	}, &remoteexec.REParams{
+		Labels:          map[string]string{"type": "compile", "compiler": "r8"},
+		Inputs:          []string{"$implicits", "${config.R8Jar}"},
+		ExecStrategy:    "${config.RER8ExecStrategy}",
+		ToolchainInputs: []string{"${config.JavaCmd}"},
+		Platform:        map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+	}, []string{"outDir", "outDict", "r8Flags", "zipFlags"}, []string{"implicits"})
 
 func (j *Module) dexCommonFlags(ctx android.ModuleContext) []string {
 	flags := j.deviceProperties.Dxflags
@@ -185,24 +196,34 @@
 		proguardDictionary := android.PathForModuleOut(ctx, "proguard_dictionary")
 		j.proguardDictionary = proguardDictionary
 		r8Flags, r8Deps := j.r8Flags(ctx, flags)
+		rule := r8
+		args := map[string]string{
+			"r8Flags":  strings.Join(r8Flags, " "),
+			"zipFlags": zipFlags,
+			"outDict":  j.proguardDictionary.String(),
+			"outDir":   outDir.String(),
+		}
+		if ctx.Config().IsEnvTrue("RBE_R8") {
+			rule = r8RE
+			args["implicits"] = strings.Join(r8Deps.Strings(), ",")
+		}
 		ctx.Build(pctx, android.BuildParams{
-			Rule:           r8,
+			Rule:           rule,
 			Description:    "r8",
 			Output:         javalibJar,
 			ImplicitOutput: proguardDictionary,
 			Input:          classesJar,
 			Implicits:      r8Deps,
-			Args: map[string]string{
-				"r8Flags":  strings.Join(r8Flags, " "),
-				"zipFlags": zipFlags,
-				"outDict":  j.proguardDictionary.String(),
-				"outDir":   outDir.String(),
-			},
+			Args:           args,
 		})
 	} else {
 		d8Flags, d8Deps := j.d8Flags(ctx, flags)
+		rule := d8
+		if ctx.Config().IsEnvTrue("RBE_D8") {
+			rule = d8RE
+		}
 		ctx.Build(pctx, android.BuildParams{
-			Rule:        d8,
+			Rule:        rule,
 			Description: "d8",
 			Output:      javalibJar,
 			Input:       classesJar,
diff --git a/java/java.go b/java/java.go
index 38f485e..f6fe76e 100644
--- a/java/java.go
+++ b/java/java.go
@@ -2754,6 +2754,7 @@
 		&sdkLibraryProperties{},
 		&DexImportProperties{},
 		&android.ApexProperties{},
+		&RuntimeResourceOverlayProperties{},
 	)
 
 	android.InitDefaultsModule(module)
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 51e680b..9e3ad5b 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -83,9 +83,6 @@
 	// module name.
 	moduleSuffix string
 
-	// The suffix to add to the make variable that references the location of the api file.
-	apiFileMakeVariableSuffix string
-
 	// SDK version that the stubs library is built against. Note that this is always
 	// *current. Older stubs library built with a numbered SDK version is created from
 	// the prebuilt jar.
@@ -133,20 +130,18 @@
 		sdkVersion: "current",
 	})
 	apiScopeSystem = initApiScope(&apiScope{
-		name:                      "system",
-		apiFilePrefix:             "system-",
-		moduleSuffix:              sdkSystemApiSuffix,
-		apiFileMakeVariableSuffix: "_SYSTEM",
-		sdkVersion:                "system_current",
-		droidstubsArgs:            []string{"-showAnnotation android.annotation.SystemApi"},
+		name:           "system",
+		apiFilePrefix:  "system-",
+		moduleSuffix:   sdkSystemApiSuffix,
+		sdkVersion:     "system_current",
+		droidstubsArgs: []string{"-showAnnotation android.annotation.SystemApi"},
 	})
 	apiScopeTest = initApiScope(&apiScope{
-		name:                      "test",
-		apiFilePrefix:             "test-",
-		moduleSuffix:              sdkTestApiSuffix,
-		apiFileMakeVariableSuffix: "_TEST",
-		sdkVersion:                "test_current",
-		droidstubsArgs:            []string{"-showAnnotation android.annotation.TestApi"},
+		name:           "test",
+		apiFilePrefix:  "test-",
+		moduleSuffix:   sdkTestApiSuffix,
+		sdkVersion:     "test_current",
+		droidstubsArgs: []string{"-showAnnotation android.annotation.TestApi"},
 	})
 	allApiScopes = apiScopes{
 		apiScopePublic,
@@ -503,17 +498,15 @@
 		}
 	}{}
 
-	sdkDep := decodeSdkDep(mctx, sdkContext(&module.Library))
-	// Use the platform API if standard libraries were requested, otherwise use
-	// no default libraries.
-	sdkVersion := ""
-	if !sdkDep.hasStandardLibs() {
-		sdkVersion = "none"
-	}
+	// The stubs source processing uses the same compile time classpath when extracting the
+	// API from the implementation library as it does when compiling it. i.e. the same
+	// * sdk version
+	// * system_modules
+	// * libs (static_libs/libs)
 
 	props.Name = proptools.StringPtr(module.docsName(apiScope))
 	props.Srcs = append(props.Srcs, module.Library.Module.properties.Srcs...)
-	props.Sdk_version = proptools.StringPtr(sdkVersion)
+	props.Sdk_version = module.Library.Module.deviceProperties.Sdk_version
 	props.System_modules = module.Library.Module.deviceProperties.System_modules
 	props.Installable = proptools.BoolPtr(false)
 	// A droiddoc module has only one Libs property and doesn't distinguish between
diff --git a/remoteexec/remoteexec.go b/remoteexec/remoteexec.go
index f511922..860db55 100644
--- a/remoteexec/remoteexec.go
+++ b/remoteexec/remoteexec.go
@@ -154,3 +154,14 @@
 	return ctx.AndroidStaticRule(name, ruleParams, commonArgs...),
 		ctx.AndroidRemoteStaticRule(name+"RE", android.RemoteRuleSupports{RBE: true}, ruleParamsRE, append(commonArgs, reArgs...)...)
 }
+
+// EnvOverrideFunc retrieves a variable func that evaluates to the value of the given environment
+// variable if set, otherwise the given default.
+func EnvOverrideFunc(envVar, defaultVal string) func(ctx android.PackageVarContext) string {
+	return func(ctx android.PackageVarContext) string {
+		if override := ctx.Config().Getenv(envVar); override != "" {
+			return override
+		}
+		return defaultVal
+	}
+}
diff --git a/rust/builder.go b/rust/builder.go
index 27eeec2..2d5e602 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -108,8 +108,8 @@
 	}
 	// TODO once we have static libraries in the host prebuilt .bp, this
 	// should be unconditionally added.
-	if !ctx.Host() {
-		// If we're on a device build, do not use an implicit sysroot
+	if !(ctx.Host() && ctx.TargetPrimary()) {
+		// If we're not targeting the host primary arch, do not use an implicit sysroot
 		rustcFlags = append(rustcFlags, "--sysroot=/dev/null")
 	}
 	// Collect linker flags
diff --git a/rust/compiler.go b/rust/compiler.go
index 81b258c..7499776 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -183,8 +183,8 @@
 
 	if !Bool(compiler.Properties.No_stdlibs) {
 		for _, stdlib := range config.Stdlibs {
-			// If we're building for host, use the compiler's stdlibs
-			if ctx.Host() {
+			// If we're building for the primary host target, use the compiler's stdlibs
+			if ctx.Host() && ctx.TargetPrimary() {
 				stdlib = stdlib + "_" + ctx.toolchain().RustTriple()
 			}
 
@@ -192,9 +192,12 @@
 			// static linking is the default, if one of our static
 			// dependencies uses a dynamic library, we need to dynamically
 			// link the stdlib as well.
-			if (len(deps.Dylibs) > 0) || (!ctx.Host()) {
+			if (len(deps.Dylibs) > 0) || ctx.Device() {
 				// Dynamically linked stdlib
 				deps.Dylibs = append(deps.Dylibs, stdlib)
+			} else if ctx.Host() && !ctx.TargetPrimary() {
+				// Otherwise use the static in-tree stdlib for host secondary arch
+				deps.Rlibs = append(deps.Rlibs, stdlib+".static")
 			}
 		}
 	}
diff --git a/rust/config/arm_device.go b/rust/config/arm_device.go
index aedb42b..ac2580b 100644
--- a/rust/config/arm_device.go
+++ b/rust/config/arm_device.go
@@ -50,7 +50,7 @@
 }
 
 type toolchainArm struct {
-	toolchain64Bit
+	toolchain32Bit
 	toolchainRustFlags string
 }
 
diff --git a/rust/library.go b/rust/library.go
index bf863bb..87e816d 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -281,7 +281,7 @@
 }
 
 func NewRustLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
-	module := newModule(hod, android.MultilibFirst)
+	module := newModule(hod, android.MultilibBoth)
 
 	library := &libraryDecorator{
 		MutatedProperties: LibraryMutatedProperties{
diff --git a/rust/rust_test.go b/rust/rust_test.go
index 02b190f..32eddc1 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -240,7 +240,7 @@
 		rust_binary {
 			name: "fizz-buzz",
 			srcs: ["foo.rs"],
-                        no_stdlibs: true,
+			no_stdlibs: true,
 		}`)
 	module := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Module().(*Module)
 
@@ -248,3 +248,16 @@
 		t.Errorf("no_stdlibs did not suppress dependency on libstd")
 	}
 }
+
+// Test that libraries provide both 32-bit and 64-bit variants.
+func TestMultilib(t *testing.T) {
+	ctx := testRust(t, `
+		rust_library_rlib {
+			name: "libfoo",
+			srcs: ["foo.rs"],
+			crate_name: "foo",
+		}`)
+
+	_ = ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_rlib")
+	_ = ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_rlib")
+}
diff --git a/rust/testing.go b/rust/testing.go
index c3a4625..aad4ffe 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -46,24 +46,29 @@
 			crate_name: "std",
 			srcs: ["foo.rs"],
 			no_stdlibs: true,
+			host_supported: true,
 		}
 		rust_library_rlib {
 			name: "libstd.static",
 			crate_name: "std",
 			srcs: ["foo.rs"],
 			no_stdlibs: true,
+			host_supported: true,
 		}
 		rust_library_dylib {
 			name: "libtest",
 			crate_name: "test",
 			srcs: ["foo.rs"],
 			no_stdlibs: true,
+			host_supported: true,
+
 		}
 		rust_library_rlib {
 			name: "libtest.static",
 			crate_name: "test",
 			srcs: ["foo.rs"],
 			no_stdlibs: true,
+			host_supported: true,
 		}
 
 ` + cc.GatherRequiredDepsForTest(android.NoOsType)
diff --git a/scripts/build-aml-prebuilts.sh b/scripts/build-aml-prebuilts.sh
index 7408349..eef6149 100755
--- a/scripts/build-aml-prebuilts.sh
+++ b/scripts/build-aml-prebuilts.sh
@@ -51,13 +51,11 @@
 SOONG_VARS=${SOONG_OUT}/soong.variables
 
 # We enable bionic linux builds as ART also needs prebuilts for it.
-# Enabling bionic linux requires setting allow_missing_dependencies.
 cat > ${SOONG_VARS}.new << EOF
 {
     "Platform_sdk_version": ${PLATFORM_SDK_VERSION},
     "Platform_sdk_codename": "${PLATFORM_VERSION}",
     "Platform_version_active_codenames": ${PLATFORM_VERSION_ALL_CODENAMES},
-    "Allow_missing_dependencies": true,
 
     "DeviceName": "generic_arm64",
     "HostArch": "x86_64",
@@ -78,4 +76,7 @@
   mv ${SOONG_VARS}.new ${SOONG_VARS}
 fi
 
-m --skip-make "$@"
+# We use force building LLVM components flag (even though we actually don't
+# compile them) because we don't have bionic host prebuilts
+# for them.
+FORCE_BUILD_LLVM_COMPONENTS=true m --skip-make "$@"
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index c0ad35c..788d016 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -46,13 +46,13 @@
 java_import {
 	name: "core.platform.api.stubs",
 }
-java_sdk_library_import {
+java_import {
 	name: "android_stubs_current",
 }
-java_sdk_library_import {
+java_import {
 	name: "android_system_stubs_current",
 }
-java_sdk_library_import {
+java_import {
 	name: "android_test_stubs_current",
 }
 java_import {
diff --git a/ui/build/config.go b/ui/build/config.go
index 55e0d03..7fcc471 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -517,6 +517,9 @@
 				ctx.Fatalln("Unknown option:", arg)
 			}
 		} else if k, v, ok := decodeKeyValue(arg); ok && len(k) > 0 {
+			if k == "OUT_DIR" {
+				ctx.Fatalln("OUT_DIR may only be set in the environment, not as a command line option.")
+			}
 			c.environ.Set(k, v)
 		} else if arg == "dist" {
 			c.dist = true
@@ -783,48 +786,6 @@
 	return false
 }
 
-func (c *configImpl) UseRBEJAVAC() bool {
-	if !c.UseRBE() {
-		return false
-	}
-
-	if v, ok := c.environ.Get("RBE_JAVAC"); ok {
-		v = strings.TrimSpace(v)
-		if v != "" && v != "false" {
-			return true
-		}
-	}
-	return false
-}
-
-func (c *configImpl) UseRBER8() bool {
-	if !c.UseRBE() {
-		return false
-	}
-
-	if v, ok := c.environ.Get("RBE_R8"); ok {
-		v = strings.TrimSpace(v)
-		if v != "" && v != "false" {
-			return true
-		}
-	}
-	return false
-}
-
-func (c *configImpl) UseRBED8() bool {
-	if !c.UseRBE() {
-		return false
-	}
-
-	if v, ok := c.environ.Get("RBE_D8"); ok {
-		v = strings.TrimSpace(v)
-		if v != "" && v != "false" {
-			return true
-		}
-	}
-	return false
-}
-
 func (c *configImpl) StartRBE() bool {
 	if !c.UseRBE() {
 		return false