Merge "Sanitize APEX module name properly."
diff --git a/android/api_levels.go b/android/api_levels.go
index b6296d8..0872066 100644
--- a/android/api_levels.go
+++ b/android/api_levels.go
@@ -73,6 +73,7 @@
 			"O-MR1": 27,
 			"P":     28,
 			"Q":     29,
+			"R":     30,
 		}
 		for i, codename := range config.PlatformVersionActiveCodenames() {
 			apiLevelsMap[codename] = baseApiLevel + i
diff --git a/android/arch.go b/android/arch.go
index 66edf7e..ba113b2 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -23,6 +23,7 @@
 	"strings"
 
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/bootstrap"
 	"github.com/google/blueprint/proptools"
 )
 
@@ -698,13 +699,31 @@
 	}
 }
 
-func osMutator(mctx BottomUpMutatorContext) {
+func osMutator(bpctx blueprint.BottomUpMutatorContext) {
 	var module Module
 	var ok bool
-	if module, ok = mctx.Module().(Module); !ok {
+	if module, ok = bpctx.Module().(Module); !ok {
+		if bootstrap.IsBootstrapModule(bpctx.Module()) {
+			// Bootstrap Go modules are always the build OS or linux bionic.
+			config := bpctx.Config().(Config)
+			osNames := []string{config.BuildOSTarget.OsVariation()}
+			for _, hostCrossTarget := range config.Targets[LinuxBionic] {
+				if hostCrossTarget.Arch.ArchType == config.BuildOSTarget.Arch.ArchType {
+					osNames = append(osNames, hostCrossTarget.OsVariation())
+				}
+			}
+			osNames = FirstUniqueStrings(osNames)
+			bpctx.CreateVariations(osNames...)
+		}
 		return
 	}
 
+	// Bootstrap Go module support above requires this mutator to be a
+	// blueprint.BottomUpMutatorContext because android.BottomUpMutatorContext
+	// filters out non-Soong modules.  Now that we've handled them, create a
+	// normal android.BottomUpMutatorContext.
+	mctx := bottomUpMutatorContextFactory(bpctx, module, false)
+
 	base := module.base()
 
 	if !base.ArchSpecific() {
@@ -828,13 +847,23 @@
 //
 // Modules can be initialized with InitAndroidMultiTargetsArchModule, in which case they will be split by OsClass,
 // but will have a common Target that is expected to handle all other selected Targets via ctx.MultiTargets().
-func archMutator(mctx BottomUpMutatorContext) {
+func archMutator(bpctx blueprint.BottomUpMutatorContext) {
 	var module Module
 	var ok bool
-	if module, ok = mctx.Module().(Module); !ok {
+	if module, ok = bpctx.Module().(Module); !ok {
+		if bootstrap.IsBootstrapModule(bpctx.Module()) {
+			// Bootstrap Go modules are always the build architecture.
+			bpctx.CreateVariations(bpctx.Config().(Config).BuildOSTarget.ArchVariation())
+		}
 		return
 	}
 
+	// Bootstrap Go module support above requires this mutator to be a
+	// blueprint.BottomUpMutatorContext because android.BottomUpMutatorContext
+	// filters out non-Soong modules.  Now that we've handled them, create a
+	// normal android.BottomUpMutatorContext.
+	mctx := bottomUpMutatorContextFactory(bpctx, module, false)
+
 	base := module.base()
 
 	if !base.ArchSpecific() {
@@ -912,7 +941,7 @@
 	modules := mctx.CreateVariations(targetNames...)
 	for i, m := range modules {
 		addTargetProperties(m, targets[i], multiTargets, i == 0)
-		m.(Module).base().setArchProperties(mctx)
+		m.base().setArchProperties(mctx)
 	}
 }
 
diff --git a/android/module.go b/android/module.go
index 046c0a0..bfb87fa 100644
--- a/android/module.go
+++ b/android/module.go
@@ -247,6 +247,7 @@
 	Disable()
 	Enabled() bool
 	Target() Target
+	Owner() string
 	InstallInData() bool
 	InstallInTestcases() bool
 	InstallInSanitizerDir() bool
diff --git a/android/mutator.go b/android/mutator.go
index 40e61de..5212553 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -75,6 +75,7 @@
 type RegisterMutatorsContext interface {
 	TopDown(name string, m TopDownMutator) MutatorHandle
 	BottomUp(name string, m BottomUpMutator) MutatorHandle
+	BottomUpBlueprint(name string, m blueprint.BottomUpMutator) MutatorHandle
 }
 
 type RegisterMutatorFunc func(RegisterMutatorsContext)
@@ -143,9 +144,9 @@
 }
 
 func registerArchMutator(ctx RegisterMutatorsContext) {
-	ctx.BottomUp("os", osMutator).Parallel()
+	ctx.BottomUpBlueprint("os", osMutator).Parallel()
 	ctx.BottomUp("image", imageMutator).Parallel()
-	ctx.BottomUp("arch", archMutator).Parallel()
+	ctx.BottomUpBlueprint("arch", archMutator).Parallel()
 }
 
 var preDeps = []RegisterMutatorFunc{
@@ -225,16 +226,21 @@
 	finalPhase bool
 }
 
+func bottomUpMutatorContextFactory(ctx blueprint.BottomUpMutatorContext, a Module,
+	finalPhase bool) BottomUpMutatorContext {
+
+	return &bottomUpMutatorContext{
+		bp:                ctx,
+		baseModuleContext: a.base().baseModuleContextFactory(ctx),
+		finalPhase:        finalPhase,
+	}
+}
+
 func (x *registerMutatorsContext) BottomUp(name string, m BottomUpMutator) MutatorHandle {
 	finalPhase := x.finalPhase
 	f := func(ctx blueprint.BottomUpMutatorContext) {
 		if a, ok := ctx.Module().(Module); ok {
-			actx := &bottomUpMutatorContext{
-				bp:                ctx,
-				baseModuleContext: a.base().baseModuleContextFactory(ctx),
-				finalPhase:        finalPhase,
-			}
-			m(actx)
+			m(bottomUpMutatorContextFactory(ctx, a, finalPhase))
 		}
 	}
 	mutator := &mutator{name: name, bottomUpMutator: f}
@@ -242,6 +248,12 @@
 	return mutator
 }
 
+func (x *registerMutatorsContext) BottomUpBlueprint(name string, m blueprint.BottomUpMutator) MutatorHandle {
+	mutator := &mutator{name: name, bottomUpMutator: m}
+	x.mutators = append(x.mutators, mutator)
+	return mutator
+}
+
 func (x *registerMutatorsContext) TopDown(name string, m TopDownMutator) MutatorHandle {
 	f := func(ctx blueprint.TopDownMutatorContext) {
 		if a, ok := ctx.Module().(Module); ok {
diff --git a/android/neverallow.go b/android/neverallow.go
index aaea920..8b8e1ac 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -199,6 +199,7 @@
 		"prebuilts/ndk",
 		"tools/test/graphicsbenchmark/apps/sample_app",
 		"tools/test/graphicsbenchmark/functional_tests/java",
+		"vendor/xts/gts-tests/hostsidetests/gamedevicecert/apps/javatests",
 	}
 
 	platformVariantPropertiesAllowedList := []string{
@@ -274,6 +275,10 @@
 			continue
 		}
 
+		if !n.appliesToBootclasspathJar(ctx) {
+			continue
+		}
+
 		ctx.ModuleErrorf("violates " + n.String())
 	}
 }
@@ -332,6 +337,18 @@
 	return ".regexp(" + m.re.String() + ")"
 }
 
+type notInListMatcher struct {
+	allowed []string
+}
+
+func (m *notInListMatcher) Test(value string) bool {
+	return !InList(value, m.allowed)
+}
+
+func (m *notInListMatcher) String() string {
+	return ".not-in-list(" + strings.Join(m.allowed, ",") + ")"
+}
+
 type isSetMatcher struct{}
 
 func (m *isSetMatcher) Test(value string) bool {
@@ -363,6 +380,8 @@
 
 	NotModuleType(types ...string) Rule
 
+	BootclasspathJar() Rule
+
 	With(properties, value string) Rule
 
 	WithMatcher(properties string, matcher ValueMatcher) Rule
@@ -390,6 +409,8 @@
 
 	props       []ruleProperty
 	unlessProps []ruleProperty
+
+	onlyBootclasspathJar bool
 }
 
 // Create a new NeverAllow rule.
@@ -465,6 +486,11 @@
 	return r
 }
 
+func (r *rule) BootclasspathJar() Rule {
+	r.onlyBootclasspathJar = true
+	return r
+}
+
 func (r *rule) String() string {
 	s := "neverallow"
 	for _, v := range r.paths {
@@ -491,6 +517,9 @@
 	for _, v := range r.osClasses {
 		s += " os:" + v.String()
 	}
+	if r.onlyBootclasspathJar {
+		s += " inBcp"
+	}
 	if len(r.reason) != 0 {
 		s += " which is restricted because " + r.reason
 	}
@@ -519,6 +548,14 @@
 	return matches
 }
 
+func (r *rule) appliesToBootclasspathJar(ctx BottomUpMutatorContext) bool {
+	if !r.onlyBootclasspathJar {
+		return true
+	}
+
+	return InList(ctx.ModuleName(), ctx.Config().BootJars())
+}
+
 func (r *rule) appliesToOsClass(osClass OsClass) bool {
 	if len(r.osClasses) == 0 {
 		return true
@@ -555,6 +592,10 @@
 	return &regexMatcher{r}
 }
 
+func NotInList(allowed []string) ValueMatcher {
+	return &notInListMatcher{allowed}
+}
+
 // assorted utils
 
 func cleanPaths(paths []string) []string {
diff --git a/apex/androidmk.go b/apex/androidmk.go
index 5c6d6cc..af2ec3d 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -108,6 +108,9 @@
 			fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
 		}
 		fmt.Fprintln(w, "LOCAL_MODULE :=", moduleName)
+		if fi.module != nil && fi.module.Owner() != "" {
+			fmt.Fprintln(w, "LOCAL_MODULE_OWNER :=", fi.module.Owner())
+		}
 		// /apex/<apex_name>/{lib|framework|...}
 		pathWhenActivated := filepath.Join("$(PRODUCT_OUT)", "apex", apexName, fi.installDir)
 		var modulePath string
diff --git a/apex/apex.go b/apex/apex.go
index c95ee94..8c85555 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -100,6 +100,13 @@
 	//
 	// Module separator
 	//
+	m["com.android.appsearch"] = []string{
+		"icing-java-proto-lite",
+		"libprotobuf-java-lite",
+	}
+	//
+	// Module separator
+	//
 	m["com.android.bluetooth.updatable"] = []string{
 		"android.hardware.audio.common@5.0",
 		"android.hardware.bluetooth.a2dp@1.0",
@@ -182,6 +189,19 @@
 	//
 	// Module separator
 	//
+	m["com.android.extservices"] = []string{
+		"error_prone_annotations",
+		"ExtServices-core",
+		"ExtServices",
+		"libtextclassifier-java",
+		"libz_current",
+		"textclassifier-statsd",
+		"TextClassifierNotificationLibNoManifest",
+		"TextClassifierServiceLibNoManifest",
+	}
+	//
+	// Module separator
+	//
 	m["com.android.neuralnetworks"] = []string{
 		"android.hardware.neuralnetworks@1.0",
 		"android.hardware.neuralnetworks@1.1",
@@ -297,7 +317,6 @@
 		"libpdx_headers",
 		"libpdx_uds",
 		"libprocinfo",
-		"libsonivox",
 		"libspeexresampler",
 		"libspeexresampler",
 		"libstagefright_esds",
@@ -334,6 +353,7 @@
 		"android.hardware.configstore@1.1",
 		"android.hardware.graphics.allocator@2.0",
 		"android.hardware.graphics.allocator@3.0",
+		"android.hardware.graphics.allocator@4.0",
 		"android.hardware.graphics.bufferqueue@1.0",
 		"android.hardware.graphics.bufferqueue@2.0",
 		"android.hardware.graphics.common-ndk_platform",
@@ -346,6 +366,7 @@
 		"android.hardware.graphics.mapper@4.0",
 		"android.hardware.media.bufferpool@2.0",
 		"android.hardware.media.c2@1.0",
+		"android.hardware.media.c2@1.1",
 		"android.hardware.media.omx@1.0",
 		"android.hardware.media@1.0",
 		"android.hardware.media@1.0",
@@ -439,6 +460,7 @@
 		"libpdx_headers",
 		"libscudo_wrapper",
 		"libsfplugin_ccodec_utils",
+		"libspeexresampler",
 		"libstagefright_amrnb_common",
 		"libstagefright_amrnbdec",
 		"libstagefright_amrnbenc",
@@ -481,6 +503,8 @@
 	// Module separator
 	//
 	m["com.android.permission"] = []string{
+		"car-ui-lib",
+		"iconloader",
 		"kotlin-annotations",
 		"kotlin-stdlib",
 		"kotlin-stdlib-jdk7",
@@ -490,6 +514,17 @@
 		"kotlinx-coroutines-core",
 		"kotlinx-coroutines-core-nodeps",
 		"permissioncontroller-statsd",
+		"GooglePermissionController",
+		"PermissionController",
+		"SettingsLibActionBarShadow",
+		"SettingsLibAppPreference",
+		"SettingsLibBarChartPreference",
+		"SettingsLibLayoutPreference",
+		"SettingsLibProgressBar",
+		"SettingsLibSearchWidget",
+		"SettingsLibSettingsTheme",
+		"SettingsLibRestrictedLockUtils",
+		"SettingsLibHelpUtils",
 	}
 	//
 	// Module separator
@@ -648,6 +683,55 @@
 	return m
 }
 
+// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
+// Adding code to the bootclasspath in new packages will cause issues on module update.
+func qModulesPackages() map[string][]string {
+	return map[string][]string{
+		"com.android.conscrypt": []string{
+			"android.net.ssl",
+			"com.android.org.conscrypt",
+		},
+		"com.android.media": []string{
+			"android.media",
+		},
+	}
+}
+
+// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
+// Adding code to the bootclasspath in new packages will cause issues on module update.
+func rModulesPackages() map[string][]string {
+	return map[string][]string{
+		"com.android.mediaprovider": []string{
+			"android.provider",
+		},
+		"com.android.permission": []string{
+			"android.permission",
+			"android.app.role",
+			"com.android.permission",
+			"com.android.role",
+		},
+		"com.android.sdkext": []string{
+			"android.os.ext",
+		},
+		"com.android.os.statsd": []string{
+			"android.app",
+			"android.os",
+			"android.util",
+			"com.android.internal.statsd",
+			"com.android.server.stats",
+		},
+		"com.android.wifi": []string{
+			"com.android.server.wifi",
+			"com.android.wifi.x",
+			"android.hardware.wifi",
+			"android.net.wifi",
+		},
+		"com.android.tethering": []string{
+			"android.net",
+		},
+	}
+}
+
 func init() {
 	android.RegisterModuleType("apex", BundleFactory)
 	android.RegisterModuleType("apex_test", testApexBundleFactory)
@@ -665,6 +749,24 @@
 		sort.Strings(*apexFileContextsInfos)
 		ctx.Strict("APEX_FILE_CONTEXTS_INFOS", strings.Join(*apexFileContextsInfos, " "))
 	})
+
+	android.AddNeverAllowRules(createApexPermittedPackagesRules(qModulesPackages())...)
+	android.AddNeverAllowRules(createApexPermittedPackagesRules(rModulesPackages())...)
+}
+
+func createApexPermittedPackagesRules(modules_packages map[string][]string) []android.Rule {
+	rules := make([]android.Rule, 0, len(modules_packages))
+	for module_name, module_packages := range modules_packages {
+		permitted_packages_rule := android.NeverAllow().
+			BootclasspathJar().
+			With("apex_available", module_name).
+			WithMatcher("permitted_packages", android.NotInList(module_packages)).
+			Because("jars that are part of the " + module_name +
+				" module may only allow these packages: " + strings.Join(module_packages, ",") +
+				". Please jarjar or move code around.")
+		rules = append(rules, permitted_packages_rule)
+	}
+	return rules
 }
 
 func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
@@ -1971,13 +2073,6 @@
 				return false
 			}
 
-			// TODO(jiyong) remove this check when R is published to AOSP. Currently, libstatssocket
-			// is capable of providing a stub variant, but is being statically linked from the bluetooth
-			// APEX.
-			if toName == "libstatssocket" {
-				return false
-			}
-
 			// The dynamic linker and crash_dump tool in the runtime APEX is the only exception to this rule.
 			// It can't make the static dependencies dynamic because it can't
 			// do the dynamic linking for itself.
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 2950c6a..610f667 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -5740,6 +5740,141 @@
 	})
 }
 
+func testApexPermittedPackagesRules(t *testing.T, errmsg, bp string, apexBootJars []string, rules []android.Rule) {
+	t.Helper()
+	android.ClearApexDependency()
+	bp += `
+	apex_key {
+		name: "myapex.key",
+		public_key: "testkey.avbpubkey",
+		private_key: "testkey.pem",
+	}`
+	fs := map[string][]byte{
+		"lib1/src/A.java": nil,
+		"lib2/src/B.java": nil,
+		"system/sepolicy/apex/myapex-file_contexts": nil,
+	}
+
+	ctx := android.NewTestArchContext()
+	ctx.RegisterModuleType("apex", BundleFactory)
+	ctx.RegisterModuleType("apex_key", ApexKeyFactory)
+	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
+	cc.RegisterRequiredBuildComponentsForTest(ctx)
+	java.RegisterJavaBuildComponents(ctx)
+	java.RegisterSystemModulesBuildComponents(ctx)
+	java.RegisterDexpreoptBootJarsComponents(ctx)
+	ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
+	ctx.PreDepsMutators(RegisterPreDepsMutators)
+	ctx.PostDepsMutators(RegisterPostDepsMutators)
+	ctx.PostDepsMutators(android.RegisterNeverallowMutator)
+
+	config := android.TestArchConfig(buildDir, nil, bp, fs)
+	android.SetTestNeverallowRules(config, rules)
+	updatableBootJars := make([]string, 0, len(apexBootJars))
+	for _, apexBootJar := range apexBootJars {
+		updatableBootJars = append(updatableBootJars, "myapex:"+apexBootJar)
+	}
+	config.TestProductVariables.UpdatableBootJars = updatableBootJars
+
+	ctx.Register(config)
+
+	_, errs := ctx.ParseBlueprintsFiles("Android.bp")
+	android.FailIfErrored(t, errs)
+
+	_, errs = ctx.PrepareBuildActions(config)
+	if errmsg == "" {
+		android.FailIfErrored(t, errs)
+	} else if len(errs) > 0 {
+		android.FailIfNoMatchingErrors(t, errmsg, errs)
+		return
+	} else {
+		t.Fatalf("missing expected error %q (0 errors are returned)", errmsg)
+	}
+}
+
+func TestApexPermittedPackagesRules(t *testing.T) {
+	testcases := []struct {
+		name            string
+		expectedError   string
+		bp              string
+		bootJars        []string
+		modulesPackages map[string][]string
+	}{
+
+		{
+			name:          "Non-Bootclasspath apex jar not satisfying allowed module packages.",
+			expectedError: "",
+			bp: `
+				java_library {
+					name: "bcp_lib1",
+					srcs: ["lib1/src/*.java"],
+					permitted_packages: ["foo.bar"],
+					apex_available: ["myapex"],
+					sdk_version: "none",
+					system_modules: "none",
+				}
+				java_library {
+					name: "nonbcp_lib2",
+					srcs: ["lib2/src/*.java"],
+					apex_available: ["myapex"],
+					permitted_packages: ["a.b"],
+					sdk_version: "none",
+					system_modules: "none",
+				}
+				apex {
+					name: "myapex",
+					key: "myapex.key",
+					java_libs: ["bcp_lib1", "nonbcp_lib2"],
+				}`,
+			bootJars: []string{"bcp_lib1"},
+			modulesPackages: map[string][]string{
+				"myapex": []string{
+					"foo.bar",
+				},
+			},
+		},
+		{
+			name:          "Bootclasspath apex jar not satisfying allowed module packages.",
+			expectedError: `module "bcp_lib2" .* which is restricted because jars that are part of the myapex module may only allow these packages: foo.bar. Please jarjar or move code around.`,
+			bp: `
+				java_library {
+					name: "bcp_lib1",
+					srcs: ["lib1/src/*.java"],
+					apex_available: ["myapex"],
+					permitted_packages: ["foo.bar"],
+					sdk_version: "none",
+					system_modules: "none",
+				}
+				java_library {
+					name: "bcp_lib2",
+					srcs: ["lib2/src/*.java"],
+					apex_available: ["myapex"],
+					permitted_packages: ["foo.bar", "bar.baz"],
+					sdk_version: "none",
+					system_modules: "none",
+				}
+				apex {
+					name: "myapex",
+					key: "myapex.key",
+					java_libs: ["bcp_lib1", "bcp_lib2"],
+				}
+			`,
+			bootJars: []string{"bcp_lib1", "bcp_lib2"},
+			modulesPackages: map[string][]string{
+				"myapex": []string{
+					"foo.bar",
+				},
+			},
+		},
+	}
+	for _, tc := range testcases {
+		t.Run(tc.name, func(t *testing.T) {
+			rules := createApexPermittedPackagesRules(tc.modulesPackages)
+			testApexPermittedPackagesRules(t, tc.expectedError, tc.bp, tc.bootJars, rules)
+		})
+	}
+}
+
 func TestTestFor(t *testing.T) {
 	ctx, _ := testApex(t, `
 		apex {
@@ -5807,8 +5942,10 @@
 		}
 	`, func(fs map[string][]byte, config android.Config) {
 		config.TestProductVariables.Platform_sdk_version = intPtr(30)
-		config.TestProductVariables.DeviceArch = proptools.StringPtr("arm")
-		config.TestProductVariables.DeviceSecondaryArch = proptools.StringPtr("arm64")
+		config.Targets[android.Android] = []android.Target{
+			{Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}},
+			{Os: android.Android, Arch: android.Arch{ArchType: android.Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}},
+		}
 	})
 
 	m := ctx.ModuleForTests("myapex", "android_common")
diff --git a/apex/builder.go b/apex/builder.go
index 26afb04..c5680ad 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -656,7 +656,7 @@
 		a.container_certificate_file,
 		a.container_private_key_file,
 	}
