Merge changes If7b81296,I3ddc53f0

* changes:
  Add more afdo testing
  Extend lto_test
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index cf74b9c..122495f 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -387,6 +387,10 @@
 		for _, enabledProdModule := range allowlists.ProdMixedBuildsEnabledList {
 			enabledModules[enabledProdModule] = true
 		}
+
+		for enabledAdHocModule := range c.BazelModulesForceEnabledByFlag() {
+			enabledModules[enabledAdHocModule] = true
+		}
 	case BazelStagingMode:
 		modulesDefaultToBazel = false
 		// Staging mode includes all prod modules plus all staging modules.
@@ -396,6 +400,10 @@
 		for _, enabledStagingMode := range allowlists.StagingMixedBuildsEnabledList {
 			enabledModules[enabledStagingMode] = true
 		}
+
+		for enabledAdHocModule := range c.BazelModulesForceEnabledByFlag() {
+			enabledModules[enabledAdHocModule] = true
+		}
 	case BazelDevMode:
 		modulesDefaultToBazel = true
 
diff --git a/android/config.go b/android/config.go
index f430b72..4a64b5b 100644
--- a/android/config.go
+++ b/android/config.go
@@ -227,6 +227,11 @@
 	mixedBuildsLock           sync.Mutex
 	mixedBuildEnabledModules  map[string]struct{}
 	mixedBuildDisabledModules map[string]struct{}
