Merge "Add tests for exported generated headers"
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index ff85661..317f5c4 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,3 +1,6 @@
 [Builtin Hooks]
 gofmt = true
 bpfmt = true
+
+[Hook Scripts]
+do_not_use_DO_NOT_MERGE = ${REPO_ROOT}/build/soong/scripts/check_do_not_merge.sh ${PREUPLOAD_COMMIT}
diff --git a/android/apex.go b/android/apex.go
index 4637942..81f8c86 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -739,6 +739,8 @@
 
 	d.flatListPath = PathForModuleOut(ctx, "depsinfo", "flatlist.txt").OutputPath
 	WriteFileRule(ctx, d.flatListPath, flatContent.String())
+
+	ctx.Phony(fmt.Sprintf("%s-depsinfo", ctx.ModuleName()), d.fullListPath, d.flatListPath)
 }
 
 // TODO(b/158059172): remove minSdkVersion allowlist
diff --git a/android/config.go b/android/config.go
index c6885dd..095b1e4 100644
--- a/android/config.go
+++ b/android/config.go
@@ -946,13 +946,7 @@
 // More info: https://source.android.com/devices/architecture/rros
 func (c *config) EnforceRROForModule(name string) bool {
 	enforceList := c.productVariables.EnforceRROTargets
-	// TODO(b/150820813) Some modules depend on static overlay, remove this after eliminating the dependency.
-	exemptedList := c.productVariables.EnforceRROExemptedTargets
-	if len(exemptedList) > 0 {
-		if InList(name, exemptedList) {
-			return false
-		}
-	}
+
 	if len(enforceList) > 0 {
 		if InList("*", enforceList) {
 			return true
@@ -961,11 +955,6 @@
 	}
 	return false
 }
-
-func (c *config) EnforceRROExemptedForModule(name string) bool {
-	return InList(name, c.productVariables.EnforceRROExemptedTargets)
-}
-
 func (c *config) EnforceRROExcludedOverlay(path string) bool {
 	excluded := c.productVariables.EnforceRROExcludedOverlays
 	if len(excluded) > 0 {
diff --git a/android/variable.go b/android/variable.go
index 76666c5..dd000ad 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -199,11 +199,9 @@
 	CrossHostArch          *string `json:",omitempty"`
 	CrossHostSecondaryArch *string `json:",omitempty"`
 
-	DeviceResourceOverlays  []string `json:",omitempty"`
-	ProductResourceOverlays []string `json:",omitempty"`
-	EnforceRROTargets       []string `json:",omitempty"`
-	// TODO(b/150820813) Some modules depend on static overlay, remove this after eliminating the dependency.
-	EnforceRROExemptedTargets  []string `json:",omitempty"`
+	DeviceResourceOverlays     []string `json:",omitempty"`
+	ProductResourceOverlays    []string `json:",omitempty"`
+	EnforceRROTargets          []string `json:",omitempty"`
 	EnforceRROExcludedOverlays []string `json:",omitempty"`
 
 	AAPTCharacteristics *string  `json:",omitempty"`
diff --git a/apex/allowed_deps.txt b/apex/allowed_deps.txt
index 4e7039c..90edca5 100644
--- a/apex/allowed_deps.txt
+++ b/apex/allowed_deps.txt
@@ -202,6 +202,7 @@
 InProcessTethering(minSdkVersion:current)
 ipmemorystore-aidl-interfaces-java(minSdkVersion:29)
 ipmemorystore-aidl-interfaces-unstable-java(minSdkVersion:29)
+ipmemorystore-aidl-interfaces-V10-java(minSdkVersion:29)
 ipmemorystore-aidl-interfaces-V11-java(minSdkVersion:29)
 jni_headers(minSdkVersion:29)
 jsr305(minSdkVersion:14)
@@ -493,7 +494,9 @@
 net-utils-framework-common(minSdkVersion:current)
 netd-client(minSdkVersion:29)
 netd_aidl_interface-java(minSdkVersion:29)
+netd_aidl_interface-lateststable-java(minSdkVersion:29)
 netd_aidl_interface-unstable-java(minSdkVersion:29)
+netd_aidl_interface-V5-java(minSdkVersion:29)
 netd_aidl_interface-V6-java(minSdkVersion:29)
 netd_event_listener_interface-java(minSdkVersion:29)
 netd_event_listener_interface-ndk_platform(minSdkVersion:29)
diff --git a/apex/apex.go b/apex/apex.go
index e06a967..662bbbd 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -2847,14 +2847,6 @@
 	//
 	// Module separator
 	//
-	m["com.android.sdkext"] = []string{
-		"fmtlib_ndk",
-		"libbase_ndk",
-		"libprotobuf-cpp-lite-ndk",
-	}
-	//
-	// Module separator
-	//
 	m["com.android.os.statsd"] = []string{
 		"libstatssocket",
 	}
diff --git a/bp2build/Android.bp b/bp2build/Android.bp
index 521bb06..7d748ec 100644
--- a/bp2build/Android.bp
+++ b/bp2build/Android.bp
@@ -11,6 +11,7 @@
         "build_conversion.go",
         "bzl_conversion.go",
         "conversion.go",
+        "metrics.go",
     ],
     deps: [
         "soong-android",
diff --git a/bp2build/bp2build.go b/bp2build/bp2build.go
index b89d0a0..7169d7e 100644
--- a/bp2build/bp2build.go
+++ b/bp2build/bp2build.go
@@ -22,13 +22,13 @@
 
 // The Bazel bp2build code generator is responsible for writing .bzl files that are equivalent to
 // Android.bp files that are capable of being built with Bazel.
-func Codegen(ctx CodegenContext) {
+func Codegen(ctx CodegenContext) CodegenMetrics {
 	outputDir := android.PathForOutput(ctx, "bp2build")
 	android.RemoveAllOutputDir(outputDir)
 
 	ruleShims := CreateRuleShims(android.ModuleTypeFactories())
 
-	buildToTargets := GenerateBazelTargets(ctx.Context(), ctx.mode)
+	buildToTargets, metrics := GenerateBazelTargets(ctx)
 
 	filesToWrite := CreateBazelFiles(ruleShims, buildToTargets, ctx.mode)
 	for _, f := range filesToWrite {
@@ -36,6 +36,8 @@
 			fmt.Errorf("Failed to write %q (dir %q) due to %q", f.Basename, f.Dir, err)
 		}
 	}
+
+	return metrics
 }
 
 func writeFile(outputDir android.OutputPath, ctx android.PathContext, f BazelFile) error {
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index 7ffcfa4..fcad686 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -105,6 +105,10 @@
 	mode    CodegenMode
 }
 
+func (c *CodegenContext) Mode() CodegenMode {
+	return c.mode
+}
+
 // CodegenMode is an enum to differentiate code-generation modes.
 type CodegenMode int
 
@@ -160,33 +164,54 @@
 	return attributes
 }
 
-func GenerateBazelTargets(ctx bpToBuildContext, codegenMode CodegenMode) map[string]BazelTargets {
+func GenerateBazelTargets(ctx CodegenContext) (map[string]BazelTargets, CodegenMetrics) {
 	buildFileToTargets := make(map[string]BazelTargets)
-	ctx.VisitAllModules(func(m blueprint.Module) {
-		dir := ctx.ModuleDir(m)
+
+	// Simple metrics tracking for bp2build
+	totalModuleCount := 0
+	ruleClassCount := make(map[string]int)
+
+	bpCtx := ctx.Context()
+	bpCtx.VisitAllModules(func(m blueprint.Module) {
+		dir := bpCtx.ModuleDir(m)
 		var t BazelTarget
 
-		switch codegenMode {
+		switch ctx.Mode() {
 		case Bp2Build:
 			if _, ok := m.(android.BazelTargetModule); !ok {
+				// Only include regular Soong modules (non-BazelTargetModules) into the total count.
+				totalModuleCount += 1
 				return
 			}
-			t = generateBazelTarget(ctx, m)
+			t = generateBazelTarget(bpCtx, m)
+			ruleClassCount[t.ruleClass] += 1
 		case QueryView:
 			// Blocklist certain module types from being generated.
-			if canonicalizeModuleType(ctx.ModuleType(m)) == "package" {
+			if canonicalizeModuleType(bpCtx.ModuleType(m)) == "package" {
 				// package module name contain slashes, and thus cannot
 				// be mapped cleanly to a bazel label.
 				return
 			}
-			t = generateSoongModuleTarget(ctx, m)
+			t = generateSoongModuleTarget(bpCtx, m)
 		default:
-			panic(fmt.Errorf("Unknown code-generation mode: %s", codegenMode))
+			panic(fmt.Errorf("Unknown code-generation mode: %s", ctx.Mode()))
 		}
 
 		buildFileToTargets[dir] = append(buildFileToTargets[dir], t)
 	})
-	return buildFileToTargets
+
+	metrics := CodegenMetrics{
+		TotalModuleCount: totalModuleCount,
+		RuleClassCount:   ruleClassCount,
+	}
+
+	return buildFileToTargets, metrics
+}
+
+// Helper method for tests to easily access the targets in a dir.
+func GenerateBazelTargetsForDir(codegenCtx CodegenContext, dir string) BazelTargets {
+	bazelTargetsMap, _ := GenerateBazelTargets(codegenCtx)
+	return bazelTargetsMap[dir]
 }
 
 // Helper method to trim quotes around strings.
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index 422422b..fce6433 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -194,6 +194,7 @@
 	for _, testCase := range testCases {
 		config := android.TestConfig(buildDir, nil, testCase.bp, nil)
 		ctx := android.NewTestContext(config)
+
 		ctx.RegisterModuleType("custom", customModuleFactory)
 		ctx.Register()
 
@@ -202,7 +203,8 @@
 		_, errs = ctx.PrepareBuildActions(config)
 		android.FailIfErrored(t, errs)
 
-		bazelTargets := GenerateBazelTargets(ctx.Context.Context, QueryView)[dir]
+		codegenCtx := NewCodegenContext(config, *ctx.Context, QueryView)
+		bazelTargets := GenerateBazelTargetsForDir(codegenCtx, dir)
 		if actualCount, expectedCount := len(bazelTargets), 1; actualCount != expectedCount {
 			t.Fatalf("Expected %d bazel target, got %d", expectedCount, actualCount)
 		}
@@ -245,6 +247,7 @@
 	for _, testCase := range testCases {
 		config := android.TestConfig(buildDir, nil, testCase.bp, nil)
 		ctx := android.NewTestContext(config)
+
 		ctx.RegisterModuleType("custom", customModuleFactory)
 		ctx.RegisterBp2BuildMutator("custom", customBp2BuildMutator)
 		ctx.RegisterForBazelConversion()
@@ -258,7 +261,9 @@
 			continue
 		}
 
-		bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[dir]
+		codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
+		bazelTargets := GenerateBazelTargetsForDir(codegenCtx, dir)
+
 		if actualCount, expectedCount := len(bazelTargets), 1; actualCount != expectedCount {
 			t.Errorf("Expected %d bazel target, got %d", expectedCount, actualCount)
 		} else {
@@ -415,7 +420,8 @@
 		_, errs = ctx.ResolveDependencies(config)
 		android.FailIfErrored(t, errs)
 
-		bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[dir]
+		codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
+		bazelTargets := GenerateBazelTargetsForDir(codegenCtx, dir)
 		if actualCount := len(bazelTargets); actualCount != testCase.expectedBazelTargetCount {
 			t.Fatalf("Expected %d bazel target, got %d", testCase.expectedBazelTargetCount, actualCount)
 		}
@@ -904,7 +910,9 @@
 		if testCase.dir != "" {
 			checkDir = testCase.dir
 		}
-		bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[checkDir]
+
+		codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
+		bazelTargets := GenerateBazelTargetsForDir(codegenCtx, checkDir)
 		if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
 			t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
 		} else {
@@ -1118,7 +1126,8 @@
 		_, errs = ctx.ResolveDependencies(config)
 		android.FailIfErrored(t, errs)
 
-		bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[dir]
+		codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
+		bazelTargets := GenerateBazelTargetsForDir(codegenCtx, dir)
 		if actualCount := len(bazelTargets); actualCount != 1 {
 			t.Fatalf("%s: Expected 1 bazel target, got %d", testCase.description, actualCount)
 		}
@@ -1205,7 +1214,8 @@
 		_, errs = ctx.ResolveDependencies(config)
 		android.FailIfErrored(t, errs)
 
-		bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[dir]
+		codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
+		bazelTargets := GenerateBazelTargetsForDir(codegenCtx, dir)
 		if actualCount := len(bazelTargets); actualCount != testCase.expectedCount {
 			t.Fatalf("%s: Expected %d bazel target, got %d", testCase.description, testCase.expectedCount, actualCount)
 		}
diff --git a/bp2build/cc_library_headers_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go
index 3cd3762..b2d8941 100644
--- a/bp2build/cc_library_headers_conversion_test.go
+++ b/bp2build/cc_library_headers_conversion_test.go
@@ -202,7 +202,8 @@
 		if testCase.dir != "" {
 			checkDir = testCase.dir
 		}
-		bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[checkDir]
+		codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
+		bazelTargets := GenerateBazelTargetsForDir(codegenCtx, checkDir)
 		if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
 			t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
 		} else {
diff --git a/bp2build/cc_object_conversion_test.go b/bp2build/cc_object_conversion_test.go
index e4ffe16..816edb8 100644
--- a/bp2build/cc_object_conversion_test.go
+++ b/bp2build/cc_object_conversion_test.go
@@ -166,7 +166,8 @@
 			continue
 		}
 
-		bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[dir]
+		codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
+		bazelTargets := GenerateBazelTargetsForDir(codegenCtx, dir)
 		if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
 			fmt.Println(bazelTargets)
 			t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
diff --git a/bp2build/metrics.go b/bp2build/metrics.go
new file mode 100644
index 0000000..916129f
--- /dev/null
+++ b/bp2build/metrics.go
@@ -0,0 +1,30 @@
+package bp2build
+
+import (
+	"android/soong/android"
+	"fmt"
+)
+
+// Simple metrics struct to collect information about a Blueprint to BUILD
+// conversion process.
+type CodegenMetrics struct {
+	// Total number of Soong/Blueprint modules
+	TotalModuleCount int
+
+	// Counts of generated Bazel targets per Bazel rule class
+	RuleClassCount map[string]int
+}
+
+// Print the codegen metrics to stdout.
+func (metrics CodegenMetrics) Print() {
+	generatedTargetCount := 0
+	for _, ruleClass := range android.SortedStringKeys(metrics.RuleClassCount) {
+		count := metrics.RuleClassCount[ruleClass]
+		fmt.Printf("[bp2build] %s: %d targets\n", ruleClass, count)
+		generatedTargetCount += count
+	}
+	fmt.Printf(
+		"[bp2build] Generated %d total BUILD targets from %d Android.bp modules.\n",
+		generatedTargetCount,
+		metrics.TotalModuleCount)
+}
diff --git a/bp2build/sh_conversion_test.go b/bp2build/sh_conversion_test.go
index dcc75bd..3e15dfc 100644
--- a/bp2build/sh_conversion_test.go
+++ b/bp2build/sh_conversion_test.go
@@ -115,7 +115,8 @@
 		if testCase.dir != "" {
 			checkDir = testCase.dir
 		}
-		bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[checkDir]
+		codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
+		bazelTargets := GenerateBazelTargetsForDir(codegenCtx, checkDir)
 		if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
 			t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
 		} else {
diff --git a/cc/config/clang.go b/cc/config/clang.go
index 76186be..5e46d5a 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -151,8 +151,6 @@
 		// This macro allows the bionic versioning.h to indirectly determine whether the
 		// option -Wunguarded-availability is on or not.
 		"-D__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__",
-		// TODO: remove this once prebuilt SDKs are only using the above macro instead.
-		"-D__ANDROID_UNGUARDED_AVAILABILITY__",
 	}, " "))
 
 	pctx.StaticVariable("ClangExtraCppflags", strings.Join([]string{
diff --git a/cc/test.go b/cc/test.go
index 17ac534..9b77e45 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -87,14 +87,10 @@
 	// Add RunCommandTargetPreparer to stop framework before the test and start it after the test.
 	Disable_framework *bool
 
-	// Add MinApiLevelModuleController to auto generated test config. If the device property of
-	// "ro.product.first_api_level" < Test_min_api_level, then skip this module.
+	// Add ShippingApiLevelModuleController to auto generated test config. If the device properties
+	// for the shipping api level is less than the test_min_api_level, skip this module.
 	Test_min_api_level *int64
 
-	// Add MinApiLevelModuleController to auto generated test config. If the device property of
-	// "ro.build.version.sdk" < Test_min_sdk_version, then skip this module.
-	Test_min_sdk_version *int64
-
 	// Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
 	// doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
 	// explicitly.
@@ -232,7 +228,6 @@
 type testDecorator struct {
 	Properties TestProperties
 	linker     *baseLinker
-	hod        android.HostOrDeviceSupported
 }
 
 func (test *testDecorator) gtest() bool {
@@ -376,9 +371,7 @@
 		}
 	})
 
-	var apiLevelProp string
 	var configs []tradefed.Config
-	var minLevel string
 	for _, module := range test.Properties.Test_mainline_modules {
 		configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module})
 	}
@@ -402,20 +395,10 @@
 	for _, tag := range test.Properties.Test_options.Test_suite_tag {
 		configs = append(configs, tradefed.Option{Name: "test-suite-tag", Value: tag})
 	}
-	if test.Properties.Test_min_api_level != nil && test.Properties.Test_min_sdk_version != nil {
-		ctx.PropertyErrorf("test_min_api_level", "'test_min_api_level' and 'test_min_sdk_version' should not be set at the same time.")
-	} else if test.Properties.Test_min_api_level != nil {
-		apiLevelProp = "ro.product.first_api_level"
-		minLevel = strconv.FormatInt(int64(*test.Properties.Test_min_api_level), 10)
-	} else if test.Properties.Test_min_sdk_version != nil {
-		apiLevelProp = "ro.build.version.sdk"
-		minLevel = strconv.FormatInt(int64(*test.Properties.Test_min_sdk_version), 10)
-	}
-	if apiLevelProp != "" {
+	if test.Properties.Test_min_api_level != nil {
 		var options []tradefed.Option
-		options = append(options, tradefed.Option{Name: "min-api-level", Value: minLevel})
-		options = append(options, tradefed.Option{Name: "api-level-prop", Value: apiLevelProp})
-		configs = append(configs, tradefed.Object{"module_controller", "com.android.tradefed.testtype.suite.module.MinApiLevelModuleController", options})
+		options = append(options, tradefed.Option{Name: "min-api-level", Value: strconv.FormatInt(int64(*test.Properties.Test_min_api_level), 10)})
+		configs = append(configs, tradefed.Object{"module_controller", "com.android.tradefed.testtype.suite.module.ShippingApiLevelModuleController", options})
 	}
 
 	test.testConfig = tradefed.AutoGenNativeTestConfig(ctx, test.Properties.Test_config,
@@ -432,8 +415,7 @@
 		ctx.PropertyErrorf("no_named_install_directory", "Module install directory may only be disabled if relative_install_path is set")
 	}
 
-	// TODO(179092189): Clean up to use Ctx.Host() when generalizing to cc_test
-	if test.testDecorator.hod == android.HostSupported && test.gtest() && test.Properties.Test_options.Unit_test == nil {
+	if ctx.Host() && test.gtest() && test.Properties.Test_options.Unit_test == nil {
 		test.Properties.Test_options.Unit_test = proptools.BoolPtr(true)
 	}
 	test.binaryDecorator.baseInstaller.install(ctx, file)
@@ -447,7 +429,6 @@
 	test := &testBinary{
 		testDecorator: testDecorator{
 			linker: binary.baseLinker,
-			hod:    hod,
 		},
 		binaryDecorator: binary,
 		baseCompiler:    NewBaseCompiler(),
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index c17e23d..3a6feca 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -134,7 +134,9 @@
 
 	// Convert the Soong module graph into Bazel BUILD files.
 	if bazelQueryViewDir != "" {
-		if err := createBazelQueryView(ctx, bazelQueryViewDir); err != nil {
+		// Run the code-generation phase to convert BazelTargetModules to BUILD files.
+		codegenContext := bp2build.NewCodegenContext(configuration, *ctx, bp2build.QueryView)
+		if err := createBazelQueryView(codegenContext, bazelQueryViewDir); err != nil {
 			fmt.Fprintf(os.Stderr, "%s", err)
 			os.Exit(1)
 		}
@@ -188,9 +190,15 @@
 	// from the regular Modules.
 	bootstrap.Main(bp2buildCtx.Context, configuration, extraNinjaDeps...)
 
-	// Run the code-generation phase to convert BazelTargetModules to BUILD files.
+	// Run the code-generation phase to convert BazelTargetModules to BUILD files
+	// and print conversion metrics to the user.
 	codegenContext := bp2build.NewCodegenContext(configuration, *bp2buildCtx, bp2build.Bp2Build)
-	bp2build.Codegen(codegenContext)
+	metrics := bp2build.Codegen(codegenContext)
+
+	// Only report metrics when in bp2build mode. The metrics aren't relevant
+	// for queryview, since that's a total repo-wide conversion and there's a
+	// 1:1 mapping for each module.
+	metrics.Print()
 
 	// Workarounds to support running bp2build in a clean AOSP checkout with no
 	// prior builds, and exiting early as soon as the BUILD files get generated,
diff --git a/cmd/soong_build/queryview.go b/cmd/soong_build/queryview.go
index dc0b323..0a77d67 100644
--- a/cmd/soong_build/queryview.go
+++ b/cmd/soong_build/queryview.go
@@ -22,9 +22,12 @@
 	"path/filepath"
 )
 
-func createBazelQueryView(ctx *android.Context, bazelQueryViewDir string) error {
+func createBazelQueryView(ctx bp2build.CodegenContext, bazelQueryViewDir string) error {
 	ruleShims := bp2build.CreateRuleShims(android.ModuleTypeFactories())
-	buildToTargets := bp2build.GenerateBazelTargets(*ctx, bp2build.QueryView)
+
+	// Ignore metrics reporting for queryview, since queryview is already a full-repo
+	// conversion and can use data from bazel query directly.
+	buildToTargets, _ := bp2build.GenerateBazelTargets(ctx)
 
 	filesToWrite := bp2build.CreateBazelFiles(ruleShims, buildToTargets, bp2build.QueryView)
 	for _, f := range filesToWrite {
diff --git a/java/aar.go b/java/aar.go
index ac7ae25..602d2c4 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -160,8 +160,8 @@
 func (a *aapt) IsRROEnforced(ctx android.BaseModuleContext) bool {
 	// True if RRO is enforced for this module or...
 	return ctx.Config().EnforceRROForModule(ctx.ModuleName()) ||
-		// if RRO is enforced for any of its dependents, and this module is not exempted.
-		(a.aaptProperties.RROEnforcedForDependent && !ctx.Config().EnforceRROExemptedForModule(ctx.ModuleName()))
+		// if RRO is enforced for any of its dependents.
+		a.aaptProperties.RROEnforcedForDependent
 }
 
 func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext sdkContext,
@@ -443,16 +443,14 @@
 					assets = append(assets, aarDep.ExportedAssets().Path())
 				}
 
-				if !ctx.Config().EnforceRROExemptedForModule(ctx.ModuleName()) {
-				outer:
-					for _, d := range aarDep.ExportedRRODirs() {
-						for _, e := range staticRRODirs {
-							if d.path == e.path {
-								continue outer
-							}
+			outer:
+				for _, d := range aarDep.ExportedRRODirs() {
+					for _, e := range staticRRODirs {
+						if d.path == e.path {
+							continue outer
 						}
-						staticRRODirs = append(staticRRODirs, d)
 					}
+					staticRRODirs = append(staticRRODirs, d)
 				}
 			}
 		}
diff --git a/java/rro_test.go b/java/rro_test.go
index 345f2ee..0a2f848 100644
--- a/java/rro_test.go
+++ b/java/rro_test.go
@@ -263,47 +263,34 @@
 
 func TestEnforceRRO_propagatesToDependencies(t *testing.T) {
 	testCases := []struct {
-		name                    string
-		enforceRROTargets       []string
-		enforceRROExemptTargets []string
-		rroDirs                 map[string][]string
+		name              string
+		enforceRROTargets []string
+		rroDirs           map[string][]string
 	}{
 		{
-			name:                    "no RRO",
-			enforceRROTargets:       nil,
-			enforceRROExemptTargets: nil,
+			name:              "no RRO",
+			enforceRROTargets: nil,
 			rroDirs: map[string][]string{
 				"foo": nil,
 				"bar": nil,
 			},
 		},
 		{
-			name:                    "enforce RRO on all",
-			enforceRROTargets:       []string{"*"},
-			enforceRROExemptTargets: nil,
+			name:              "enforce RRO on all",
+			enforceRROTargets: []string{"*"},
 			rroDirs: map[string][]string{
 				"foo": {"product/vendor/blah/overlay/lib2/res"},
 				"bar": {"product/vendor/blah/overlay/lib2/res"},
 			},
 		},
 		{
-			name:                    "enforce RRO on foo",
-			enforceRROTargets:       []string{"foo"},
-			enforceRROExemptTargets: nil,
+			name:              "enforce RRO on foo",
+			enforceRROTargets: []string{"foo"},
 			rroDirs: map[string][]string{
 				"foo": {"product/vendor/blah/overlay/lib2/res"},
 				"bar": {"product/vendor/blah/overlay/lib2/res"},
 			},
 		},
-		{
-			name:                    "enforce RRO on foo, bar exempted",
-			enforceRROTargets:       []string{"foo"},
-			enforceRROExemptTargets: []string{"bar"},
-			rroDirs: map[string][]string{
-				"foo": {"product/vendor/blah/overlay/lib2/res"},
-				"bar": nil,
-			},
-		},
 	}
 
 	productResourceOverlays := []string{
@@ -351,9 +338,6 @@
 			if testCase.enforceRROTargets != nil {
 				config.TestProductVariables.EnforceRROTargets = testCase.enforceRROTargets
 			}
-			if testCase.enforceRROExemptTargets != nil {
-				config.TestProductVariables.EnforceRROExemptedTargets = testCase.enforceRROExemptTargets
-			}
 
 			ctx := testContext(config)
 			run(t, ctx, config)
diff --git a/rust/config/global.go b/rust/config/global.go
index 182dc6a..12f4972 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -24,7 +24,7 @@
 var pctx = android.NewPackageContext("android/soong/rust/config")
 
 var (
-	RustDefaultVersion = "1.49.0"
+	RustDefaultVersion = "1.50.0"
 	RustDefaultBase    = "prebuilts/rust/"
 	DefaultEdition     = "2018"
 	Stdlibs            = []string{
diff --git a/rust/config/lints.go b/rust/config/lints.go
index 06bb668..ac8165b 100644
--- a/rust/config/lints.go
+++ b/rust/config/lints.go
@@ -52,6 +52,7 @@
 	// deny.
 	defaultClippyLints = []string{
 		"-A clippy::type-complexity",
+		"-A clippy::unnecessary-wraps",
 	}
 
 	// Rust lints for vendor code.
diff --git a/scripts/check_do_not_merge.sh b/scripts/check_do_not_merge.sh
new file mode 100755
index 0000000..ad6a0a9
--- /dev/null
+++ b/scripts/check_do_not_merge.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+if git show -s --format=%s $1 | grep -qE '(DO NOT MERGE)|(RESTRICT AUTOMERGE)'; then
+    cat >&2 <<EOF
+DO NOT MERGE and RESTRICT AUTOMERGE very often lead to unintended results
+and are not allowed to be used in this project.
+Please use the Merged-In tag to be more explicit about where this change
+should merge to. Google-internal documentation exists at go/merged-in
+
+If this check is mis-triggering or you know Merged-In is incorrect in this
+situation you can bypass this check with \`repo upload --no-verify\`.
+EOF
+    exit 1
+fi