-	if ctx.Config().IsEnvTrue("RBE_SIGNAPK") {
+	if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_SIGNAPK") {
 		rule = java.SignapkRE
 		args["implicits"] = strings.Join(implicits.Strings(), ",")
 		args["outCommaList"] = a.outputFile.String()
@@ -690,7 +690,7 @@
 	apexBundleName := a.Name()
 	a.outputFile = android.PathForModuleInstall(&factx, "apex", apexBundleName)
 
-	if a.installable() && a.GetOverriddenBy() == "" {
+	if a.installable() {
 		installPath := android.PathForModuleInstall(ctx, "apex", apexBundleName)
 		devicePath := android.InstallPathToOnDevicePath(ctx, installPath)
 		addFlattenedFileContextsInfos(ctx, apexBundleName+":"+devicePath+":"+a.fileContexts.String())
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index d459f87..37457e9 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -257,6 +257,9 @@
 	// list of commands to create symlinks for backward compatibility.
 	// these commands will be attached as LOCAL_POST_INSTALL_CMD
 	compatSymlinks []string
+
+	hostRequired        []string
+	postInstallCommands []string
 }
 
 type ApexSetProperties struct {
@@ -343,21 +346,43 @@
 	for _, overridden := range a.properties.Overrides {
 		a.compatSymlinks = append(a.compatSymlinks, makeCompatSymlinks(overridden, ctx)...)
 	}
+
+	if ctx.Config().InstallExtraFlattenedApexes() {
+		// flattened apex should be in /system_ext/apex
+		flattenedApexDir := android.PathForModuleInstall(&systemExtContext{ctx}, "apex", a.BaseModuleName())
+		a.postInstallCommands = append(a.postInstallCommands,
+			fmt.Sprintf("$(HOST_OUT_EXECUTABLES)/deapexer --debugfs_path $(HOST_OUT_EXECUTABLES)/debugfs extract %s %s",
+				a.outputApex.String(),
+				flattenedApexDir.ToMakePath().String(),
+			))
+		a.hostRequired = []string{"deapexer", "debugfs"}
+	}
+}
+
+type systemExtContext struct {
+	android.ModuleContext
+}
+
+func (*systemExtContext) SystemExtSpecific() bool {
+	return true
 }
 
 func (a *ApexSet) AndroidMkEntries() []android.AndroidMkEntries {
 	return []android.AndroidMkEntries{android.AndroidMkEntries{
-		Class:      "ETC",
-		OutputFile: android.OptionalPathForPath(a.outputApex),
-		Include:    "$(BUILD_PREBUILT)",
+		Class:         "ETC",
+		OutputFile:    android.OptionalPathForPath(a.outputApex),
+		Include:       "$(BUILD_PREBUILT)",
+		Host_required: a.hostRequired,
 		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
 			func(entries *android.AndroidMkEntries) {
 				entries.SetString("LOCAL_MODULE_PATH", a.installDir.ToMakePath().String())
 				entries.SetString("LOCAL_MODULE_STEM", a.installFilename)
 				entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !a.installable())
 				entries.AddStrings("LOCAL_OVERRIDES_MODULES", a.properties.Overrides...)
-				if len(a.compatSymlinks) > 0 {
-					entries.SetString("LOCAL_POST_INSTALL_CMD", strings.Join(a.compatSymlinks, " && "))
+				postInstallCommands := append([]string{}, a.postInstallCommands...)
+				postInstallCommands = append(postInstallCommands, a.compatSymlinks...)
+				if len(postInstallCommands) > 0 {
+					entries.SetString("LOCAL_POST_INSTALL_CMD", strings.Join(postInstallCommands, " && "))
 				}
 			},
 		},
diff --git a/cc/builder.go b/cc/builder.go
index 81d2f1e..ef65348 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -584,7 +584,7 @@
 			tidyFiles = append(tidyFiles, tidyFile)
 
 			rule := clangTidy
-			if ctx.Config().IsEnvTrue("RBE_CLANG_TIDY") {
+			if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_CLANG_TIDY") {
 				rule = clangTidyRE
 			}
 
@@ -610,7 +610,7 @@
 			sAbiDumpFiles = append(sAbiDumpFiles, sAbiDumpFile)
 
 			dumpRule := sAbiDump
-			if ctx.Config().IsEnvTrue("RBE_ABI_DUMPER") {
+			if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_ABI_DUMPER") {
 				dumpRule = sAbiDumpRE
 			}
 			ctx.Build(pctx, android.BuildParams{
@@ -745,7 +745,7 @@
 		"ldFlags":       flags.globalLdFlags + " " + flags.localLdFlags,
 		"crtEnd":        crtEnd.String(),
 	}
-	if ctx.Config().IsEnvTrue("RBE_CXX_LINKS") {
+	if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_CXX_LINKS") {
 		rule = ldRE
 		args["implicitOutputs"] = strings.Join(implicitOutputs.Strings(), ",")
 		args["implicitInputs"] = strings.Join(deps.Strings(), ",")
@@ -789,7 +789,7 @@
 		"arch":                ctx.Arch().ArchType.Name,
 		"exportedHeaderFlags": exportedHeaderFlags,
 	}
-	if ctx.Config().IsEnvTrue("RBE_ABI_LINKER") {
+	if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_ABI_LINKER") {
 		rule = sAbiLinkRE
 		rbeImplicits := implicits.Strings()
 		for _, p := range strings.Split(exportedHeaderFlags, " ") {
@@ -912,7 +912,7 @@
 		"ldCmd":   ldCmd,
 		"ldFlags": flags.globalLdFlags + " " + flags.localLdFlags,
 	}
-	if ctx.Config().IsEnvTrue("RBE_CXX_LINKS") {
+	if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_CXX_LINKS") {
 		rule = partialLdRE
 		args["inCommaList"] = strings.Join(objFiles.Strings(), ",")
 		args["implicitInputs"] = strings.Join(deps.Strings(), ",")
diff --git a/cc/config/vndk.go b/cc/config/vndk.go
index 54f693e..6f2e807 100644
--- a/cc/config/vndk.go
+++ b/cc/config/vndk.go
@@ -18,10 +18,12 @@
 // For these libraries, the vendor variants must be installed even if the device
 // has VndkUseCoreVariant set.
 var VndkMustUseVendorVariantList = []string{
+	"android.hardware.automotive.occupant_awareness-ndk_platform",
 	"android.hardware.light-ndk_platform",
 	"android.hardware.identity-ndk_platform",
 	"android.hardware.nfc@1.2",
 	"android.hardware.power-ndk_platform",
+	"android.hardware.rebootescrow-ndk_platform",
 	"android.hardware.vibrator-ndk_platform",
 	"libbinder",
 	"libcrypto",
diff --git a/cc/config/x86_windows_host.go b/cc/config/x86_windows_host.go
index cd0a508..b5b5553 100644
--- a/cc/config/x86_windows_host.go
+++ b/cc/config/x86_windows_host.go
@@ -49,7 +49,11 @@
 
 	windowsClangCppflags = []string{}
 
-	windowsX86ClangCppflags = []string{}
+	windowsX86ClangCppflags = []string{
+		// Use SjLj exceptions for 32-bit.  libgcc_eh implements SjLj
+		// exception model for 32-bit.
+		"-fsjlj-exceptions",
+	}
 
 	windowsX8664ClangCppflags = []string{}
 
diff --git a/cc/sanitize.go b/cc/sanitize.go
index cee9d84..174dcfe 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -48,6 +48,10 @@
 		// higher number of "optimized out" stack variables.
 		// b/112437883.
 		"-mllvm", "-instcombine-lower-dbg-declare=0",
+		// TODO(b/159343917): HWASan and GlobalISel don't play nicely, and
+		// GlobalISel is the default at -O0 on aarch64.
+		"-mllvm", "--aarch64-enable-global-isel-at-O=-1",
+		"-mllvm", "-fast-isel=false",
 	}
 
 	cfiCflags = []string{"-flto", "-fsanitize-cfi-cross-dso",
diff --git a/cc/stl.go b/cc/stl.go
index 4e74c7f..e18fe95 100644
--- a/cc/stl.go
+++ b/cc/stl.go
@@ -239,11 +239,6 @@
 			flags.Local.CppFlags = append(flags.Local.CppFlags, "-nostdinc++")
 			flags.extraLibFlags = append(flags.extraLibFlags, "-nostdlib++")
 			if ctx.Windows() {
-				// Use SjLj exceptions for 32-bit.  libgcc_eh implements SjLj
-				// exception model for 32-bit.
-				if ctx.Arch().ArchType == android.X86 {
-					flags.Local.CppFlags = append(flags.Local.CppFlags, "-fsjlj-exceptions")
-				}
 				flags.Local.CppFlags = append(flags.Local.CppFlags,
 					// Disable visiblity annotations since we're using static
 					// libc++.
diff --git a/java/androidmk.go b/java/androidmk.go
index a503d2a..65c44a3 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -509,53 +509,14 @@
 func (ddoc *Droiddoc) AndroidMkEntries() []android.AndroidMkEntries {
 	return []android.AndroidMkEntries{android.AndroidMkEntries{
 		Class:      "JAVA_LIBRARIES",
-		OutputFile: android.OptionalPathForPath(ddoc.stubsSrcJar),
+		OutputFile: android.OptionalPathForPath(ddoc.Javadoc.docZip),
 		Include:    "$(BUILD_SYSTEM)/soong_droiddoc_prebuilt.mk",
 		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
 			func(entries *android.AndroidMkEntries) {
-				if BoolDefault(ddoc.Javadoc.properties.Installable, true) && ddoc.Javadoc.docZip != nil {
+				if ddoc.Javadoc.docZip != nil {
 					entries.SetPath("LOCAL_DROIDDOC_DOC_ZIP", ddoc.Javadoc.docZip)
 				}
-				if ddoc.Javadoc.stubsSrcJar != nil {
-					entries.SetPath("LOCAL_DROIDDOC_STUBS_SRCJAR", ddoc.Javadoc.stubsSrcJar)
-				}
-			},
-		},
-		ExtraFooters: []android.AndroidMkExtraFootersFunc{
-			func(w io.Writer, name, prefix, moduleDir string, entries *android.AndroidMkEntries) {
-				if ddoc.checkCurrentApiTimestamp != nil {
-					fmt.Fprintln(w, ".PHONY:", ddoc.Name()+"-check-current-api")
-					fmt.Fprintln(w, ddoc.Name()+"-check-current-api:",
-						ddoc.checkCurrentApiTimestamp.String())
-
-					fmt.Fprintln(w, ".PHONY: checkapi")
-					fmt.Fprintln(w, "checkapi:",
-						ddoc.checkCurrentApiTimestamp.String())
-
-					fmt.Fprintln(w, ".PHONY: droidcore")
-					fmt.Fprintln(w, "droidcore: checkapi")
-				}
-				if ddoc.updateCurrentApiTimestamp != nil {
-					fmt.Fprintln(w, ".PHONY:", ddoc.Name()+"-update-current-api")
-					fmt.Fprintln(w, ddoc.Name()+"-update-current-api:",
-						ddoc.updateCurrentApiTimestamp.String())
-
-					fmt.Fprintln(w, ".PHONY: update-api")
-					fmt.Fprintln(w, "update-api:",
-						ddoc.updateCurrentApiTimestamp.String())
-				}
-				if ddoc.checkLastReleasedApiTimestamp != nil {
-					fmt.Fprintln(w, ".PHONY:", ddoc.Name()+"-check-last-released-api")
-					fmt.Fprintln(w, ddoc.Name()+"-check-last-released-api:",
-						ddoc.checkLastReleasedApiTimestamp.String())
-
-					fmt.Fprintln(w, ".PHONY: checkapi")
-					fmt.Fprintln(w, "checkapi:",
-						ddoc.checkLastReleasedApiTimestamp.String())
-
-					fmt.Fprintln(w, ".PHONY: droidcore")
-					fmt.Fprintln(w, "droidcore: checkapi")
-				}
+				entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !BoolDefault(ddoc.Javadoc.properties.Installable, true))
 			},
 		},
 	}}
diff --git a/java/app.go b/java/app.go
index 406894d..dbc09e9 100755
--- a/java/app.go
+++ b/java/app.go
@@ -118,17 +118,17 @@
 }
 
 func SupportedAbis(ctx android.ModuleContext) []string {
-	abiName := func(archVar string, deviceArch string) string {
+	abiName := func(targetIdx int, deviceArch string) string {
 		if abi, found := TargetCpuAbi[deviceArch]; found {
 			return abi
 		}
-		ctx.ModuleErrorf("Invalid %s: %s", archVar, deviceArch)
+		ctx.ModuleErrorf("Target %d has invalid Arch: %s", targetIdx, deviceArch)
 		return "BAD_ABI"
 	}
 
-	result := []string{abiName("TARGET_ARCH", ctx.DeviceConfig().DeviceArch())}
-	if s := ctx.DeviceConfig().DeviceSecondaryArch(); s != "" {
-		result = append(result, abiName("TARGET_2ND_ARCH", s))
+	var result []string
+	for i, target := range ctx.Config().Targets[android.Android] {
+		result = append(result, abiName(i, target.Arch.ArchType.String()))
 	}
 	return result
 }
@@ -268,6 +268,9 @@
 
 	// the logging parent of this app.
 	Logging_parent *string
+
+	// Whether to rename the package in resources to the override name rather than the base name. Defaults to true.
+	Rename_resources_package *bool
 }
 
 // runtime_resource_overlay properties that can be overridden by override_runtime_resource_overlay
@@ -505,10 +508,23 @@
 		!a.IsForPlatform() || a.appProperties.AlwaysPackageNativeLibs
 }
 
+func generateAaptRenamePackageFlags(packageName string, renameResourcesPackage bool) []string {
+	aaptFlags := []string{"--rename-manifest-package " + packageName}
+	if renameResourcesPackage {
+		// Required to rename the package name in the resources table.
+		aaptFlags = append(aaptFlags, "--rename-resources-package "+packageName)
+	}
+	return aaptFlags
+}
+
 func (a *AndroidApp) OverriddenManifestPackageName() string {
 	return a.overriddenManifestPackageName
 }
 
+func (a *AndroidApp) renameResourcesPackage() bool {
+	return proptools.BoolDefault(a.overridableAppProperties.Rename_resources_package, true)
+}
+
 func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
 	a.aapt.usesNonSdkApis = Bool(a.Module.deviceProperties.Platform_apis)
 
@@ -541,7 +557,7 @@
 		if !overridden {
 			manifestPackageName = *a.overridableAppProperties.Package_name
 		}
-		aaptLinkFlags = append(aaptLinkFlags, "--rename-manifest-package "+manifestPackageName)
+		aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, a.renameResourcesPackage())...)
 		a.overriddenManifestPackageName = manifestPackageName
 	}
 
@@ -801,18 +817,32 @@
 
 	// Build a final signed app package.
 	packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk")
+	v4SigningRequested := Bool(a.Module.deviceProperties.V4_signature)
+	var v4SignatureFile android.WritablePath = nil
+	if v4SigningRequested {
+		v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+".apk.idsig")
+	}
 	var lineageFile android.Path
 	if lineage := String(a.overridableAppProperties.Lineage); lineage != "" {
 		lineageFile = android.PathForModuleSrc(ctx, lineage)
 	}
-	CreateAndSignAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates, apkDeps, lineageFile)
+	CreateAndSignAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile)
 	a.outputFile = packageFile
+	if v4SigningRequested {
+		a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
+	}
 
 	for _, split := range a.aapt.splits {
 		// Sign the split APKs
 		packageFile := android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk")
-		CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, lineageFile)
+		if v4SigningRequested {
+			v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig")
+		}
+		CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile)
 		a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
+		if v4SigningRequested {
+			a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
+		}
 	}
 
 	// Build an app bundle.
@@ -1528,7 +1558,7 @@
 		if lineage := String(a.properties.Lineage); lineage != "" {
 			lineageFile = android.PathForModuleSrc(ctx, lineage)
 		}
-		SignAppPackage(ctx, signed, dexOutput, certificates, lineageFile)
+		SignAppPackage(ctx, signed, dexOutput, certificates, nil, lineageFile)
 		a.outputFile = signed
 	} else {
 		alignedApk := android.PathForModuleOut(ctx, "zip-aligned", apkFilename)
@@ -1801,7 +1831,7 @@
 		if !overridden {
 			manifestPackageName = *r.overridableProperties.Package_name
 		}
-		aaptLinkFlags = append(aaptLinkFlags, "--rename-manifest-package "+manifestPackageName)
+		aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, false)...)
 	}
 	if r.overridableProperties.Target_package_name != nil {
 		aaptLinkFlags = append(aaptLinkFlags,
@@ -1817,7 +1847,7 @@
 	if lineage := String(r.properties.Lineage); lineage != "" {
 		lineageFile = android.PathForModuleSrc(ctx, lineage)
 	}
-	SignAppPackage(ctx, signed, r.aapt.exportPackage, certificates, lineageFile)
+	SignAppPackage(ctx, signed, r.aapt.exportPackage, certificates, nil, lineageFile)
 	r.certificate = certificates[0]
 
 	r.outputFile = signed
@@ -1883,8 +1913,10 @@
 	// to true if either uses_libs or optional_uses_libs is set.  Will unconditionally default to true in the future.
 	Enforce_uses_libs *bool
 
-	// If the library itself is a uses-library (this is needed for non-SDK libraries).
-	Is_uses_lib *bool
+	// Optional name of the <uses-library> provided by this module. This is needed for non-SDK
+	// libraries, because SDK ones are automatically picked up by Soong. The <uses-library> name
+	// normally is the same as the module name, but there are exceptions.
+	Provides_uses_lib *string
 }
 
 // usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the
diff --git a/java/app_builder.go b/java/app_builder.go
index 014bd54..69e462c 100644
--- a/java/app_builder.go
+++ b/java/app_builder.go
@@ -52,7 +52,7 @@
 	})
 
 func CreateAndSignAppPackage(ctx android.ModuleContext, outputFile android.WritablePath,
-	packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate, deps android.Paths, lineageFile android.Path) {
+	packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate, deps android.Paths, v4SignatureFile android.WritablePath, lineageFile android.Path) {
 
 	unsignedApkName := strings.TrimSuffix(outputFile.Base(), ".apk") + "-unsigned.apk"
 	unsignedApk := android.PathForModuleOut(ctx, unsignedApkName)
@@ -73,10 +73,10 @@
 		Implicits: deps,
 	})
 