+
+	// These are modules to be built with Bazel beyond the allowlisted/build-mode
+	// specified modules. They are passed via the command-line flag
+	// "--bazel-force-enabled-modules"
+	bazelForceEnabledModules map[string]struct{}
 }
 
 type deviceConfig struct {
@@ -399,7 +404,8 @@
 
 // NewConfig creates a new Config object. The srcDir argument specifies the path
 // to the root source directory. It also loads the config file, if found.
-func NewConfig(moduleListFile string, buildMode SoongBuildMode, runGoTests bool, outDir, soongOutDir string, availableEnv map[string]string) (Config, error) {
+func NewConfig(moduleListFile string, buildMode SoongBuildMode, runGoTests bool, outDir, soongOutDir string, availableEnv map[string]string,
+	bazelForceEnabledModules []string) (Config, error) {
 	// Make a config with default options.
 	config := &config{
 		ProductVariablesFileName: filepath.Join(soongOutDir, productVariablesFileName),
@@ -415,6 +421,7 @@
 		fs:                        pathtools.NewOsFs(absSrcDir),
 		mixedBuildDisabledModules: make(map[string]struct{}),
 		mixedBuildEnabledModules:  make(map[string]struct{}),
+		bazelForceEnabledModules:  make(map[string]struct{}),
 	}
 
 	config.deviceConfig = &deviceConfig{
@@ -500,6 +507,10 @@
 	config.BazelContext, err = NewBazelContext(config)
 	config.Bp2buildPackageConfig = GetBp2BuildAllowList()
 
+	for _, module := range bazelForceEnabledModules {
+		config.bazelForceEnabledModules[module] = struct{}{}
+	}
+
 	return Config{config}, err
 }
 
@@ -1158,6 +1169,10 @@
 	return String(c.productVariables.PrebuiltHiddenApiDir)
 }
 
+func (c *config) BazelModulesForceEnabledByFlag() map[string]struct{} {
+	return c.bazelForceEnabledModules
+}
+
 func (c *deviceConfig) Arches() []Arch {
 	var arches []Arch
 	for _, target := range c.config.Targets[Android] {
diff --git a/android/fixture.go b/android/fixture.go
index 3f01f5a..c2b16f6 100644
--- a/android/fixture.go
+++ b/android/fixture.go
@@ -213,6 +213,46 @@
 	})
 }
 
+// FixtureTestRunner determines the type of test to run.
+//
+// If no custom FixtureTestRunner is provided (using the FixtureSetTestRunner) then the default test
+// runner will run a standard Soong test that corresponds to what happens when Soong is run on the
+// command line.
+type FixtureTestRunner interface {
+	// FinalPreparer is a function that is run immediately before parsing the blueprint files. It is
+	// intended to perform the initialization needed by PostParseProcessor.
+	//
+	// It returns a CustomTestResult that is passed into PostParseProcessor and returned from
+	// FixturePreparer.RunTestWithCustomResult. If it needs to return some custom data then it must
+	// provide its own implementation of CustomTestResult and return an instance of that. Otherwise,
+	// it can just return the supplied *TestResult.
+	FinalPreparer(result *TestResult) CustomTestResult
+
+	// PostParseProcessor is called after successfully parsing the blueprint files and can do further
+	// work on the result of parsing the files.
+	//
+	// Successfully parsing simply means that no errors were encountered when parsing the blueprint
+	// files.
+	//
+	// This must collate any information useful for testing, e.g. errs, ninja deps and custom data in
+	// the supplied result.
+	PostParseProcessor(result CustomTestResult)
+}
+
+// FixtureSetTestRunner sets the FixtureTestRunner in the fixture.
+//
+// It is an error if more than one of these is applied to a single fixture. If none of these are
+// applied then the fixture will use the defaultTestRunner which will run the test as if it was
+// being run in `m <target>`.
+func FixtureSetTestRunner(testRunner FixtureTestRunner) FixturePreparer {
+	return newSimpleFixturePreparer(func(fixture *fixture) {
+		if fixture.testRunner != nil {
+			panic("fixture test runner has already been set")
+		}
+		fixture.testRunner = testRunner
+	})
+}
+
 // Modify the config
 func FixtureModifyConfig(mutator func(config Config)) FixturePreparer {
 	return newSimpleFixturePreparer(func(f *fixture) {
@@ -391,6 +431,21 @@
 	// Shorthand for Fixture(t).RunTest()
 	RunTest(t *testing.T) *TestResult
 
+	// RunTestWithCustomResult runs the test just as RunTest(t) does but instead of returning a
+	// *TestResult it returns the CustomTestResult that was returned by the custom
+	// FixtureTestRunner.PostParseProcessor method that ran the test, or the *TestResult if that
+	// method returned nil.
+	//
+	// This method must be used when needing to access custom data collected by the
+	// FixtureTestRunner.PostParseProcessor method.
+	//
+	// e.g. something like this
+	//
+	//   preparers := ...FixtureSetTestRunner(&myTestRunner)...
+	//   customResult := preparers.RunTestWithCustomResult(t).(*myCustomTestResult)
+	//   doSomething(customResult.data)
+	RunTestWithCustomResult(t *testing.T) CustomTestResult
+
 	// Run the test with the supplied Android.bp file.
 	//
 	// preparer.RunTestWithBp(t, bp) is shorthand for
@@ -619,7 +674,7 @@
 	MockFS() MockFS
 
 	// Run the test, checking any errors reported and returning a TestResult instance.
-	RunTest() *TestResult
+	RunTest() CustomTestResult
 }
 
 // Struct to allow TestResult to embed a *TestContext and allow call forwarding to its methods.
@@ -642,6 +697,39 @@
 	NinjaDeps []string
 }
 
+func (r *TestResult) testResult() *TestResult { return r }
+
+// CustomTestResult is the interface that FixtureTestRunner implementations who wish to return
+// custom data must implement. It must embed *TestResult and initialize that to the value passed
+// into the method. It is returned from the FixtureTestRunner.FinalPreparer, passed into the
+// FixtureTestRunner.PostParseProcessor and returned from FixturePreparer.RunTestWithCustomResult.
+//
+// e.g. something like this:
+//
+//		type myCustomTestResult struct {
+//		    *android.TestResult
+//		    data []string
+//		}
+//
+//		func (r *myTestRunner) FinalPreparer(result *TestResult) CustomTestResult {
+//	     ... do some final test preparation ...
+//	     return &myCustomTestResult{TestResult: result)
+//	 }
+//
+//		func (r *myTestRunner) PostParseProcessor(result CustomTestResult) {
+//		    ...
+//		    myData := []string {....}
+//		    ...
+//		    customResult := result.(*myCustomTestResult)
+//	     customResult.data = myData
+//		}
+type CustomTestResult interface {
+	// testResult returns the embedded *TestResult.
+	testResult() *TestResult
+}
+
+var _ CustomTestResult = (*TestResult)(nil)
+
 type TestPathContext struct {
 	*TestResult
 }
@@ -696,6 +784,11 @@
 
 func (b *baseFixturePreparer) RunTest(t *testing.T) *TestResult {
 	t.Helper()
+	return b.RunTestWithCustomResult(t).testResult()
+}
+
+func (b *baseFixturePreparer) RunTestWithCustomResult(t *testing.T) CustomTestResult {
+	t.Helper()
 	fixture := b.self.Fixture(t)
 	return fixture.RunTest()
 }
@@ -724,13 +817,16 @@
 		ctx.SetModuleListFile(ctx.config.mockBpList)
 	}
 
-	return fixture.RunTest()
+	return fixture.RunTest().testResult()
 }
 
 type fixture struct {
 	// The preparers used to create this fixture.
 	preparers []*simpleFixturePreparer
 
+	// The test runner used in this fixture, defaults to defaultTestRunner if not set.
+	testRunner FixtureTestRunner
+
 	// The gotest state of the go test within which this was created.
 	t *testing.T
 
@@ -762,7 +858,7 @@
 	return f.mockFS
 }
 