-	SignAppPackage(ctx, outputFile, unsignedApk, certificates, lineageFile)
+	SignAppPackage(ctx, outputFile, unsignedApk, certificates, v4SignatureFile, lineageFile)
 }
 
-func SignAppPackage(ctx android.ModuleContext, signedApk android.WritablePath, unsignedApk android.Path, certificates []Certificate, lineageFile android.Path) {
+func SignAppPackage(ctx android.ModuleContext, signedApk android.WritablePath, unsignedApk android.Path, certificates []Certificate, v4SignatureFile android.WritablePath, lineageFile android.Path) {
 
 	var certificateArgs []string
 	var deps android.Paths
@@ -87,6 +87,11 @@
 
 	outputFiles := android.WritablePaths{signedApk}
 	var flags []string
+	if v4SignatureFile != nil {
+		outputFiles = append(outputFiles, v4SignatureFile)
+		flags = append(flags, "--enable-v4")
+	}
+
 	if lineageFile != nil {
 		flags = append(flags, "--lineage", lineageFile.String())
 		deps = append(deps, lineageFile)
@@ -97,7 +102,7 @@
 		"certificates": strings.Join(certificateArgs, " "),
 		"flags":        strings.Join(flags, " "),
 	}
-	if ctx.Config().IsEnvTrue("RBE_SIGNAPK") {
+	if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_SIGNAPK") {
 		rule = SignapkRE
 		args["implicits"] = strings.Join(deps.Strings(), ",")
 		args["outCommaList"] = strings.Join(outputFiles.Strings(), ",")
@@ -236,7 +241,7 @@
 	args := map[string]string{
 		"jarArgs": strings.Join(proptools.NinjaAndShellEscapeList(jarArgs), " "),
 	}
-	if ctx.Config().IsEnvTrue("RBE_ZIP") {
+	if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_ZIP") {
 		rule = zipRE
 		args["implicits"] = strings.Join(deps.Strings(), ",")
 	}
diff --git a/java/app_test.go b/java/app_test.go
index b8d8616..5367971 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -176,16 +176,17 @@
 			set: "prebuilts/apks/app.apks",
 		}`
 	testCases := []struct {
-		name                string
-		deviceArch          *string
-		deviceSecondaryArch *string
-		aaptPrebuiltDPI     []string
-		sdkVersion          int
-		expected            map[string]string
+		name            string
+		targets         []android.Target
+		aaptPrebuiltDPI []string
+		sdkVersion      int
+		expected        map[string]string
 	}{
 		{
-			name:            "One",
-			deviceArch:      proptools.StringPtr("x86"),
+			name: "One",
+			targets: []android.Target{
+				{Os: android.Android, Arch: android.Arch{ArchType: android.X86}},
+			},
 			aaptPrebuiltDPI: []string{"ldpi", "xxhdpi"},
 			sdkVersion:      29,
 			expected: map[string]string{
@@ -197,11 +198,13 @@
 			},
 		},
 		{
-			name:                "Two",
-			deviceArch:          proptools.StringPtr("x86_64"),
-			deviceSecondaryArch: proptools.StringPtr("x86"),
-			aaptPrebuiltDPI:     nil,
-			sdkVersion:          30,
+			name: "Two",
+			targets: []android.Target{
+				{Os: android.Android, Arch: android.Arch{ArchType: android.X86_64}},
+				{Os: android.Android, Arch: android.Arch{ArchType: android.X86}},
+			},
+			aaptPrebuiltDPI: nil,
+			sdkVersion:      30,
 			expected: map[string]string{
 				"abis":              "X86_64,X86",
 				"allow-prereleased": "false",
@@ -216,8 +219,7 @@
 		config := testAppConfig(nil, bp, nil)
 		config.TestProductVariables.AAPTPrebuiltDPI = test.aaptPrebuiltDPI
 		config.TestProductVariables.Platform_sdk_version = &test.sdkVersion
-		config.TestProductVariables.DeviceArch = test.deviceArch
-		config.TestProductVariables.DeviceSecondaryArch = test.deviceSecondaryArch
+		config.Targets[android.Android] = test.targets
 		ctx := testContext()
 		run(t, ctx, config)
 		module := ctx.ModuleForTests("foo", "android_common")
@@ -1655,6 +1657,66 @@
 	}
 }
 
+func TestRequestV4SigningFlag(t *testing.T) {
+	testCases := []struct {
+		name     string
+		bp       string
+		expected string
+	}{
+		{
+			name: "default",
+			bp: `
+				android_app {
+					name: "foo",
+					srcs: ["a.java"],
+					sdk_version: "current",
+				}
+			`,
+			expected: "",
+		},
+		{
+			name: "default",
+			bp: `
+				android_app {
+					name: "foo",
+					srcs: ["a.java"],
+					sdk_version: "current",
+					v4_signature: false,
+				}
+			`,
+			expected: "",
+		},
+		{
+			name: "module certificate property",
+			bp: `
+				android_app {
+					name: "foo",
+					srcs: ["a.java"],
+					sdk_version: "current",
+					v4_signature: true,
+				}
+			`,
+			expected: "--enable-v4",
+		},
+	}
+
+	for _, test := range testCases {
+		t.Run(test.name, func(t *testing.T) {
+			config := testAppConfig(nil, test.bp, nil)
+			ctx := testContext()
+
+			run(t, ctx, config)
+			foo := ctx.ModuleForTests("foo", "android_common")
+
+			signapk := foo.Output("foo.apk")
+			signFlags := signapk.Args["flags"]
+			if test.expected != signFlags {
+				t.Errorf("Incorrect signing flags, expected: %q, got: %q", test.expected, signFlags)
+			}
+		})
+	}
+}
+
 func TestPackageNameOverride(t *testing.T) {
 	testCases := []struct {
 		name                string
@@ -1777,52 +1839,125 @@
 			base: "foo",
 			package_name: "org.dandroid.bp",
 		}
+
+		override_android_app {
+			name: "baz_no_rename_resources",
+			base: "foo",
+			package_name: "org.dandroid.bp",
+			rename_resources_package: false,
+		}
+
+		android_app {
+			name: "foo_no_rename_resources",
+			srcs: ["a.java"],
+			certificate: "expiredkey",
+			overrides: ["qux"],
+			rename_resources_package: false,
+			sdk_version: "current",
+		}
+
+		override_android_app {
+			name: "baz_base_no_rename_resources",
+			base: "foo_no_rename_resources",
+			package_name: "org.dandroid.bp",
+		}
+
+		override_android_app {
+			name: "baz_override_base_rename_resources",
+			base: "foo_no_rename_resources",
+			package_name: "org.dandroid.bp",
+			rename_resources_package: true,
+		}
 		`)
 
 	expectedVariants := []struct {
-		moduleName     string
-		variantName    string
-		apkName        string
-		apkPath        string
-		certFlag       string
-		lineageFlag    string
-		overrides      []string
-		aaptFlag       string
-		logging_parent string
+		name            string
+		moduleName      string
+		variantName     string
+		apkName         string
+		apkPath         string
+		certFlag        string
+		lineageFlag     string
+		overrides       []string
+		packageFlag     string
+		renameResources bool
+		logging_parent  string
 	}{
 		{
-			moduleName:     "foo",
-			variantName:    "android_common",
-			apkPath:        "/target/product/test_device/system/app/foo/foo.apk",
-			certFlag:       "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
-			lineageFlag:    "",
-			overrides:      []string{"qux"},
-			aaptFlag:       "",
-			logging_parent: "",
+			name:            "foo",
+			moduleName:      "foo",
+			variantName:     "android_common",
+			apkPath:         "/target/product/test_device/system/app/foo/foo.apk",
+			certFlag:        "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
+			lineageFlag:     "",
+			overrides:       []string{"qux"},
+			packageFlag:     "",
+			renameResources: false,
+			logging_parent:  "",
 		},
 		{
-			moduleName:     "bar",
-			variantName:    "android_common_bar",
-			apkPath:        "/target/product/test_device/system/app/bar/bar.apk",
-			certFlag:       "cert/new_cert.x509.pem cert/new_cert.pk8",
-			lineageFlag:    "--lineage lineage.bin",
-			overrides:      []string{"qux", "foo"},
-			aaptFlag:       "",
-			logging_parent: "bah",
+			name:            "foo",
+			moduleName:      "bar",
+			variantName:     "android_common_bar",
+			apkPath:         "/target/product/test_device/system/app/bar/bar.apk",
+			certFlag:        "cert/new_cert.x509.pem cert/new_cert.pk8",
+			lineageFlag:     "--lineage lineage.bin",
+			overrides:       []string{"qux", "foo"},
+			packageFlag:     "",
+			renameResources: false,
+			logging_parent:  "bah",
 		},
 		{
-			moduleName:     "baz",
-			variantName:    "android_common_baz",
-			apkPath:        "/target/product/test_device/system/app/baz/baz.apk",
-			certFlag:       "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
-			lineageFlag:    "",
-			overrides:      []string{"qux", "foo"},
-			aaptFlag:       "--rename-manifest-package org.dandroid.bp",
-			logging_parent: "",
+			name:            "foo",
+			moduleName:      "baz",
+			variantName:     "android_common_baz",
+			apkPath:         "/target/product/test_device/system/app/baz/baz.apk",
+			certFlag:        "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
+			lineageFlag:     "",
+			overrides:       []string{"qux", "foo"},
+			packageFlag:     "org.dandroid.bp",
+			renameResources: true,
+			logging_parent:  "",
+		},
+		{
+			name:            "foo",
+			moduleName:      "baz_no_rename_resources",
+			variantName:     "android_common_baz_no_rename_resources",
+			apkPath:         "/target/product/test_device/system/app/baz_no_rename_resources/baz_no_rename_resources.apk",
+			certFlag:        "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
+			lineageFlag:     "",
+			overrides:       []string{"qux", "foo"},
+			packageFlag:     "org.dandroid.bp",
+			renameResources: false,
+			logging_parent:  "",
+		},
+		{
+			name:            "foo_no_rename_resources",
+			moduleName:      "baz_base_no_rename_resources",
+			variantName:     "android_common_baz_base_no_rename_resources",
+			apkPath:         "/target/product/test_device/system/app/baz_base_no_rename_resources/baz_base_no_rename_resources.apk",
+			certFlag:        "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
+			lineageFlag:     "",
+			overrides:       []string{"qux", "foo_no_rename_resources"},
+			packageFlag:     "org.dandroid.bp",
+			renameResources: false,
+			logging_parent:  "",
+		},
+		{
+			name:            "foo_no_rename_resources",
+			moduleName:      "baz_override_base_rename_resources",
+			variantName:     "android_common_baz_override_base_rename_resources",
+			apkPath:         "/target/product/test_device/system/app/baz_override_base_rename_resources/baz_override_base_rename_resources.apk",
+			certFlag:        "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
+			lineageFlag:     "",
+			overrides:       []string{"qux", "foo_no_rename_resources"},
+			packageFlag:     "org.dandroid.bp",
+			renameResources: true,
+			logging_parent:  "",
 		},
 	}
 	for _, expected := range expectedVariants {
-		variant := ctx.ModuleForTests("foo", expected.variantName)
+		variant := ctx.ModuleForTests(expected.name, expected.variantName)
 
 		// Check the final apk name
 		outputs := variant.AllOutputs()
@@ -1868,9 +2003,12 @@
 		// Check the package renaming flag, if exists.
 		res := variant.Output("package-res.apk")
 		aapt2Flags := res.Args["flags"]
-		if !strings.Contains(aapt2Flags, expected.aaptFlag) {
-			t.Errorf("package renaming flag, %q is missing in aapt2 link flags, %q", expected.aaptFlag, aapt2Flags)
+		checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
+		expectedPackage := expected.packageFlag
+		if !expected.renameResources {
+			expectedPackage = ""
 		}
+		checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expectedPackage)
 	}
 }
 
@@ -2007,6 +2145,7 @@
 		res := variant.Output("package-res.apk")
 		aapt2Flags := res.Args["flags"]
 		checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
+		checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expected.packageFlag)
 		checkAapt2LinkFlag(t, aapt2Flags, "rename-instrumentation-target-package", expected.targetPackageFlag)
 	}
 }
@@ -3131,6 +3270,65 @@
 	}
 }
 
+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)
+	}
+}
+
 func TestOverrideRuntimeResourceOverlay(t *testing.T) {
 	ctx, _ := testJava(t, `
 		runtime_resource_overlay {
@@ -3202,65 +3400,7 @@
 		res := variant.Output("package-res.apk")
 		aapt2Flags := res.Args["flags"]
 		checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
+		checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", "")
 		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 7318fcb..3043e46 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -385,7 +385,7 @@
 		"outDir":        android.PathForModuleOut(ctx, "turbine", "classes").String(),
 		"javaVersion":   flags.javaVersion.String(),
 	}
-	if ctx.Config().IsEnvTrue("RBE_TURBINE") {
+	if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_TURBINE") {
 		rule = turbineRE
 		args["implicits"] = strings.Join(deps.Strings(), ",")
 	}
@@ -452,7 +452,7 @@
 		annoDir = filepath.Join(shardDir, annoDir)
 	}
 	rule := javac
-	if ctx.Config().IsEnvTrue("RBE_JAVAC") {
+	if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_JAVAC") {
 		rule = javacRE
 	}
 	ctx.Build(pctx, android.BuildParams{
@@ -480,7 +480,7 @@
 	jarArgs []string, deps android.Paths) {
 
 	rule := jar
-	if ctx.Config().IsEnvTrue("RBE_JAR") {
+	if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_JAR") {
 		rule = jarRE
 	}
 	ctx.Build(pctx, android.BuildParams{
diff --git a/java/config/config.go b/java/config/config.go
index 05da3b5..31e2b0f 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -41,6 +41,7 @@
 
 	InstrumentFrameworkModules = []string{
 		"framework",
+		"framework-minus-apex",
 		"telephony-common",
 		"services",
 		"android.car",
@@ -51,6 +52,7 @@
 		"core-libart",
 		// TODO: Could this be all updatable bootclasspath jars?
 		"updatable-media",
+		"framework-mediaprovider",
 		"framework-sdkextensions",
 		"android.net.ipsec.ike",
 	}
diff --git a/java/dex.go b/java/dex.go
index c85914c..21a5926 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -38,6 +38,10 @@
 		// True if the module containing this has it set by default.
 		EnabledByDefault bool `blueprint:"mutated"`
 
+		// If true, runs R8 in Proguard compatibility mode (default).
+		// Otherwise, runs R8 in full mode.
+		Proguard_compatibility *bool
+
 		// If true, optimize for size by removing unused code.  Defaults to true for apps,
 		// false for libraries and tests.
 		Shrink *bool
@@ -113,7 +117,6 @@
 			`rm -f "$outDict" && rm -rf "${outUsageDir}" && ` +
 			`mkdir -p $$(dirname ${outUsage}) && ` +
 			`$r8Template${config.R8Cmd} ${config.DexFlags} -injars $in --output $outDir ` +
-			`--force-proguard-compatibility ` +
 			`--no-data-resources ` +
 			`-printmapping ${outDict} ` +
 			`-printusage ${outUsage} ` +
@@ -230,6 +233,10 @@
 
 	r8Flags = append(r8Flags, opt.Proguard_flags...)
 
+	if BoolDefault(opt.Proguard_compatibility, true) {
+		r8Flags = append(r8Flags, "--force-proguard-compatibility")
+	}
+
 	// TODO(ccross): Don't shrink app instrumentation tests by default.
 	if !Bool(opt.Shrink) {
 		r8Flags = append(r8Flags, "-dontshrink")
@@ -288,7 +295,7 @@
 			"outUsageZip": proguardUsageZip.String(),
 			"outDir":      outDir.String(),
 		}
-		if ctx.Config().IsEnvTrue("RBE_R8") {
+		if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_R8") {
 			rule = r8RE
 			args["implicits"] = strings.Join(r8Deps.Strings(), ",")
 		}
@@ -304,7 +311,7 @@
 	} else {
 		d8Flags, d8Deps := d8Flags(flags)
 		rule := d8
-		if ctx.Config().IsEnvTrue("RBE_D8") {
+		if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_D8") {
 			rule = d8RE
 		}
 		ctx.Build(pctx, android.BuildParams{
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 4c5f66c..7073eff 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -70,10 +70,6 @@
 	// or .aidl files.
 	Srcs []string `android:"path,arch_variant"`
 
-	// list of directories rooted at the Android.bp file that will
-	// be added to the search paths for finding source files when passing package names.
-	Local_sourcepaths []string
-
 	// list of source files that should not be used to build the Java module.
 	// This is most useful in the arch/multilib variants to remove non-common files
 	// filegroup or genrule can be included within this property.
@@ -175,10 +171,6 @@
 	// resources output directory under out/soong/.intermediates.
 	Resourcesoutdir *string
 
-	// if set to true, collect the values used by the Dev tools and
-	// write them in files packaged with the SDK. Defaults to false.
-	Write_sdk_values *bool
-
 	// index.html under current module will be copied to docs out dir, if not null.
 	Static_doc_index_redirect *string `android:"path"`
 
@@ -195,22 +187,6 @@
 	// the generated removed API filename by Doclava.
 	Removed_api_filename *string
 
-	// the generated removed Dex API filename by Doclava.
-	Removed_dex_api_filename *string
-
-	// if set to false, don't allow droiddoc to generate stubs source files. Defaults to false.
-	Create_stubs *bool
-
-	Check_api struct {
-		Last_released ApiToCheck
-
-		Current ApiToCheck
-
-		// do not perform API check against Last_released, in the case that both two specified API
-		// files by Last_released are modules which don't exist.
-		Ignore_missing_latest_api *bool `blueprint:"mutated"`
-	}
-
 	// if set to true, generate docs through Dokka instead of Doclava.
 	Dokka_enabled *bool
 
@@ -639,10 +615,9 @@
 	j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
 	j.srcFiles = append(j.srcFiles, deps.srcs...)
 
-	if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
-		j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
+	if len(j.srcFiles) > 0 {
+		j.sourcepaths = android.PathsForModuleSrc(ctx, []string{"."})
 	}
-	j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
 
 	j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
 	argFilesMap := map[string]string{}
@@ -748,17 +723,7 @@
 type Droiddoc struct {
 	Javadoc
 
-	properties        DroiddocProperties
-	apiFile           android.WritablePath
-	privateApiFile    android.WritablePath
-	removedApiFile    android.WritablePath
-	removedDexApiFile android.WritablePath
-
-	checkCurrentApiTimestamp      android.WritablePath
-	updateCurrentApiTimestamp     android.WritablePath
-	checkLastReleasedApiTimestamp android.WritablePath
-
-	apiFilePath android.Path
+	properties DroiddocProperties
 }
 
 // droiddoc converts .java source files to documentation using doclava or dokka.
@@ -783,17 +748,18 @@
 	return module
 }
 
-func (d *Droiddoc) ApiFilePath() android.Path {
-	return d.apiFilePath
+func (d *Droiddoc) OutputFiles(tag string) (android.Paths, error) {
+	switch tag {
+	case "", ".docs.zip":
+		return android.Paths{d.Javadoc.docZip}, nil
+	default:
+		return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+	}
 }
 
 func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
 	d.Javadoc.addDeps(ctx)
 
-	if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
-		ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
-	}
-
 	if String(d.properties.Custom_template) != "" {
 		ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
 	}
@@ -873,41 +839,6 @@
 	}
 }
 
-func (d *Droiddoc) createStubs() bool {
-	return BoolDefault(d.properties.Create_stubs, false)
-}
-
-func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
-	if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
-		apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
-		String(d.properties.Api_filename) != "" {
-
-		d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
-		cmd.FlagWithOutput("-api ", d.apiFile)
-		d.apiFilePath = d.apiFile
-	}
-
-	if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
-		apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
-		String(d.properties.Removed_api_filename) != "" {
-		d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
-		cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
-	}
-
-	if String(d.properties.Removed_dex_api_filename) != "" {
-		d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
-		cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
-	}
-
-	if d.createStubs() {
-		cmd.FlagWithArg("-stubs ", stubsDir.String())
-	}
-
-	if Bool(d.properties.Write_sdk_values) {
-		cmd.FlagWithArg("-sdkvalues ", android.PathForModuleOut(ctx, "out").String())
-	}
-}
-
 func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
 	if String(d.properties.Static_doc_index_redirect) != "" {
 		staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
@@ -1010,22 +941,15 @@
 	deps := d.Javadoc.collectDeps(ctx)
 
 	d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
-	d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
 
 	jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
 	doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
-	java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
-	checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
 
 	outDir := android.PathForModuleOut(ctx, "out")
 	srcJarDir := android.PathForModuleOut(ctx, "srcjars")
-	stubsDir := android.PathForModuleOut(ctx, "stubsDir")
 
 	rule := android.NewRuleBuilder()
 
-	rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
-	rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
-
 	srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
 
 	var cmd *android.RuleBuilderCommand
@@ -1036,8 +960,6 @@
 			deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
 	}
 
-	d.stubsFlags(ctx, cmd, stubsDir)
-
 	cmd.Flag(strings.Join(d.Javadoc.args, " ")).Implicits(d.Javadoc.argFiles)
 
 	if d.properties.Compat_config != nil {
@@ -1067,120 +989,11 @@
 		FlagWithArg("-C ", outDir.String()).
 		FlagWithArg("-D ", outDir.String())
 
-	rule.Command().
-		BuiltTool(ctx, "soong_zip").
-		Flag("-write_if_changed").
-		Flag("-jar").
-		FlagWithOutput("-o ", d.stubsSrcJar).
-		FlagWithArg("-C ", stubsDir.String()).
-		FlagWithArg("-D ", stubsDir.String())
-
 	rule.Restat()
 
 	zipSyncCleanupCmd(rule, srcJarDir)
 
 	rule.Build(pctx, ctx, "javadoc", desc)
-
-	if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
-		apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
-		removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
-
-		d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
-
-		rule := android.NewRuleBuilder()
-
-		rule.Command().Text("( true")
-
-		rule.Command().
-			BuiltTool(ctx, "apicheck").
-			Flag("-JXmx1024m").
-			FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
-			OptionalFlag(d.properties.Check_api.Current.Args).
-			Input(apiFile).
-			Input(d.apiFile).
-			Input(removedApiFile).
-			Input(d.removedApiFile)
-
-		msg := fmt.Sprintf(`\n******************************\n`+
-			`You have tried to change the API from what has been previously approved.\n\n`+
-			`To make these errors go away, you have two choices:\n`+
-			`   1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
-			`      errors above.\n\n`+
-			`   2. You can update current.txt by executing the following command:\n`+
-			`         make %s-update-current-api\n\n`+
-			`      To submit the revised current.txt to the main Android repository,\n`+
-			`      you will need approval.\n`+
-			`******************************\n`, ctx.ModuleName())
-
-		rule.Command().
-			Text("touch").Output(d.checkCurrentApiTimestamp).
-			Text(") || (").
-			Text("echo").Flag("-e").Flag(`"` + msg + `"`).
-			Text("; exit 38").
-			Text(")")
-
-		rule.Build(pctx, ctx, "doclavaCurrentApiCheck", "check current API")
-
-		d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
-
-		// update API rule
-		rule = android.NewRuleBuilder()
-
-		rule.Command().Text("( true")
-
-		rule.Command().
-			Text("cp").Flag("-f").
-			Input(d.apiFile).Flag(apiFile.String())
-
-		rule.Command().
-			Text("cp").Flag("-f").
-			Input(d.removedApiFile).Flag(removedApiFile.String())
-
-		msg = "failed to update public API"
-
-		rule.Command().
-			Text("touch").Output(d.updateCurrentApiTimestamp).
-			Text(") || (").
-			Text("echo").Flag("-e").Flag(`"` + msg + `"`).
-			Text("; exit 38").
-			Text(")")
-
-		rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
-	}
-
-	if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") {
-		apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
-		removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
-
-		d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
-
-		rule := android.NewRuleBuilder()
-
-		rule.Command().
-			Text("(").
-			BuiltTool(ctx, "apicheck").
-			Flag("-JXmx1024m").
-			FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
-			OptionalFlag(d.properties.Check_api.Last_released.Args).
-			Input(apiFile).
-			Input(d.apiFile).
-			Input(removedApiFile).
-			Input(d.removedApiFile)
-
-		msg := `\n******************************\n` +
-			`You have tried to change the API from what has been previously released in\n` +
-			`an SDK.  Please fix the errors listed above.\n` +
-			`******************************\n`
-
-		rule.Command().
-			Text("touch").Output(d.checkLastReleasedApiTimestamp).
-			Text(") || (").
-			Text("echo").Flag("-e").Flag(`"` + msg + `"`).
-			Text("; exit 38").
-			Text(")")
-
-		rule.Build(pctx, ctx, "doclavaLastApiCheck", "check last API")
-	}
 }
 
 //