-func (f *fixture) RunTest() *TestResult {
+func (f *fixture) RunTest() CustomTestResult {
 	f.t.Helper()
 
 	// If in debug mode output the state of the fixture before running the test.
@@ -800,30 +896,59 @@
 	// Set the NameResolver in the TestContext.
 	ctx.NameResolver = resolver
 
-	ctx.Register()
-	var ninjaDeps []string
-	extraNinjaDeps, errs := ctx.ParseBlueprintsFiles("ignored")
-	if len(errs) == 0 {
-		ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
-		extraNinjaDeps, errs = ctx.PrepareBuildActions(f.config)
-		if len(errs) == 0 {
-			ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
-		}
+	// If test runner has not been set then use the default runner.
+	if f.testRunner == nil {
+		f.testRunner = defaultTestRunner
 	}
 
+	// Create the result to collate result information.
 	result := &TestResult{
 		testContext: testContext{ctx},
 		fixture:     f,
 		Config:      f.config,
-		Errs:        errs,
-		NinjaDeps:   ninjaDeps,
+	}
+
+	// Do any last minute preparation before parsing the blueprint files.
+	customResult := f.testRunner.FinalPreparer(result)
+
+	// Parse the blueprint files adding the information to the result.
+	extraNinjaDeps, errs := ctx.ParseBlueprintsFiles("ignored")
+	result.NinjaDeps = append(result.NinjaDeps, extraNinjaDeps...)
+	result.Errs = append(result.Errs, errs...)
+
+	if len(result.Errs) == 0 {
+		// If parsing the blueprint files was successful then perform any additional processing.
+		f.testRunner.PostParseProcessor(customResult)
 	}
 
 	f.errorHandler.CheckErrors(f.t, result)
 
+	return customResult
+}
+
+// standardTestRunner is the implementation of the default test runner
+type standardTestRunner struct{}
+
+func (s *standardTestRunner) FinalPreparer(result *TestResult) CustomTestResult {
+	// Register the hard coded mutators and singletons used by the standard Soong build as well as
+	// any additional instances that have been registered with this fixture.
+	result.TestContext.Register()
 	return result
 }
 
+func (s *standardTestRunner) PostParseProcessor(customResult CustomTestResult) {
+	result := customResult.(*TestResult)
+	ctx := result.TestContext
+	cfg := result.Config
+	// Prepare the build actions, i.e. run all the mutators, singletons and then invoke the
+	// GenerateAndroidBuildActions methods on all the modules.
+	extraNinjaDeps, errs := ctx.PrepareBuildActions(cfg)
+	result.NinjaDeps = append(result.NinjaDeps, extraNinjaDeps...)
+	result.CollateErrs(errs)
+}
+
+var defaultTestRunner FixtureTestRunner = &standardTestRunner{}
+
 func (f *fixture) outputDebugState() {
 	fmt.Printf("Begin Fixture State for %s\n", f.t.Name())
 	if len(f.config.env) == 0 {
@@ -909,3 +1034,10 @@
 func (r *TestResult) Module(name string, variant string) Module {
 	return r.ModuleForTests(name, variant).Module()
 }
+
+// CollateErrs adds additional errors to the result and returns true if there is more than one
+// error in the result.
+func (r *TestResult) CollateErrs(errs []error) bool {
+	r.Errs = append(r.Errs, errs...)
+	return len(r.Errs) > 0
+}
diff --git a/bazel/cquery/request_type.go b/bazel/cquery/request_type.go
index e4830d3..118a3a9 100644
--- a/bazel/cquery/request_type.go
+++ b/bazel/cquery/request_type.go
@@ -33,6 +33,7 @@
 	TidyFiles            []string
 	TocFile              string
 	UnstrippedOutput     string
+	AbiDiffFiles         []string
 }
 
 type getOutputFilesRequestType struct{}
@@ -174,6 +175,11 @@
 if clang_tidy_info:
   tidy_files = [v.path for v in clang_tidy_info.tidy_files.to_list()]
 
+abi_diff_files = []
+abi_diff_info = p.get("//build/bazel/rules/abi:abi_dump.bzl%AbiDiffInfo")
+if abi_diff_info:
+  abi_diff_files = [f.path for f in abi_diff_info.diff_files.to_list()]
+
 return json_encode({
 	"OutputFiles": outputFiles,
 	"CcObjectFiles": ccObjectFiles,
@@ -187,6 +193,7 @@
 	"TidyFiles": tidy_files,
 	"TocFile": toc_file,
 	"UnstrippedOutput": unstripped,
+	"AbiDiffFiles": abi_diff_files,
 })`
 
 }
diff --git a/bp2build/cc_prebuilt_library_conversion_test.go b/bp2build/cc_prebuilt_library_conversion_test.go
index 47006ac..2fe158e 100644
--- a/bp2build/cc_prebuilt_library_conversion_test.go
+++ b/bp2build/cc_prebuilt_library_conversion_test.go
@@ -91,9 +91,9 @@
 			ModuleTypeUnderTest:        "cc_prebuilt_library",
 			ModuleTypeUnderTestFactory: cc.PrebuiltLibraryFactory,
 			Filesystem: map[string]string{
-				"libf.so":    "",
-				"testdir/1/": "",
-				"testdir/2/": "",
+				"libf.so":             "",
+				"testdir/1/include.h": "",
+				"testdir/2/other.h":   "",
 			},
 			Blueprint: `
 cc_prebuilt_library {
diff --git a/bp2build/testing.go b/bp2build/testing.go
index 4e63d19..c059add 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -91,65 +91,66 @@
 
 func RunBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc Bp2buildTestCase) {
 	t.Helper()
-	bp2buildSetup := func(ctx *android.TestContext) {
-		registerModuleTypes(ctx)
-		ctx.RegisterForBazelConversion()
-	}
+	bp2buildSetup := android.GroupFixturePreparers(
+		android.FixtureRegisterWithContext(registerModuleTypes),
+		SetBp2BuildTestRunner,
+	)
 	runBp2BuildTestCaseWithSetup(t, bp2buildSetup, tc)
 }
 
 func RunApiBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc Bp2buildTestCase) {
 	t.Helper()
-	apiBp2BuildSetup := func(ctx *android.TestContext) {
-		registerModuleTypes(ctx)
-		ctx.RegisterForApiBazelConversion()
-	}
+	apiBp2BuildSetup := android.GroupFixturePreparers(
+		android.FixtureRegisterWithContext(registerModuleTypes),
+		SetApiBp2BuildTestRunner,
+	)
 	runBp2BuildTestCaseWithSetup(t, apiBp2BuildSetup, tc)
 }
 
-func runBp2BuildTestCaseWithSetup(t *testing.T, setup func(ctx *android.TestContext), tc Bp2buildTestCase) {
+func runBp2BuildTestCaseWithSetup(t *testing.T, extraPreparer android.FixturePreparer, tc Bp2buildTestCase) {
 	t.Helper()
 	dir := "."
 	filesystem := make(map[string][]byte)
-	toParse := []string{
-		"Android.bp",
-	}
 	for f, content := range tc.Filesystem {
-		if strings.HasSuffix(f, "Android.bp") {
-			toParse = append(toParse, f)
-		}
 		filesystem[f] = []byte(content)
 	}
-	config := android.TestConfig(buildDir, nil, tc.Blueprint, filesystem)
-	ctx := android.NewTestContext(config)
 
-	setup(ctx)
-	ctx.RegisterModuleType(tc.ModuleTypeUnderTest, tc.ModuleTypeUnderTestFactory)
-
-	// A default configuration for tests to not have to specify bp2build_available on top level targets.
-	bp2buildConfig := android.NewBp2BuildAllowlist().SetDefaultConfig(
-		allowlists.Bp2BuildConfig{
-			android.Bp2BuildTopLevel: allowlists.Bp2BuildDefaultTrueRecursively,
-		},
-	)
-	for _, f := range tc.KeepBuildFileForDirs {
-		bp2buildConfig.SetKeepExistingBuildFile(map[string]bool{
-			f: /*recursive=*/ false,
-		})
-	}
-	ctx.RegisterBp2BuildConfig(bp2buildConfig)
-
-	_, parseErrs := ctx.ParseFileList(dir, toParse)
-	if errored(t, tc, parseErrs) {
-		return
-	}
-	_, resolveDepsErrs := ctx.ResolveDependencies(config)
-	if errored(t, tc, resolveDepsErrs) {
-		return
+	preparers := []android.FixturePreparer{
+		extraPreparer,
+		android.FixtureMergeMockFs(filesystem),
+		android.FixtureWithRootAndroidBp(tc.Blueprint),
+		android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
+			ctx.RegisterModuleType(tc.ModuleTypeUnderTest, tc.ModuleTypeUnderTestFactory)
+		}),
+		android.FixtureModifyContext(func(ctx *android.TestContext) {
+			// A default configuration for tests to not have to specify bp2build_available on top level
+			// targets.
+			bp2buildConfig := android.NewBp2BuildAllowlist().SetDefaultConfig(
+				allowlists.Bp2BuildConfig{
+					android.Bp2BuildTopLevel: allowlists.Bp2BuildDefaultTrueRecursively,
+				},
+			)
+			for _, f := range tc.KeepBuildFileForDirs {
+				bp2buildConfig.SetKeepExistingBuildFile(map[string]bool{
+					f: /*recursive=*/ false,
+				})
+			}
+			ctx.RegisterBp2BuildConfig(bp2buildConfig)
+		}),
+		android.FixtureModifyEnv(func(env map[string]string) {
+			if tc.UnconvertedDepsMode == errorModulesUnconvertedDeps {
+				env["BP2BUILD_ERROR_UNCONVERTED"] = "true"
+			}
+		}),
 	}
 
-	parseAndResolveErrs := append(parseErrs, resolveDepsErrs...)
-	if tc.ExpectedErr != nil && checkError(t, parseAndResolveErrs, tc.ExpectedErr) {
+	preparer := android.GroupFixturePreparers(preparers...)
+	if tc.ExpectedErr != nil {
+		pattern := "\\Q" + tc.ExpectedErr.Error() + "\\E"
+		preparer = preparer.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(pattern))
+	}
+	result := preparer.RunTestWithCustomResult(t).(*BazelTestResult)
+	if len(result.Errs) > 0 {
 		return
 	}
 
@@ -157,27 +158,115 @@
 	if tc.Dir != "" {
 		checkDir = tc.Dir
 	}
-	codegenCtx := NewCodegenContext(config, ctx.Context, Bp2Build)
-	codegenCtx.unconvertedDepMode = tc.UnconvertedDepsMode
-	bazelTargets, errs := generateBazelTargetsForDir(codegenCtx, checkDir)
-	if tc.ExpectedErr != nil {
-		if checkError(t, errs, tc.ExpectedErr) {
-			return
-		} else {
-			t.Errorf("Expected error: %q, got: %q and %q", tc.ExpectedErr, errs, parseAndResolveErrs)
-		}
-	} else {
-		android.FailIfErrored(t, errs)
+	expectedTargets := map[string][]string{
+		checkDir: tc.ExpectedBazelTargets,
 	}
-	if actualCount, expectedCount := len(bazelTargets), len(tc.ExpectedBazelTargets); actualCount != expectedCount {
+
+	result.CompareAllBazelTargets(t, tc.Description, expectedTargets, true)
+}
+
+// SetBp2BuildTestRunner customizes the test fixture mechanism to run tests in Bp2Build mode.
+var SetBp2BuildTestRunner = android.FixtureSetTestRunner(&bazelTestRunner{Bp2Build})
+
+// SetApiBp2BuildTestRunner customizes the test fixture mechanism to run tests in ApiBp2build mode.
+var SetApiBp2BuildTestRunner = android.FixtureSetTestRunner(&bazelTestRunner{ApiBp2build})
+
+// bazelTestRunner customizes the test fixture mechanism to run tests of the bp2build and
+// apiBp2build build modes.
+type bazelTestRunner struct {
+	mode CodegenMode
+}
+
+func (b *bazelTestRunner) FinalPreparer(result *android.TestResult) android.CustomTestResult {
+	ctx := result.TestContext
+	switch b.mode {
+	case Bp2Build:
+		ctx.RegisterForBazelConversion()
+	case ApiBp2build:
+		ctx.RegisterForApiBazelConversion()
+	default:
+		panic(fmt.Errorf("unknown build mode: %d", b.mode))
+	}
+
+	return &BazelTestResult{TestResult: result}
+}
+
+func (b *bazelTestRunner) PostParseProcessor(result android.CustomTestResult) {
+	bazelResult := result.(*BazelTestResult)
+	ctx := bazelResult.TestContext
+	config := bazelResult.Config
+	_, errs := ctx.ResolveDependencies(config)
+	if bazelResult.CollateErrs(errs) {
+		return
+	}
+
+	codegenCtx := NewCodegenContext(config, ctx.Context, Bp2Build)
+	res, errs := GenerateBazelTargets(codegenCtx, false)
+	if bazelResult.CollateErrs(errs) {
+		return
+	}
+
+	// Store additional data for access by tests.
+	bazelResult.conversionResults = res
+}
+
+// BazelTestResult is a wrapper around android.TestResult to provide type safe access to the bazel
+// specific data stored by the bazelTestRunner.
+type BazelTestResult struct {
+	*android.TestResult
+
+	// The result returned by the GenerateBazelTargets function.
+	conversionResults
+}
+
+// CompareAllBazelTargets compares the BazelTargets produced by the test for all the directories
+// with the supplied set of expected targets.
+//
+// If ignoreUnexpected=false then this enforces an exact match where every BazelTarget produced must
+// have a corresponding expected BazelTarget.
+//
+// If ignoreUnexpected=true then it will ignore directories for which there are no expected targets.
+func (b BazelTestResult) CompareAllBazelTargets(t *testing.T, description string, expectedTargets map[string][]string, ignoreUnexpected bool) {
+	actualTargets := b.buildFileToTargets
+
+	// Generate the sorted set of directories to check.
+	dirsToCheck := android.SortedStringKeys(expectedTargets)
+	if !ignoreUnexpected {
+		// This needs to perform an exact match so add the directories in which targets were
+		// produced to the list of directories to check.
+		dirsToCheck = append(dirsToCheck, android.SortedStringKeys(actualTargets)...)
+		dirsToCheck = android.SortedUniqueStrings(dirsToCheck)
+	}
+
+	for _, dir := range dirsToCheck {
+		expected := expectedTargets[dir]
+		actual := actualTargets[dir]
+
+		if expected == nil {
+			if actual != nil {
+				t.Errorf("did not expect any bazel modules in %q but found %d", dir, len(actual))
+			}
+		} else if actual == nil {
+			expectedCount := len(expected)
+			if expectedCount > 0 {
+				t.Errorf("expected %d bazel modules in %q but did not find any", expectedCount, dir)
+			}
+		} else {
+			b.CompareBazelTargets(t, description, expected, actual)
+		}
+	}
+}
+
+func (b BazelTestResult) CompareBazelTargets(t *testing.T, description string, expectedContents []string, actualTargets BazelTargets) {
+	if actualCount, expectedCount := len(actualTargets), len(expectedContents); actualCount != expectedCount {
 		t.Errorf("%s: Expected %d bazel target (%s), got %d (%s)",
-			tc.Description, expectedCount, tc.ExpectedBazelTargets, actualCount, bazelTargets)
+			description, expectedCount, expectedContents, actualCount, actualTargets)
 	} else {
-		for i, target := range bazelTargets {
-			if w, g := tc.ExpectedBazelTargets[i], target.content; w != g {
+		for i, actualTarget := range actualTargets {
+			if w, g := expectedContents[i], actualTarget.content; w != g {
 				t.Errorf(
-					"%s: Expected generated Bazel target to be `%s`, got `%s`",
-					tc.Description, w, g)
+					"%s[%d]: Expected generated Bazel target to be `%s`, got `%s`",
+					description, i, w, g)
 			}
 		}
 	}
diff --git a/cc/library.go b/cc/library.go
index 6ba01eb..d1d1945 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -905,6 +905,10 @@
 	}
 	handler.module.linker.(*libraryDecorator).tocFile = tocFile
 
+	if len(ccInfo.AbiDiffFiles) > 0 {
+		handler.module.linker.(*libraryDecorator).sAbiDiff = android.PathsForBazelOut(ctx, ccInfo.AbiDiffFiles)
+	}
+
 	ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
 		TableOfContents: tocFile,
 		SharedLibrary:   outputFilePath,
diff --git a/cc/sanitize_test.go b/cc/sanitize_test.go
index 580adfa..b102d33 100644
--- a/cc/sanitize_test.go
+++ b/cc/sanitize_test.go
@@ -314,6 +314,10 @@
 }
 
 func TestMiscUndefined(t *testing.T) {
+	if runtime.GOOS != "linux" {
+		t.Skip("requires linux")
+	}
+
 	bp := `
 	cc_binary {
 		name: "bin_with_ubsan",
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 029bbb4..e7323dd 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -89,6 +89,7 @@
 	flag.StringVar(&bp2buildMarker, "bp2build_marker", "", "If set, run bp2build, touch the specified marker file then exit")
 	flag.StringVar(&symlinkForestMarker, "symlink_forest_marker", "", "If set, create the bp2build symlink forest, touch the specified marker file, then exit")
 	flag.StringVar(&cmdlineArgs.OutFile, "o", "build.ninja", "the Ninja file to output")
+	flag.StringVar(&cmdlineArgs.BazelForceEnabledModules, "bazel-force-enabled-modules", "", "additional modules to build with Bazel. Comma-delimited")
 	flag.BoolVar(&cmdlineArgs.EmptyNinjaFile, "empty-ninja-file", false, "write out a 0-byte ninja file")
 	flag.BoolVar(&cmdlineArgs.BazelMode, "bazel-mode", false, "use bazel for analysis of certain modules")
 	flag.BoolVar(&cmdlineArgs.BazelModeStaging, "bazel-mode-staging", false, "use bazel for analysis of certain near-ready modules")
@@ -118,6 +119,10 @@
 
 func newConfig(availableEnv map[string]string) android.Config {
 	var buildMode android.SoongBuildMode
+	var bazelForceEnabledModules []string
+	if len(cmdlineArgs.BazelForceEnabledModules) > 0 {
+		bazelForceEnabledModules = strings.Split(cmdlineArgs.BazelForceEnabledModules, ",")
+	}
 
 	if symlinkForestMarker != "" {
 		buildMode = android.SymlinkForest
@@ -141,7 +146,7 @@
 		buildMode = android.AnalysisNoBazel
 	}
 
-	configuration, err := android.NewConfig(cmdlineArgs.ModuleListFile, buildMode, runGoTests, outDir, soongOutDir, availableEnv)
+	configuration, err := android.NewConfig(cmdlineArgs.ModuleListFile, buildMode, runGoTests, outDir, soongOutDir, availableEnv, bazelForceEnabledModules)
 	if err != nil {
 		fmt.Fprintf(os.Stderr, "%s", err)
 		os.Exit(1)
diff --git a/java/base.go b/java/base.go
index 5d24981..55d77dc 100644
--- a/java/base.go
+++ b/java/base.go
@@ -868,7 +868,7 @@
 	flags = append(flags, genAidlIncludeFlags(ctx, aidlSrcs, includeDirs))
 
 	sdkVersion := (j.SdkVersion(ctx)).Kind
-	defaultTrace := ((sdkVersion == android.SdkSystemServer) || (sdkVersion == android.SdkCore) || (sdkVersion == android.SdkCorePlatform) || (sdkVersion == android.SdkModule))
+	defaultTrace := ((sdkVersion == android.SdkSystemServer) || (sdkVersion == android.SdkCore) || (sdkVersion == android.SdkCorePlatform) || (sdkVersion == android.SdkModule) || (sdkVersion == android.SdkSystem))
 	if proptools.BoolDefault(j.deviceProperties.Aidl.Generate_traces, defaultTrace) {
 		flags = append(flags, "-t")
 	}
diff --git a/ui/build/config.go b/ui/build/config.go
index c98601e..7651a0f 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -109,6 +109,8 @@
 	emptyNinjaFile bool
 
 	metricsUploader string
+
+	bazelForceEnabledModules string
 }
 
 const srcDirFileCheck = "build/soong/root.bp"
@@ -238,7 +240,7 @@
 }
 
 func defaultBazelProdMode(cfg *configImpl) bool {
-	// Envirnoment flag to disable Bazel for users which experience
+	// Environment flag to disable Bazel for users which experience
 	// broken bazel-handled builds, or significant performance regressions.
 	if cfg.IsBazelMixedBuildForceDisabled() {
 		return false
@@ -741,6 +743,14 @@
 			c.bazelStagingMode = true
 		} else if arg == "--search-api-dir" {
 			c.searchApiDir = true
+		} else if strings.HasPrefix(arg, "--build-command=") {
+			buildCmd := strings.TrimPrefix(arg, "--build-command=")
+			// remove quotations
+			buildCmd = strings.TrimPrefix(buildCmd, "\"")
+			buildCmd = strings.TrimSuffix(buildCmd, "\"")
+			ctx.Metrics.SetBuildCommand([]string{buildCmd})
+		} else if strings.HasPrefix(arg, "--bazel-force-enabled-modules=") {
+			c.bazelForceEnabledModules = strings.TrimPrefix(arg, "--bazel-force-enabled-modules=")
 		} else if len(arg) > 0 && arg[0] == '-' {
 			parseArgNum := func(def int) int {
 				if len(arg) > 2 {
@@ -1488,6 +1498,10 @@
 	return c.Environment().IsEnvTrue("BUILD_BROKEN_DISABLE_BAZEL")
 }
 
+func (c *configImpl) BazelModulesForceEnabledByFlag() string {
+	return c.bazelForceEnabledModules
+}
+
 func GetMetricsUploader(topDir string, env *Environment) string {
 	if p, ok := env.Get("METRICS_UPLOADER"); ok {
 		metricsUploader := filepath.Join(topDir, p)
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 837f0a4..de3179a 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -273,6 +273,10 @@
 	if config.bazelStagingMode {
 		mainSoongBuildExtraArgs = append(mainSoongBuildExtraArgs, "--bazel-mode-staging")
 	}
+	if len(config.bazelForceEnabledModules) > 0 {
+		mainSoongBuildExtraArgs = append(mainSoongBuildExtraArgs, "--bazel-force-enabled-modules="+config.bazelForceEnabledModules)
+	}
+
 	queryviewDir := filepath.Join(config.SoongOutDir(), "queryview")
 	// The BUILD files will be generated in out/soong/.api_bp2build (no symlinks to src files)
 	// The final workspace will be generated in out/soong/api_bp2build