@@ -1464,7 +1277,7 @@
 	// Metalava uses lots of memory, restrict the number of metalava jobs that can run in parallel.
 	rule.HighMem()
 	cmd := rule.Command()
-	if ctx.Config().IsEnvTrue("RBE_METALAVA") {
+	if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_METALAVA") {
 		rule.Remoteable(android.RemoteRuleSupports{RBE: true})
 		pool := ctx.Config().GetenvWithDefault("RBE_METALAVA_POOL", "metalava")
 		execStrategy := ctx.Config().GetenvWithDefault("RBE_METALAVA_EXEC_STRATEGY", remoteexec.LocalExecStrategy)
@@ -1600,6 +1413,15 @@
 		d.apiLintReport = android.PathForModuleOut(ctx, "api_lint_report.txt")
 		cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) // TODO:  Change to ":api-lint"
 
+		// TODO(b/154317059): Clean up this whitelist by baselining and/or checking in last-released.
+		if d.Name() != "android.car-system-stubs-docs" &&
+			d.Name() != "android.car-stubs-docs" &&
+			d.Name() != "system-api-stubs-docs" &&
+			d.Name() != "test-api-stubs-docs" {
+			cmd.Flag("--lints-as-errors")
+			cmd.Flag("--warnings-as-errors") // Most lints are actually warnings.
+		}
+
 		baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
 		updatedBaselineOutput := android.PathForModuleOut(ctx, "api_lint_baseline.txt")
 		d.apiLintTimestamp = android.PathForModuleOut(ctx, "api_lint.timestamp")
diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go
index ea3fbda..29b6bcd 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -207,6 +207,15 @@
 	rule.Build(pctx, ctx, "hiddenAPIStubFlagsFile", "hiddenapi stub flags")
 }
 
+func moduleForGreyListRemovedApis(ctx android.SingletonContext, module android.Module) bool {
+	switch ctx.ModuleName(module) {
+	case "api-stubs-docs", "system-api-stubs-docs", "android.car-stubs-docs", "android.car-system-stubs-docs":
+		return true
+	default:
+		return false
+	}
+}
+
 // flagsRule creates a rule to build hiddenapi-flags.csv out of flags.csv files generated for boot image modules and
 // the unsupported API.
 func flagsRule(ctx android.SingletonContext) android.Path {
@@ -222,7 +231,7 @@
 			// Track @removed public and system APIs via corresponding droidstubs targets.
 			// These APIs are not present in the stubs, however, we have to keep allowing access
 			// to them at runtime.
-			if m := ctx.ModuleName(module); m == "api-stubs-docs" || m == "system-api-stubs-docs" {
+			if moduleForGreyListRemovedApis(ctx, module) {
 				greylistRemovedApis = append(greylistRemovedApis, ds.removedDexApiFile)
 			}
 		}
diff --git a/java/java.go b/java/java.go
index c568ec4..9830c51 100644
--- a/java/java.go
+++ b/java/java.go
@@ -324,6 +324,10 @@
 	Stem *string
 
 	IsSDKLibrary bool `blueprint:"mutated"`
+
+	// If true, generate the signature file of APK Signing Scheme V4, along side the signed APK file.
+	// Defaults to false.
+	V4_signature *bool
 }
 
 // Functionality common to Module and Import
@@ -1490,7 +1494,7 @@
 		args := map[string]string{
 			"jarArgs": "-P META-INF/services/ " + strings.Join(proptools.NinjaAndShellEscapeList(zipargs), " "),
 		}
-		if ctx.Config().IsEnvTrue("RBE_ZIP") {
+		if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_ZIP") {
 			rule = zipRE
 			args["implicits"] = strings.Join(services.Strings(), ",")
 		}
@@ -1979,9 +1983,9 @@
 	// added to the Android manifest.
 	j.exportedSdkLibs.MaybeAddLibraryPath(ctx, j.OptionalImplicitSdkLibrary(), j.DexJarBuildPath(), j.DexJarInstallPath())
 
-	// If this is a non-SDK uses-library, export itself.
-	if proptools.Bool(j.usesLibraryProperties.Is_uses_lib) {
-		j.exportedSdkLibs.AddLibraryPath(ctx, ctx.ModuleName(), j.DexJarBuildPath(), j.DexJarInstallPath())
+	// A non-SDK library may provide a <uses-library> (the name may be different from the module name).
+	if lib := proptools.String(j.usesLibraryProperties.Provides_uses_lib); lib != "" {
+		j.exportedSdkLibs.AddLibraryPath(ctx, lib, j.DexJarBuildPath(), j.DexJarInstallPath())
 	}
 
 	j.distFiles = j.GenerateTaggedDistFiles(ctx)
diff --git a/java/java_test.go b/java/java_test.go
index 3f7bab1..9e63577 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1097,16 +1097,26 @@
 		    srcs: ["bar-doc/IBar.aidl"],
 		    path: "bar-doc",
 		}
-		droiddoc {
-		    name: "bar-doc",
+		droidstubs {
+		    name: "bar-stubs",
 		    srcs: [
 		        "bar-doc/a.java",
-		        "bar-doc/IFoo.aidl",
-		        ":bar-doc-aidl-srcs",
 		    ],
 		    exclude_srcs: [
 		        "bar-doc/b.java"
 		    ],
+		    api_levels_annotations_dirs: [
+		      "droiddoc-templates-sdk",
+		    ],
+		    api_levels_annotations_enabled: true,
+		}
+		droiddoc {
+		    name: "bar-doc",
+		    srcs: [
+		        ":bar-stubs",
+		        "bar-doc/IFoo.aidl",
+		        ":bar-doc-aidl-srcs",
+		    ],
 		    custom_template: "droiddoc-templates-sdk",
 		    hdf: [
 		        "android.whichdoc offline",
@@ -1123,23 +1133,29 @@
 			"bar-doc/a.java": nil,
 			"bar-doc/b.java": nil,
 		})
-	barDocModule := ctx.ModuleForTests("bar-doc", "android_common")
-	barDoc := barDocModule.Rule("javadoc")
-	notExpected := " -stubs "
-	if strings.Contains(barDoc.RuleParams.Command, notExpected) {
-		t.Errorf("bar-doc command contains flag %q to create stubs, but should not", notExpected)
+	barStubs := ctx.ModuleForTests("bar-stubs", "android_common")
+	barStubsOutputs, err := barStubs.Module().(*Droidstubs).OutputFiles("")
+	if err != nil {
+		t.Errorf("Unexpected error %q retrieving \"bar-stubs\" output file", err)
+	}
+	if len(barStubsOutputs) != 1 {
+		t.Errorf("Expected one output from \"bar-stubs\" got %s", barStubsOutputs)
 	}
 
-	var javaSrcs []string
-	for _, i := range barDoc.Inputs {
-		javaSrcs = append(javaSrcs, i.Base())
-	}
-	if len(javaSrcs) != 1 || javaSrcs[0] != "a.java" {
-		t.Errorf("inputs of bar-doc must be []string{\"a.java\"}, but was %#v.", javaSrcs)
+	barStubsOutput := barStubsOutputs[0]
+	barDoc := ctx.ModuleForTests("bar-doc", "android_common")
+	javaDoc := barDoc.Rule("javadoc")
+	if g, w := javaDoc.Implicits.Strings(), barStubsOutput.String(); !inList(w, g) {
+		t.Errorf("implicits of bar-doc must contain %q, but was %q.", w, g)
 	}
 
-	aidl := barDocModule.Rule("aidl")
-	if g, w := barDoc.Implicits.Strings(), aidl.Output.String(); !inList(w, g) {
+	expected := "-sourcepath " + buildDir + "/.intermediates/bar-doc/android_common/srcjars "
+	if !strings.Contains(javaDoc.RuleParams.Command, expected) {
+		t.Errorf("bar-doc command does not contain flag %q, but should\n%q", expected, javaDoc.RuleParams.Command)
+	}
+
+	aidl := barDoc.Rule("aidl")
+	if g, w := javaDoc.Implicits.Strings(), aidl.Output.String(); !inList(w, g) {
 		t.Errorf("implicits of bar-doc must contain %q, but was %q.", w, g)
 	}
 
@@ -1159,16 +1175,26 @@
 		    srcs: ["bar-doc/IBar.aidl"],
 		    path: "bar-doc",
 		}
-		droiddoc {
-		    name: "bar-doc",
+		droidstubs {
+		    name: "bar-stubs",
 		    srcs: [
 		        "bar-doc/a.java",
-		        "bar-doc/IFoo.aidl",
-		        ":bar-doc-aidl-srcs",
 		    ],
 		    exclude_srcs: [
 		        "bar-doc/b.java"
 		    ],
+		    api_levels_annotations_dirs: [
+		      "droiddoc-templates-sdk",
+		    ],
+		    api_levels_annotations_enabled: true,
+		}
+		droiddoc {
+		    name: "bar-doc",
+		    srcs: [
+		        ":bar-stubs",
+		        "bar-doc/IFoo.aidl",
+		        ":bar-doc-aidl-srcs",
+		    ],
 		    custom_template: "droiddoc-templates-sdk",
 		    hdf: [
 		        "android.whichdoc offline",
diff --git a/java/legacy_core_platform_api_usage.go b/java/legacy_core_platform_api_usage.go
index 8af66d0..021920a 100644
--- a/java/legacy_core_platform_api_usage.go
+++ b/java/legacy_core_platform_api_usage.go
@@ -19,6 +19,10 @@
 	"android/soong/java/config"
 )
 
+// This variable is effectively unused in pre-master branches, and is
+// included (with the same value as it has in AOSP) only to ease
+// merges between branches (see the comment in the
+// useLegacyCorePlatformApi() function):
 var legacyCorePlatformApiModules = []string{
 	"ahat-test-dump",
 	"android.car",
@@ -132,6 +136,10 @@
 	"wifi-service",
 }
 
+// This variable is effectively unused in pre-master branches, and is
+// included (with the same value as it has in AOSP) only to ease
+// merges between branches (see the comment in the
+// useLegacyCorePlatformApi() function):
 var legacyCorePlatformApiLookup = make(map[string]struct{})
 
 func init() {
@@ -141,8 +149,12 @@
 }
 
 func useLegacyCorePlatformApi(ctx android.EarlyModuleContext) bool {
-	_, found := legacyCorePlatformApiLookup[ctx.ModuleName()]
-	return found
+	// In pre-master branches, we don't attempt to force usage of the stable
+	// version of the core/platform API. Instead, we always use the legacy
+	// version --- except in tests, where we always use stable, so that we
+	// can make the test assertions the same as other branches.
+	// This should be false in tests and true otherwise:
+	return ctx.Config().TestProductVariables == nil
 }
 
 func corePlatformSystemModules(ctx android.EarlyModuleContext) string {
diff --git a/java/testing.go b/java/testing.go
index 1db6ef2..70c857f 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -95,11 +95,10 @@
 		MAIN_FILE = '%main%'`),
 
 		// For java_sdk_library
-		"api/module-lib-current.txt":                        nil,
-		"api/module-lib-removed.txt":                        nil,
-		"api/system-server-current.txt":                     nil,
-		"api/system-server-removed.txt":                     nil,
-		"build/soong/scripts/gen-java-current-api-files.sh": nil,
+		"api/module-lib-current.txt":    nil,
+		"api/module-lib-removed.txt":    nil,
+		"api/system-server-current.txt": nil,
+		"api/system-server-removed.txt": nil,
 	}
 
 	cc.GatherRequiredFilesForTest(mockFS)