Merge "Add jdk.internal.math to package_allowed_list.txt (OpenJDK 11)"
diff --git a/android/Android.bp b/android/Android.bp
index 1bccd7b..5901ed9 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -66,7 +66,6 @@
         "prebuilt.go",
         "prebuilt_build_tool.go",
         "proto.go",
-        "queryview.go",
         "register.go",
         "rule_builder.go",
         "sandbox.go",
diff --git a/android/bazel.go b/android/bazel.go
index bebb61b..692fbcd 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -120,6 +120,10 @@
 	// allows modules to opt-out.
 	Bp2BuildDefaultTrueRecursively BazelConversionConfigEntry = iota + 1
 
+	// all modules in this package (not recursively) default to bp2build_available: true.
+	// allows modules to opt-out.
+	Bp2BuildDefaultTrue
+
 	// all modules in this package (not recursively) default to bp2build_available: false.
 	// allows modules to opt-in.
 	Bp2BuildDefaultFalse
@@ -141,6 +145,7 @@
 		"build/bazel/bazel_skylib":/* recursive = */ true,
 		"build/bazel/rules":/* recursive = */ true,
 		"build/bazel/rules_cc":/* recursive = */ true,
+		"build/bazel/scripts":/* recursive = */ true,
 		"build/bazel/tests":/* recursive = */ true,
 		"build/bazel/platforms":/* recursive = */ true,
 		"build/bazel/product_variables":/* recursive = */ true,
@@ -164,7 +169,9 @@
 		"build/bazel/examples/apex/minimal": Bp2BuildDefaultTrueRecursively,
 		"development/sdk":                   Bp2BuildDefaultTrueRecursively,
 		"external/gwp_asan":                 Bp2BuildDefaultTrueRecursively,
+		"external/brotli":                   Bp2BuildDefaultTrue,
 		"system/core/libcutils":             Bp2BuildDefaultTrueRecursively,
+		"system/core/libprocessgroup":       Bp2BuildDefaultTrue,
 		"system/core/property_service/libpropertyinfoparser": Bp2BuildDefaultTrueRecursively,
 		"system/libbase":                  Bp2BuildDefaultTrueRecursively,
 		"system/logging/liblog":           Bp2BuildDefaultTrueRecursively,
@@ -173,6 +180,7 @@
 		"external/arm-optimized-routines": Bp2BuildDefaultTrueRecursively,
 		"external/fmtlib":                 Bp2BuildDefaultTrueRecursively,
 		"external/jemalloc_new":           Bp2BuildDefaultTrueRecursively,
+		"external/libcxx":                 Bp2BuildDefaultTrueRecursively,
 		"external/libcxxabi":              Bp2BuildDefaultTrueRecursively,
 		"external/scudo":                  Bp2BuildDefaultTrueRecursively,
 		"prebuilts/clang/host/linux-x86":  Bp2BuildDefaultTrueRecursively,
@@ -217,6 +225,12 @@
 
 		"gwp_asan_crash_handler", // cc_library, ld.lld: error: undefined symbol: memset
 
+		//system/core/libprocessgroup/...
+		"libprocessgroup", // depends on //system/core/libprocessgroup/cgrouprc:libcgrouprc
+
+		//external/brotli/...
+		"brotli-fuzzer-corpus", // "declared output 'external/brotli/c/fuzz/73231c6592f195ffd41100b8706d1138ff6893b9' was not created by genrule"
+
 		// Tests. Handle later.
 		"libbionic_tests_headers_posix", // http://b/186024507, cc_library_static, sched.h, time.h not found
 		"libjemalloc5_integrationtest",
@@ -237,8 +251,12 @@
 	// Per-module denylist to opt modules out of mixed builds. Such modules will
 	// still be generated via bp2build.
 	mixedBuildsDisabledList = []string{
-		"libc++abi",      // http://b/195970501, cc_library_static, duplicate symbols because it propagates libc objects.
-		"libc++demangle", // http://b/195970501, cc_library_static, duplicate symbols because it propagates libc objects.
+		"libbrotli",           // http://b/198585397, ld.lld: error: bionic/libc/arch-arm64/generic/bionic/memmove.S:95:(.text+0x10): relocation R_AARCH64_CONDBR19 out of range: -1404176 is not in [-1048576, 1048575]; references __memcpy
+		"libc++fs",            // http://b/198403271, Missing symbols/members in the global namespace when referenced from headers in //external/libcxx/includes
+		"libc++_experimental", // http://b/198403271, Missing symbols/members in the global namespace when referenced from headers in //external/libcxx/includes
+		"libc++_static",       // http://b/198403271, Missing symbols/members in the global namespace when referenced from headers in //external/libcxx/includes
+		"libc++abi",           // http://b/195970501, cc_library_static, duplicate symbols because it propagates libc objects.
+		"libc++demangle",      // http://b/195970501, cc_library_static, duplicate symbols because it propagates libc objects.
 	}
 
 	// Used for quicker lookups
@@ -340,11 +358,10 @@
 func bp2buildDefaultTrueRecursively(packagePath string, config Bp2BuildConfig) bool {
 	ret := false
 
-	// Return exact matches in the config.
-	if config[packagePath] == Bp2BuildDefaultTrueRecursively {
+	// Check if the package path has an exact match in the config.
+	if config[packagePath] == Bp2BuildDefaultTrue || config[packagePath] == Bp2BuildDefaultTrueRecursively {
 		return true
-	}
-	if config[packagePath] == Bp2BuildDefaultFalse {
+	} else if config[packagePath] == Bp2BuildDefaultFalse {
 		return false
 	}
 
diff --git a/android/config.go b/android/config.go
index 1482e5d..e0fc266 100644
--- a/android/config.go
+++ b/android/config.go
@@ -72,13 +72,29 @@
 }
 
 func (c Config) OutDir() string {
-	return c.soongOutDir
+	return c.outDir
+}
+
+func (c Config) RunGoTests() bool {
+	return c.runGoTests
+}
+
+func (c Config) UseValidationsForGoTests() bool {
+	return c.useValidationsForGoTests
 }
 
 func (c Config) DebugCompilation() bool {
 	return false // Never compile Go code in the main build for debugging
 }
 
+func (c Config) Subninjas() []string {
+	return []string{}
+}
+
+func (c Config) PrimaryBuilderInvocations() []bootstrap.PrimaryBuilderInvocation {
+	return []bootstrap.PrimaryBuilderInvocation{}
+}
+
 // A DeviceConfig object represents the configuration for a particular device
 // being built. For now there will only be one of these, but in the future there
 // may be multiple devices being built.
@@ -122,9 +138,13 @@
 
 	deviceConfig *deviceConfig
 
-	soongOutDir    string // the path of the build output directory
+	outDir         string // The output directory (usually out/)
+	soongOutDir    string
 	moduleListFile string // the path to the file which lists blueprint files to parse.
 
+	runGoTests               bool
+	useValidationsForGoTests bool
+
 	env       map[string]string
 	envLock   sync.Mutex
 	envDeps   map[string]string
@@ -283,9 +303,10 @@
 
 // NullConfig returns a mostly empty Config for use by standalone tools like dexpreopt_gen that
 // use the android package.
-func NullConfig(soongOutDir string) Config {
+func NullConfig(outDir, soongOutDir string) Config {
 	return Config{
 		config: &config{
+			outDir:      outDir,
 			soongOutDir: soongOutDir,
 			fs:          pathtools.OsFs,
 		},
@@ -319,6 +340,9 @@
 			ShippingApiLevel:                  stringPtr("30"),
 		},
 
+		outDir: buildDir,
+		// soongOutDir is inconsistent with production (it should be buildDir + "/soong")
+		// but a lot of tests assume this :(
 		soongOutDir:  buildDir,
 		captureBuild: true,
 		env:          envCopy,
@@ -396,8 +420,8 @@
 // bootstrap run. Only per-run data is reset. Data which needs to persist across
 // multiple runs in the same program execution is carried over (such as Bazel
 // context or environment deps).
-func ConfigForAdditionalRun(c Config) (Config, error) {
-	newConfig, err := NewConfig(c.soongOutDir, c.moduleListFile, c.env)
+func ConfigForAdditionalRun(cmdlineArgs bootstrap.Args, c Config) (Config, error) {
+	newConfig, err := NewConfig(cmdlineArgs, c.soongOutDir, c.env)
 	if err != nil {
 		return Config{}, err
 	}
@@ -408,17 +432,20 @@
 
 // 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(soongOutDir string, moduleListFile string, availableEnv map[string]string) (Config, error) {
+func NewConfig(cmdlineArgs bootstrap.Args, soongOutDir string, availableEnv map[string]string) (Config, error) {
 	// Make a config with default options.
 	config := &config{
 		ProductVariablesFileName: filepath.Join(soongOutDir, productVariablesFileName),
 
 		env: availableEnv,
 
-		soongOutDir:       soongOutDir,
-		multilibConflicts: make(map[ArchType]bool),
+		outDir:                   cmdlineArgs.OutDir,
+		soongOutDir:              soongOutDir,
+		runGoTests:               cmdlineArgs.RunGoTests,
+		useValidationsForGoTests: cmdlineArgs.UseValidations,
+		multilibConflicts:        make(map[ArchType]bool),
 
-		moduleListFile: moduleListFile,
+		moduleListFile: cmdlineArgs.ModuleListFile,
 		fs:             pathtools.NewOsFs(absSrcDir),
 	}
 
@@ -525,7 +552,7 @@
 	pathsToParse := []string{}
 	for candidate := range mockFS {
 		base := filepath.Base(candidate)
-		if base == "Blueprints" || base == "Android.bp" {
+		if base == "Android.bp" {
 			pathsToParse = append(pathsToParse, candidate)
 		}
 	}
diff --git a/android/license_kind_test.go b/android/license_kind_test.go
index 1f09568..7a909a6 100644
--- a/android/license_kind_test.go
+++ b/android/license_kind_test.go
@@ -14,38 +14,38 @@
 	{
 		name: "license_kind must not accept licenses property",
 		fs: map[string][]byte{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				license_kind {
 					name: "top_license",
 					licenses: ["other_license"],
 				}`),
 		},
 		expectedErrors: []string{
-			`top/Blueprints:4:14: unrecognized property "licenses"`,
+			`top/Android.bp:4:14: unrecognized property "licenses"`,
 		},
 	},
 	{
 		name: "bad license_kind",
 		fs: map[string][]byte{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				license_kind {
 					name: "top_notice",
 					conditions: ["notice"],
 				}`),
-			"other/Blueprints": []byte(`
+			"other/Android.bp": []byte(`
 				mock_license {
 					name: "other_notice",
 					license_kinds: ["notice"],
 				}`),
 		},
 		expectedErrors: []string{
-			`other/Blueprints:2:5: "other_notice" depends on undefined module "notice"`,
+			`other/Android.bp:2:5: "other_notice" depends on undefined module "notice"`,
 		},
 	},
 	{
 		name: "good license kind",
 		fs: map[string][]byte{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				license_kind {
 					name: "top_by_exception_only",
 					conditions: ["by_exception_only"],
@@ -55,7 +55,7 @@
 					name: "top_proprietary",
 					license_kinds: ["top_by_exception_only"],
 				}`),
-			"other/Blueprints": []byte(`
+			"other/Android.bp": []byte(`
 				mock_license {
 					name: "other_proprietary",
 					license_kinds: ["top_proprietary"],
@@ -65,7 +65,7 @@
 	{
 		name: "multiple license kinds",
 		fs: map[string][]byte{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				license_kind {
 					name: "top_notice",
 					conditions: ["notice"],
@@ -85,7 +85,7 @@
 					name: "top_proprietary",
 					license_kinds: ["top_by_exception_only"],
 				}`),
-			"other/Blueprints": []byte(`
+			"other/Android.bp": []byte(`
 				mock_license {
 					name: "other_rule",
 					license_kinds: ["top_by_exception_only"],
diff --git a/android/license_test.go b/android/license_test.go
index 26b33c3..7222cd7 100644
--- a/android/license_test.go
+++ b/android/license_test.go
@@ -27,7 +27,7 @@
 	{
 		name: "license must not accept licenses property",
 		fs: map[string][]byte{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				license {
 					name: "top_license",
 					visibility: ["//visibility:private"],
@@ -35,13 +35,13 @@
 				}`),
 		},
 		expectedErrors: []string{
-			`top/Blueprints:5:14: unrecognized property "licenses"`,
+			`top/Android.bp:5:14: unrecognized property "licenses"`,
 		},
 	},
 	{
 		name: "private license",
 		fs: map[string][]byte{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				license_kind {
 					name: "top_notice",
 					conditions: ["notice"],
@@ -53,27 +53,27 @@
 					license_kinds: ["top_notice"],
 					visibility: ["//visibility:private"],
 				}`),
-			"other/Blueprints": []byte(`
+			"other/Android.bp": []byte(`
 				rule {
 					name: "arule",
 					licenses: ["top_allowed_as_notice"],
 				}`),
-			"yetmore/Blueprints": []byte(`
+			"yetmore/Android.bp": []byte(`
 				package {
 					default_applicable_licenses: ["top_allowed_as_notice"],
 				}`),
 		},
 		expectedErrors: []string{
-			`other/Blueprints:2:5: module "arule": depends on //top:top_allowed_as_notice ` +
+			`other/Android.bp:2:5: module "arule": depends on //top:top_allowed_as_notice ` +
 				`which is not visible to this module`,
-			`yetmore/Blueprints:2:5: module "//yetmore": depends on //top:top_allowed_as_notice ` +
+			`yetmore/Android.bp:2:5: module "//yetmore": depends on //top:top_allowed_as_notice ` +
 				`which is not visible to this module`,
 		},
 	},
 	{
 		name: "must reference license_kind module",
 		fs: map[string][]byte{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				rule {
 					name: "top_by_exception_only",
 				}
@@ -85,14 +85,14 @@
 				}`),
 		},
 		expectedErrors: []string{
-			`top/Blueprints:6:5: module "top_proprietary": license_kinds property ` +
+			`top/Android.bp:6:5: module "top_proprietary": license_kinds property ` +
 				`"top_by_exception_only" is not a license_kind module`,
 		},
 	},
 	{
 		name: "license_kind module must exist",
 		fs: map[string][]byte{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				license {
 					name: "top_notice_allowed",
 					license_kinds: ["top_notice"],
@@ -100,13 +100,13 @@
 				}`),
 		},
 		expectedErrors: []string{
-			`top/Blueprints:2:5: "top_notice_allowed" depends on undefined module "top_notice"`,
+			`top/Android.bp:2:5: "top_notice_allowed" depends on undefined module "top_notice"`,
 		},
 	},
 	{
 		name: "public license",
 		fs: map[string][]byte{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				license_kind {
 					name: "top_by_exception_only",
 					conditions: ["by_exception_only"],
@@ -118,12 +118,12 @@
 					license_kinds: ["top_by_exception_only"],
 					visibility: ["//visibility:public"],
 				}`),
-			"other/Blueprints": []byte(`
+			"other/Android.bp": []byte(`
 				rule {
 					name: "arule",
 					licenses: ["top_proprietary"],
 				}`),
-			"yetmore/Blueprints": []byte(`
+			"yetmore/Android.bp": []byte(`
 				package {
 					default_applicable_licenses: ["top_proprietary"],
 				}`),
@@ -132,7 +132,7 @@
 	{
 		name: "multiple licenses",
 		fs: map[string][]byte{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				package {
 					default_applicable_licenses: ["top_proprietary"],
 				}
@@ -162,12 +162,12 @@
 					name: "myrule",
 					licenses: ["top_allowed_as_notice", "top_proprietary"]
 				}`),
-			"other/Blueprints": []byte(`
+			"other/Android.bp": []byte(`
 				rule {
 					name: "arule",
 					licenses: ["top_proprietary"],
 				}`),
-			"yetmore/Blueprints": []byte(`
+			"yetmore/Android.bp": []byte(`
 				package {
 					default_applicable_licenses: ["top_proprietary"],
 				}`),
diff --git a/android/licenses.go b/android/licenses.go
index 464ba49..d54f8f4 100644
--- a/android/licenses.go
+++ b/android/licenses.go
@@ -293,7 +293,7 @@
 	case "*android.soongConfigModuleTypeModule": // creates aliases for modules with licenses
 	case "*android.soongConfigModuleTypeImport": // creates aliases for modules with licenses
 	case "*android.soongConfigStringVariableDummyModule": // used for creating aliases
-	case "*android.SoongConfigBoolVariableDummyModule": // used for creating aliases
+	case "*android.soongConfigBoolVariableDummyModule": // used for creating aliases
 	default:
 		return false
 	}
diff --git a/android/licenses_test.go b/android/licenses_test.go
index 8503310..d05b0a3 100644
--- a/android/licenses_test.go
+++ b/android/licenses_test.go
@@ -20,7 +20,7 @@
 	{
 		name: "invalid module type without licenses property",
 		fs: map[string][]byte{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_bad_module {
 					name: "libexample",
 				}`),
@@ -30,7 +30,7 @@
 	{
 		name: "license must exist",
 		fs: map[string][]byte{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_library {
 					name: "libexample",
 					licenses: ["notice"],
@@ -41,7 +41,7 @@
 	{
 		name: "all good",
 		fs: map[string][]byte{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				license_kind {
 					name: "notice",
 					conditions: ["shownotice"],
@@ -58,12 +58,12 @@
 					name: "libexample1",
 					licenses: ["top_Apache2"],
 				}`),
-			"top/nested/Blueprints": []byte(`
+			"top/nested/Android.bp": []byte(`
 				mock_library {
 					name: "libnested",
 					licenses: ["top_Apache2"],
 				}`),
-			"other/Blueprints": []byte(`
+			"other/Android.bp": []byte(`
 				mock_library {
 					name: "libother",
 					licenses: ["top_Apache2"],
@@ -101,7 +101,7 @@
 		// Check that licenses is the union of the defaults modules.
 		name: "defaults union, basic",
 		fs: map[string][]byte{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				license_kind {
 					name: "top_notice",
 					conditions: ["notice"],
@@ -125,7 +125,7 @@
 					name: "libsamepackage",
 					deps: ["libexample"],
 				}`),
-			"top/nested/Blueprints": []byte(`
+			"top/nested/Android.bp": []byte(`
 				license_kind {
 					name: "nested_notice",
 					conditions: ["notice"],
@@ -140,7 +140,7 @@
 					name: "libnested",
 					deps: ["libexample"],
 				}`),
-			"other/Blueprints": []byte(`
+			"other/Android.bp": []byte(`
 				mock_library {
 					name: "libother",
 					deps: ["libexample"],
@@ -174,7 +174,7 @@
 	{
 		name: "defaults union, multiple defaults",
 		fs: map[string][]byte{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				license {
 					name: "top",
 				}
@@ -194,7 +194,7 @@
 					name: "libsamepackage",
 					deps: ["libexample"],
 				}`),
-			"top/nested/Blueprints": []byte(`
+			"top/nested/Android.bp": []byte(`
 				license {
 					name: "top_nested",
 					license_text: ["LICENSE.txt"],
@@ -203,7 +203,7 @@
 					name: "libnested",
 					deps: ["libexample"],
 				}`),
-			"other/Blueprints": []byte(`
+			"other/Android.bp": []byte(`
 				license {
 					name: "other",
 				}
@@ -211,7 +211,7 @@
 					name: "libother",
 					deps: ["libexample"],
 				}`),
-			"outsider/Blueprints": []byte(`
+			"outsider/Android.bp": []byte(`
 				mock_library {
 					name: "liboutsider",
 					deps: ["libexample"],
@@ -251,7 +251,7 @@
 	{
 		name: "defaults_licenses invalid",
 		fs: map[string][]byte{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_defaults {
 					name: "top_defaults",
 					licenses: ["notice"],
@@ -262,7 +262,7 @@
 	{
 		name: "defaults_licenses overrides package default",
 		fs: map[string][]byte{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				package {
 					default_applicable_licenses: ["by_exception_only"],
 				}
@@ -298,7 +298,7 @@
 	{
 		name: "package default_applicable_licenses must exist",
 		fs: map[string][]byte{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				package {
 					default_applicable_licenses: ["notice"],
 				}`),
@@ -309,7 +309,7 @@
 		// This test relies on the default licenses being legacy_public.
 		name: "package default_applicable_licenses property used when no licenses specified",
 		fs: map[string][]byte{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				package {
 					default_applicable_licenses: ["top_notice"],
 				}
@@ -320,7 +320,7 @@
 				mock_library {
 					name: "libexample",
 				}`),
-			"outsider/Blueprints": []byte(`
+			"outsider/Android.bp": []byte(`
 				mock_library {
 					name: "liboutsider",
 					deps: ["libexample"],
@@ -338,7 +338,7 @@
 	{
 		name: "package default_applicable_licenses not inherited to subpackages",
 		fs: map[string][]byte{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				package {
 					default_applicable_licenses: ["top_notice"],
 				}
@@ -348,7 +348,7 @@
 				mock_library {
 					name: "libexample",
 				}`),
-			"top/nested/Blueprints": []byte(`
+			"top/nested/Android.bp": []byte(`
 				package {
 					default_applicable_licenses: ["outsider"],
 				}
@@ -356,11 +356,11 @@
 				mock_library {
 					name: "libnested",
 				}`),
-			"top/other/Blueprints": []byte(`
+			"top/other/Android.bp": []byte(`
 				mock_library {
 					name: "libother",
 				}`),
-			"outsider/Blueprints": []byte(`
+			"outsider/Android.bp": []byte(`
 				license {
 					name: "outsider",
 				}
@@ -385,7 +385,7 @@
 	{
 		name: "verify that prebuilt dependencies are included",
 		fs: map[string][]byte{
-			"prebuilts/Blueprints": []byte(`
+			"prebuilts/Android.bp": []byte(`
 				license {
 					name: "prebuilt"
 				}
@@ -394,7 +394,7 @@
 					licenses: ["prebuilt"],
 				}`),
 			"top/sources/source_file": nil,
-			"top/sources/Blueprints": []byte(`
+			"top/sources/Android.bp": []byte(`
 				license {
 					name: "top_sources"
 				}
@@ -403,7 +403,7 @@
 					licenses: ["top_sources"],
 				}`),
 			"top/other/source_file": nil,
-			"top/other/Blueprints": []byte(`
+			"top/other/Android.bp": []byte(`
 				source {
 					name: "other",
 					deps: [":module"],
@@ -419,7 +419,7 @@
 	{
 		name: "verify that prebuilt dependencies are ignored for licenses reasons (preferred)",
 		fs: map[string][]byte{
-			"prebuilts/Blueprints": []byte(`
+			"prebuilts/Android.bp": []byte(`
 				license {
 					name: "prebuilt"
 				}
@@ -429,7 +429,7 @@
 					prefer: true,
 				}`),
 			"top/sources/source_file": nil,
-			"top/sources/Blueprints": []byte(`
+			"top/sources/Android.bp": []byte(`
 				license {
 					name: "top_sources"
 				}
@@ -438,7 +438,7 @@
 					licenses: ["top_sources"],
 				}`),
 			"top/other/source_file": nil,
-			"top/other/Blueprints": []byte(`
+			"top/other/Android.bp": []byte(`
 				source {
 					name: "other",
 					deps: [":module"],
diff --git a/android/override_module.go b/android/override_module.go
index e72cb78..51e74d4 100644
--- a/android/override_module.go
+++ b/android/override_module.go
@@ -295,7 +295,7 @@
 }
 
 func overridableModuleDepsMutator(ctx BottomUpMutatorContext) {
-	if b, ok := ctx.Module().(OverridableModule); ok {
+	if b, ok := ctx.Module().(OverridableModule); ok && b.Enabled() {
 		b.OverridablePropertiesDepsMutator(ctx)
 	}
 }
diff --git a/android/package_test.go b/android/package_test.go
index 3bd30cc..7ea10a4 100644
--- a/android/package_test.go
+++ b/android/package_test.go
@@ -13,7 +13,7 @@
 	{
 		name: "package must not accept visibility and name properties",
 		fs: map[string][]byte{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				package {
 					name: "package",
 					visibility: ["//visibility:private"],
@@ -21,21 +21,21 @@
 				}`),
 		},
 		expectedErrors: []string{
-			`top/Blueprints:5:14: unrecognized property "licenses"`,
-			`top/Blueprints:3:10: unrecognized property "name"`,
-			`top/Blueprints:4:16: unrecognized property "visibility"`,
+			`top/Android.bp:5:14: unrecognized property "licenses"`,
+			`top/Android.bp:3:10: unrecognized property "name"`,
+			`top/Android.bp:4:16: unrecognized property "visibility"`,
 		},
 	},
 	{
 		name: "multiple packages in separate directories",
 		fs: map[string][]byte{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				package {
 				}`),
-			"other/Blueprints": []byte(`
+			"other/Android.bp": []byte(`
 				package {
 				}`),
-			"other/nested/Blueprints": []byte(`
+			"other/nested/Android.bp": []byte(`
 				package {
 				}`),
 		},
@@ -43,7 +43,7 @@
 	{
 		name: "package must not be specified more than once per package",
 		fs: map[string][]byte{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				package {
 					default_visibility: ["//visibility:private"],
 					default_applicable_licenses: ["license"],
diff --git a/android/queryview.go b/android/queryview.go
deleted file mode 100644
index 224652e..0000000
--- a/android/queryview.go
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2020 Google Inc. All rights reserved.
-//
-// 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.
-
-package android
-
-import (
-	"fmt"
-	"os"
-	"strings"
-
-	"github.com/google/blueprint"
-)
-
-// The Bazel QueryView singleton is responsible for generating the Ninja actions
-// for calling the soong_build primary builder in the main build.ninja file.
-func init() {
-	RegisterSingletonType("bazel_queryview", BazelQueryViewSingleton)
-}
-
-// BazelQueryViewSingleton is the singleton responsible for registering the
-// soong_build build statement that will convert the Soong module graph after
-// applying *all* mutators, enabing the feature to query the final state of the
-// Soong graph. This mode is meant for querying the build graph state, and not meant
-// for generating BUILD files to be checked in.
-func BazelQueryViewSingleton() Singleton {
-	return &bazelQueryViewSingleton{}
-}
-
-// BazelConverterSingleton is the singleton responsible for registering the soong_build
-// build statement that will convert the Soong module graph by applying an alternate
-// pipeline of mutators, with the goal of reaching semantic equivalence between the original
-// Blueprint and final BUILD files. Using this mode, the goal is to be able to
-// build with these BUILD files directly in the source tree.
-func BazelConverterSingleton() Singleton {
-	return &bazelConverterSingleton{}
-}
-
-type bazelQueryViewSingleton struct{}
-type bazelConverterSingleton struct{}
-
-func generateBuildActionsForBazelConversion(ctx SingletonContext, converterMode bool) {
-	name := "queryview"
-	descriptionTemplate := "[EXPERIMENTAL, PRE-PRODUCTION] Creating the Bazel QueryView workspace with %s at $outDir"
-
-	// Create a build and rule statement, using the Bazel QueryView's WORKSPACE
-	// file as the output file marker.
-	var deps Paths
-	moduleListFilePath := pathForBuildToolDep(ctx, ctx.Config().moduleListFile)
-	deps = append(deps, moduleListFilePath)
-	deps = append(deps, pathForBuildToolDep(ctx, ctx.Config().ProductVariablesFileName))
-
-	bazelQueryViewDirectory := PathForOutput(ctx, name)
-	bazelQueryViewWorkspaceFile := bazelQueryViewDirectory.Join(ctx, "WORKSPACE")
-	primaryBuilder := primaryBuilderPath(ctx)
-	bazelQueryView := ctx.Rule(pctx, "bazelQueryView",
-		blueprint.RuleParams{
-			Command: fmt.Sprintf(
-				`rm -rf "${outDir}/"* && `+
-					`mkdir -p "${outDir}" && `+
-					`echo WORKSPACE: $$(cat "%s") > "${outDir}/.queryview-depfile.d" && `+
-					`BUILDER="%s" && `+
-					`echo BUILDER=$$BUILDER && `+
-					`cd "$$(dirname "$$BUILDER")" && `+
-					`echo PWD=$$PWD && `+
-					`ABSBUILDER="$$PWD/$$(basename "$$BUILDER")" && `+
-					`echo ABSBUILDER=$$ABSBUILDER && `+
-					`cd / && `+
-					`env -i "$$ABSBUILDER" --bazel_queryview_dir "${outDir}" "%s"`,
-				moduleListFilePath.String(), // Use the contents of Android.bp.list as the depfile.
-				primaryBuilder.String(),
-				strings.Join(os.Args[1:], "\" \""),
-			),
-			CommandDeps: []string{primaryBuilder.String()},
-			Description: fmt.Sprintf(
-				descriptionTemplate,
-				primaryBuilder.Base()),
-			Deps:    blueprint.DepsGCC,
-			Depfile: "${outDir}/.queryview-depfile.d",
-		},
-		"outDir")
-
-	ctx.Build(pctx, BuildParams{
-		Rule:   bazelQueryView,
-		Output: bazelQueryViewWorkspaceFile,
-		Inputs: deps,
-		Args: map[string]string{
-			"outDir": bazelQueryViewDirectory.String(),
-		},
-	})
-
-	// Add a phony target for generating the workspace
-	ctx.Phony(name, bazelQueryViewWorkspaceFile)
-}
-
-func (c *bazelQueryViewSingleton) GenerateBuildActions(ctx SingletonContext) {
-	generateBuildActionsForBazelConversion(ctx, false)
-}
-
-func (c *bazelConverterSingleton) GenerateBuildActions(ctx SingletonContext) {
-	generateBuildActionsForBazelConversion(ctx, true)
-}
diff --git a/android/visibility_test.go b/android/visibility_test.go
index ffd7909..714c92a 100644
--- a/android/visibility_test.go
+++ b/android/visibility_test.go
@@ -16,7 +16,7 @@
 	{
 		name: "invalid visibility: empty list",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_library {
 					name: "libexample",
 					visibility: [],
@@ -27,7 +27,7 @@
 	{
 		name: "invalid visibility: empty rule",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_library {
 					name: "libexample",
 					visibility: [""],
@@ -38,7 +38,7 @@
 	{
 		name: "invalid visibility: unqualified",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_library {
 					name: "libexample",
 					visibility: ["target"],
@@ -49,7 +49,7 @@
 	{
 		name: "invalid visibility: empty namespace",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_library {
 					name: "libexample",
 					visibility: ["//"],
@@ -60,7 +60,7 @@
 	{
 		name: "invalid visibility: empty module",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_library {
 					name: "libexample",
 					visibility: [":"],
@@ -71,7 +71,7 @@
 	{
 		name: "invalid visibility: empty namespace and module",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_library {
 					name: "libexample",
 					visibility: ["//:"],
@@ -82,7 +82,7 @@
 	{
 		name: "//visibility:unknown",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_library {
 					name: "libexample",
 					visibility: ["//visibility:unknown"],
@@ -93,7 +93,7 @@
 	{
 		name: "//visibility:xxx mixed",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_library {
 					name: "libexample",
 					visibility: ["//visibility:public", "//namespace"],
@@ -114,7 +114,7 @@
 	{
 		name: "//visibility:legacy_public",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_library {
 					name: "libexample",
 					visibility: ["//visibility:legacy_public"],
@@ -130,7 +130,7 @@
 		// the current directory, a nested directory and a directory in a separate tree.
 		name: "//visibility:public",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_library {
 					name: "libexample",
 					visibility: ["//visibility:public"],
@@ -140,12 +140,12 @@
 					name: "libsamepackage",
 					deps: ["libexample"],
 				}`),
-			"top/nested/Blueprints": []byte(`
+			"top/nested/Android.bp": []byte(`
 				mock_library {
 					name: "libnested",
 					deps: ["libexample"],
 				}`),
-			"other/Blueprints": []byte(`
+			"other/Android.bp": []byte(`
 				mock_library {
 					name: "libother",
 					deps: ["libexample"],
@@ -157,7 +157,7 @@
 		// directory only.
 		name: "//visibility:private",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_library {
 					name: "libexample",
 					visibility: ["//visibility:private"],
@@ -167,12 +167,12 @@
 					name: "libsamepackage",
 					deps: ["libexample"],
 				}`),
-			"top/nested/Blueprints": []byte(`
+			"top/nested/Android.bp": []byte(`
 				mock_library {
 					name: "libnested",
 					deps: ["libexample"],
 				}`),
-			"other/Blueprints": []byte(`
+			"other/Android.bp": []byte(`
 				mock_library {
 					name: "libother",
 					deps: ["libexample"],
@@ -189,7 +189,7 @@
 		// Verify that :__pkg__ allows the module to be referenced from the current directory only.
 		name: ":__pkg__",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_library {
 					name: "libexample",
 					visibility: [":__pkg__"],
@@ -199,12 +199,12 @@
 					name: "libsamepackage",
 					deps: ["libexample"],
 				}`),
-			"top/nested/Blueprints": []byte(`
+			"top/nested/Android.bp": []byte(`
 				mock_library {
 					name: "libnested",
 					deps: ["libexample"],
 				}`),
-			"other/Blueprints": []byte(`
+			"other/Android.bp": []byte(`
 				mock_library {
 					name: "libother",
 					deps: ["libexample"],
@@ -222,7 +222,7 @@
 		// the top/nested directory only, not a subdirectory of top/nested and not peak directory.
 		name: "//top/nested",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_library {
 					name: "libexample",
 					visibility: ["//top/nested"],
@@ -232,17 +232,17 @@
 					name: "libsamepackage",
 					deps: ["libexample"],
 				}`),
-			"top/nested/Blueprints": []byte(`
+			"top/nested/Android.bp": []byte(`
 				mock_library {
 					name: "libnested",
 					deps: ["libexample"],
 				}`),
-			"top/nested/again/Blueprints": []byte(`
+			"top/nested/again/Android.bp": []byte(`
 				mock_library {
 					name: "libnestedagain",
 					deps: ["libexample"],
 				}`),
-			"peak/Blueprints": []byte(`
+			"peak/Android.bp": []byte(`
 				mock_library {
 					name: "libother",
 					deps: ["libexample"],
@@ -260,7 +260,7 @@
 		// and sub directories but nowhere else.
 		name: ":__subpackages__",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_library {
 					name: "libexample",
 					visibility: [":__subpackages__"],
@@ -270,12 +270,12 @@
 					name: "libsamepackage",
 					deps: ["libexample"],
 				}`),
-			"top/nested/Blueprints": []byte(`
+			"top/nested/Android.bp": []byte(`
 				mock_library {
 					name: "libnested",
 					deps: ["libexample"],
 				}`),
-			"peak/other/Blueprints": []byte(`
+			"peak/other/Android.bp": []byte(`
 				mock_library {
 					name: "libother",
 					deps: ["libexample"],
@@ -291,7 +291,7 @@
 		// directory and sub directories but nowhere else.
 		name: "//top/nested:__subpackages__",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_library {
 					name: "libexample",
 					visibility: ["//top/nested:__subpackages__", "//other"],
@@ -301,12 +301,12 @@
 					name: "libsamepackage",
 					deps: ["libexample"],
 				}`),
-			"top/nested/Blueprints": []byte(`
+			"top/nested/Android.bp": []byte(`
 				mock_library {
 					name: "libnested",
 					deps: ["libexample"],
 				}`),
-			"top/other/Blueprints": []byte(`
+			"top/other/Android.bp": []byte(`
 				mock_library {
 					name: "libother",
 					deps: ["libexample"],
@@ -322,7 +322,7 @@
 		// the current directory, top/nested and peak and all its subpackages.
 		name: `["//top/nested", "//peak:__subpackages__"]`,
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_library {
 					name: "libexample",
 					visibility: ["//top/nested", "//peak:__subpackages__"],
@@ -332,12 +332,12 @@
 					name: "libsamepackage",
 					deps: ["libexample"],
 				}`),
-			"top/nested/Blueprints": []byte(`
+			"top/nested/Android.bp": []byte(`
 				mock_library {
 					name: "libnested",
 					deps: ["libexample"],
 				}`),
-			"peak/other/Blueprints": []byte(`
+			"peak/other/Android.bp": []byte(`
 				mock_library {
 					name: "libother",
 					deps: ["libexample"],
@@ -348,7 +348,7 @@
 		// Verify that //vendor... cannot be used outside vendor apart from //vendor:__subpackages__
 		name: `//vendor`,
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_library {
 					name: "libexample",
 					visibility: ["//vendor:__subpackages__"],
@@ -358,13 +358,13 @@
 					name: "libsamepackage",
 					visibility: ["//vendor/apps/AcmeSettings"],
 				}`),
-			"vendor/Blueprints": []byte(`
+			"vendor/Android.bp": []byte(`
 				mock_library {
 					name: "libvendorexample",
 					deps: ["libexample"],
 					visibility: ["//vendor/nested"],
 				}`),
-			"vendor/nested/Blueprints": []byte(`
+			"vendor/nested/Android.bp": []byte(`
 				mock_library {
 					name: "libvendornested",
 					deps: ["libexample", "libvendorexample"],
@@ -382,7 +382,7 @@
 		// Check that visibility is the union of the defaults modules.
 		name: "defaults union, basic",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_defaults {
 					name: "libexample_defaults",
 					visibility: ["//other"],
@@ -396,17 +396,17 @@
 					name: "libsamepackage",
 					deps: ["libexample"],
 				}`),
-			"top/nested/Blueprints": []byte(`
+			"top/nested/Android.bp": []byte(`
 				mock_library {
 					name: "libnested",
 					deps: ["libexample"],
 				}`),
-			"other/Blueprints": []byte(`
+			"other/Android.bp": []byte(`
 				mock_library {
 					name: "libother",
 					deps: ["libexample"],
 				}`),
-			"outsider/Blueprints": []byte(`
+			"outsider/Android.bp": []byte(`
 				mock_library {
 					name: "liboutsider",
 					deps: ["libexample"],
@@ -420,7 +420,7 @@
 	{
 		name: "defaults union, multiple defaults",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_defaults {
 					name: "libexample_defaults_1",
 					visibility: ["//other"],
@@ -437,17 +437,17 @@
 					name: "libsamepackage",
 					deps: ["libexample"],
 				}`),
-			"top/nested/Blueprints": []byte(`
+			"top/nested/Android.bp": []byte(`
 				mock_library {
 					name: "libnested",
 					deps: ["libexample"],
 				}`),
-			"other/Blueprints": []byte(`
+			"other/Android.bp": []byte(`
 				mock_library {
 					name: "libother",
 					deps: ["libexample"],
 				}`),
-			"outsider/Blueprints": []byte(`
+			"outsider/Android.bp": []byte(`
 				mock_library {
 					name: "liboutsider",
 					deps: ["libexample"],
@@ -461,7 +461,7 @@
 	{
 		name: "//visibility:public mixed with other in defaults",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_defaults {
 					name: "libexample_defaults",
 					visibility: ["//visibility:public", "//namespace"],
@@ -479,7 +479,7 @@
 	{
 		name: "//visibility:public overriding defaults",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_defaults {
 					name: "libexample_defaults",
 					visibility: ["//namespace"],
@@ -489,7 +489,7 @@
 					visibility: ["//visibility:public"],
 					defaults: ["libexample_defaults"],
 				}`),
-			"outsider/Blueprints": []byte(`
+			"outsider/Android.bp": []byte(`
 				mock_library {
 					name: "liboutsider",
 					deps: ["libexample"],
@@ -502,7 +502,7 @@
 	{
 		name: "//visibility:public mixed with other from different defaults 1",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_defaults {
 					name: "libexample_defaults_1",
 					visibility: ["//namespace"],
@@ -515,7 +515,7 @@
 					name: "libexample",
 					defaults: ["libexample_defaults_1", "libexample_defaults_2"],
 				}`),
-			"outsider/Blueprints": []byte(`
+			"outsider/Android.bp": []byte(`
 				mock_library {
 					name: "liboutsider",
 					deps: ["libexample"],
@@ -525,7 +525,7 @@
 	{
 		name: "//visibility:public mixed with other from different defaults 2",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_defaults {
 					name: "libexample_defaults_1",
 					visibility: ["//visibility:public"],
@@ -538,7 +538,7 @@
 					name: "libexample",
 					defaults: ["libexample_defaults_1", "libexample_defaults_2"],
 				}`),
-			"outsider/Blueprints": []byte(`
+			"outsider/Android.bp": []byte(`
 				mock_library {
 					name: "liboutsider",
 					deps: ["libexample"],
@@ -548,7 +548,7 @@
 	{
 		name: "//visibility:private in defaults",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_defaults {
 					name: "libexample_defaults",
 					visibility: ["//visibility:private"],
@@ -561,12 +561,12 @@
 					name: "libsamepackage",
 					deps: ["libexample"],
 				}`),
-			"top/nested/Blueprints": []byte(`
+			"top/nested/Android.bp": []byte(`
 				mock_library {
 					name: "libnested",
 					deps: ["libexample"],
 				}`),
-			"other/Blueprints": []byte(`
+			"other/Android.bp": []byte(`
 				mock_library {
 					name: "libother",
 					deps: ["libexample"],
@@ -582,7 +582,7 @@
 	{
 		name: "//visibility:private mixed with other in defaults",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_defaults {
 					name: "libexample_defaults",
 					visibility: ["//visibility:private", "//namespace"],
@@ -600,7 +600,7 @@
 	{
 		name: "//visibility:private overriding defaults",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_defaults {
 					name: "libexample_defaults",
 					visibility: ["//namespace"],
@@ -619,7 +619,7 @@
 	{
 		name: "//visibility:private in defaults overridden",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_defaults {
 					name: "libexample_defaults",
 					visibility: ["//visibility:private"],
@@ -638,7 +638,7 @@
 	{
 		name: "//visibility:private override //visibility:public",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_defaults {
 					name: "libexample_defaults",
 					visibility: ["//visibility:public"],
@@ -656,7 +656,7 @@
 	{
 		name: "//visibility:public override //visibility:private",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_defaults {
 					name: "libexample_defaults",
 					visibility: ["//visibility:private"],
@@ -674,7 +674,7 @@
 	{
 		name: "//visibility:override must be first in the list",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_library {
 					name: "libexample",
 					visibility: ["//other", "//visibility:override", "//namespace"],
@@ -687,7 +687,7 @@
 	{
 		name: "//visibility:override discards //visibility:private",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_defaults {
 					name: "libexample_defaults",
 					visibility: ["//visibility:private"],
@@ -698,7 +698,7 @@
 					visibility: ["//visibility:override", "//other"],
 					defaults: ["libexample_defaults"],
 				}`),
-			"other/Blueprints": []byte(`
+			"other/Android.bp": []byte(`
 				mock_library {
 					name: "libother",
 					deps: ["libexample"],
@@ -708,7 +708,7 @@
 	{
 		name: "//visibility:override discards //visibility:public",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_defaults {
 					name: "libexample_defaults",
 					visibility: ["//visibility:public"],
@@ -719,12 +719,12 @@
 					visibility: ["//visibility:override", "//other"],
 					defaults: ["libexample_defaults"],
 				}`),
-			"other/Blueprints": []byte(`
+			"other/Android.bp": []byte(`
 				mock_library {
 					name: "libother",
 					deps: ["libexample"],
 				}`),
-			"namespace/Blueprints": []byte(`
+			"namespace/Android.bp": []byte(`
 				mock_library {
 					name: "libnamespace",
 					deps: ["libexample"],
@@ -737,7 +737,7 @@
 	{
 		name: "//visibility:override discards defaults supplied rules",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_defaults {
 					name: "libexample_defaults",
 					visibility: ["//namespace"],
@@ -748,12 +748,12 @@
 					visibility: ["//visibility:override", "//other"],
 					defaults: ["libexample_defaults"],
 				}`),
-			"other/Blueprints": []byte(`
+			"other/Android.bp": []byte(`
 				mock_library {
 					name: "libother",
 					deps: ["libexample"],
 				}`),
-			"namespace/Blueprints": []byte(`
+			"namespace/Android.bp": []byte(`
 				mock_library {
 					name: "libnamespace",
 					deps: ["libexample"],
@@ -766,7 +766,7 @@
 	{
 		name: "//visibility:override can override //visibility:public with //visibility:private",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_defaults {
 					name: "libexample_defaults",
 					visibility: ["//visibility:public"],
@@ -776,7 +776,7 @@
 					visibility: ["//visibility:override", "//visibility:private"],
 					defaults: ["libexample_defaults"],
 				}`),
-			"namespace/Blueprints": []byte(`
+			"namespace/Android.bp": []byte(`
 				mock_library {
 					name: "libnamespace",
 					deps: ["libexample"],
@@ -789,7 +789,7 @@
 	{
 		name: "//visibility:override can override //visibility:private with //visibility:public",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_defaults {
 					name: "libexample_defaults",
 					visibility: ["//visibility:private"],
@@ -799,7 +799,7 @@
 					visibility: ["//visibility:override", "//visibility:public"],
 					defaults: ["libexample_defaults"],
 				}`),
-			"namespace/Blueprints": []byte(`
+			"namespace/Android.bp": []byte(`
 				mock_library {
 					name: "libnamespace",
 					deps: ["libexample"],
@@ -809,7 +809,7 @@
 	{
 		name: "//visibility:private mixed with itself",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_defaults {
 					name: "libexample_defaults_1",
 					visibility: ["//visibility:private"],
@@ -823,7 +823,7 @@
 					visibility: ["//visibility:private"],
 					defaults: ["libexample_defaults_1", "libexample_defaults_2"],
 				}`),
-			"outsider/Blueprints": []byte(`
+			"outsider/Android.bp": []byte(`
 				mock_library {
 					name: "liboutsider",
 					deps: ["libexample"],
@@ -839,7 +839,7 @@
 	{
 		name: "defaults_visibility invalid",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_defaults {
 					name: "top_defaults",
 					defaults_visibility: ["//visibility:invalid"],
@@ -852,7 +852,7 @@
 	{
 		name: "defaults_visibility overrides package default",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				package {
 					default_visibility: ["//visibility:private"],
 				}
@@ -860,7 +860,7 @@
 					name: "top_defaults",
 					defaults_visibility: ["//visibility:public"],
 				}`),
-			"outsider/Blueprints": []byte(`
+			"outsider/Android.bp": []byte(`
 				mock_library {
 					name: "liboutsider",
 					defaults: ["top_defaults"],
@@ -872,7 +872,7 @@
 	{
 		name: "package default_visibility property is checked",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				package {
 					default_visibility: ["//visibility:invalid"],
 				}`),
@@ -883,7 +883,7 @@
 		// This test relies on the default visibility being legacy_public.
 		name: "package default_visibility property used when no visibility specified",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				package {
 					default_visibility: ["//visibility:private"],
 				}
@@ -891,7 +891,7 @@
 				mock_library {
 					name: "libexample",
 				}`),
-			"outsider/Blueprints": []byte(`
+			"outsider/Android.bp": []byte(`
 				mock_library {
 					name: "liboutsider",
 					deps: ["libexample"],
@@ -905,7 +905,7 @@
 	{
 		name: "package default_visibility public does not override visibility private",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				package {
 					default_visibility: ["//visibility:public"],
 				}
@@ -914,7 +914,7 @@
 					name: "libexample",
 					visibility: ["//visibility:private"],
 				}`),
-			"outsider/Blueprints": []byte(`
+			"outsider/Android.bp": []byte(`
 				mock_library {
 					name: "liboutsider",
 					deps: ["libexample"],
@@ -928,7 +928,7 @@
 	{
 		name: "package default_visibility private does not override visibility public",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				package {
 					default_visibility: ["//visibility:private"],
 				}
@@ -937,7 +937,7 @@
 					name: "libexample",
 					visibility: ["//visibility:public"],
 				}`),
-			"outsider/Blueprints": []byte(`
+			"outsider/Android.bp": []byte(`
 				mock_library {
 					name: "liboutsider",
 					deps: ["libexample"],
@@ -947,7 +947,7 @@
 	{
 		name: "package default_visibility :__subpackages__",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				package {
 					default_visibility: [":__subpackages__"],
 				}
@@ -955,12 +955,12 @@
 				mock_library {
 					name: "libexample",
 				}`),
-			"top/nested/Blueprints": []byte(`
+			"top/nested/Android.bp": []byte(`
 				mock_library {
 					name: "libnested",
 					deps: ["libexample"],
 				}`),
-			"outsider/Blueprints": []byte(`
+			"outsider/Android.bp": []byte(`
 				mock_library {
 					name: "liboutsider",
 					deps: ["libexample"],
@@ -974,7 +974,7 @@
 	{
 		name: "package default_visibility inherited to subpackages",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				package {
 					default_visibility: ["//outsider"],
 				}
@@ -983,12 +983,12 @@
 					name: "libexample",
           visibility: [":__subpackages__"],
 				}`),
-			"top/nested/Blueprints": []byte(`
+			"top/nested/Android.bp": []byte(`
 				mock_library {
 					name: "libnested",
 					deps: ["libexample"],
 				}`),
-			"outsider/Blueprints": []byte(`
+			"outsider/Android.bp": []byte(`
 				mock_library {
 					name: "liboutsider",
 					deps: ["libexample", "libnested"],
@@ -1002,11 +1002,11 @@
 	{
 		name: "package default_visibility inherited to subpackages",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				package {
 					default_visibility: ["//visibility:private"],
 				}`),
-			"top/nested/Blueprints": []byte(`
+			"top/nested/Android.bp": []byte(`
 				package {
 					default_visibility: ["//outsider"],
 				}
@@ -1014,11 +1014,11 @@
 				mock_library {
 					name: "libnested",
 				}`),
-			"top/other/Blueprints": []byte(`
+			"top/other/Android.bp": []byte(`
 				mock_library {
 					name: "libother",
 				}`),
-			"outsider/Blueprints": []byte(`
+			"outsider/Android.bp": []byte(`
 				mock_library {
 					name: "liboutsider",
 					deps: ["libother", "libnested"],
@@ -1032,19 +1032,19 @@
 	{
 		name: "verify that prebuilt dependencies are ignored for visibility reasons (not preferred)",
 		fs: MockFS{
-			"prebuilts/Blueprints": []byte(`
+			"prebuilts/Android.bp": []byte(`
 				prebuilt {
 					name: "module",
 					visibility: ["//top/other"],
 				}`),
 			"top/sources/source_file": nil,
-			"top/sources/Blueprints": []byte(`
+			"top/sources/Android.bp": []byte(`
 				source {
 					name: "module",
 					visibility: ["//top/other"],
 				}`),
 			"top/other/source_file": nil,
-			"top/other/Blueprints": []byte(`
+			"top/other/Android.bp": []byte(`
 				source {
 					name: "other",
 					deps: [":module"],
@@ -1054,20 +1054,20 @@
 	{
 		name: "verify that prebuilt dependencies are ignored for visibility reasons (preferred)",
 		fs: MockFS{
-			"prebuilts/Blueprints": []byte(`
+			"prebuilts/Android.bp": []byte(`
 				prebuilt {
 					name: "module",
 					visibility: ["//top/other"],
 					prefer: true,
 				}`),
 			"top/sources/source_file": nil,
-			"top/sources/Blueprints": []byte(`
+			"top/sources/Android.bp": []byte(`
 				source {
 					name: "module",
 					visibility: ["//top/other"],
 				}`),
 			"top/other/source_file": nil,
-			"top/other/Blueprints": []byte(`
+			"top/other/Android.bp": []byte(`
 				source {
 					name: "other",
 					deps: [":module"],
@@ -1077,7 +1077,7 @@
 	{
 		name: "ensure visibility properties are checked for correctness",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_parent {
 					name: "parent",
 					visibility: ["//top/nested"],
@@ -1094,7 +1094,7 @@
 	{
 		name: "invalid visibility added to child detected during gather phase",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_parent {
 					name: "parent",
 					visibility: ["//top/nested"],
@@ -1116,7 +1116,7 @@
 	{
 		name: "automatic visibility inheritance enabled",
 		fs: MockFS{
-			"top/Blueprints": []byte(`
+			"top/Android.bp": []byte(`
 				mock_parent {
 					name: "parent",
 					visibility: ["//top/nested"],
@@ -1125,12 +1125,12 @@
 						visibility: ["//top/other"],
 					},
 				}`),
-			"top/nested/Blueprints": []byte(`
+			"top/nested/Android.bp": []byte(`
 				mock_library {
 					name: "libnested",
 					deps: ["libchild"],
 				}`),
-			"top/other/Blueprints": []byte(`
+			"top/other/Android.bp": []byte(`
 				mock_library {
 					name: "libother",
 					deps: ["libchild"],
diff --git a/apex/apex.go b/apex/apex.go
index 6bafcae..fbf6a6f 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -111,9 +111,6 @@
 	// List of java libraries that are embedded inside this APEX bundle.
 	Java_libs []string
 
-	// List of prebuilt files that are embedded inside this APEX bundle.
-	Prebuilts []string
-
 	// List of platform_compat_config files that are embedded inside this APEX bundle.
 	Compat_configs []string
 
@@ -291,6 +288,9 @@
 	// List of APKs that are embedded inside this APEX.
 	Apps []string
 
+	// List of prebuilt files that are embedded inside this APEX bundle.
+	Prebuilts []string
+
 	// List of runtime resource overlays (RROs) that are embedded inside this APEX.
 	Rros []string
 
@@ -684,7 +684,6 @@
 	// each target os/architectures, appropriate dependencies are selected by their
 	// target.<os>.multilib.<type> groups and are added as (direct) dependencies.
 	targets := ctx.MultiTargets()
-	config := ctx.DeviceConfig()
 	imageVariation := a.getImageVariation(ctx)
 
 	a.combineProperties(ctx)
@@ -758,23 +757,6 @@
 		}
 	}
 
-	if prebuilts := a.properties.Prebuilts; len(prebuilts) > 0 {
-		// For prebuilt_etc, use the first variant (64 on 64/32bit device, 32 on 32bit device)
-		// regardless of the TARGET_PREFER_* setting. See b/144532908
-		archForPrebuiltEtc := config.Arches()[0]
-		for _, arch := range config.Arches() {
-			// Prefer 64-bit arch if there is any
-			if arch.ArchType.Multilib == "lib64" {
-				archForPrebuiltEtc = arch
-				break
-			}
-		}
-		ctx.AddFarVariationDependencies([]blueprint.Variation{
-			{Mutator: "os", Variation: ctx.Os().String()},
-			{Mutator: "arch", Variation: archForPrebuiltEtc.String()},
-		}, prebuiltTag, prebuilts...)
-	}
-
 	// Common-arch dependencies come next
 	commonVariation := ctx.Config().AndroidCommonTarget.Variations()
 	ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.properties.Bootclasspath_fragments...)
@@ -814,6 +796,25 @@
 	ctx.AddFarVariationDependencies(commonVariation, androidAppTag, a.overridableProperties.Apps...)
 	ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.overridableProperties.Bpfs...)
 	ctx.AddFarVariationDependencies(commonVariation, rroTag, a.overridableProperties.Rros...)
+	if prebuilts := a.overridableProperties.Prebuilts; len(prebuilts) > 0 {
+		// For prebuilt_etc, use the first variant (64 on 64/32bit device, 32 on 32bit device)
+		// regardless of the TARGET_PREFER_* setting. See b/144532908
+		arches := ctx.DeviceConfig().Arches()
+		if len(arches) != 0 {
+			archForPrebuiltEtc := arches[0]
+			for _, arch := range arches {
+				// Prefer 64-bit arch if there is any
+				if arch.ArchType.Multilib == "lib64" {
+					archForPrebuiltEtc = arch
+					break
+				}
+			}
+			ctx.AddFarVariationDependencies([]blueprint.Variation{
+				{Mutator: "os", Variation: ctx.Os().String()},
+				{Mutator: "arch", Variation: archForPrebuiltEtc.String()},
+			}, prebuiltTag, prebuilts...)
+		}
+	}
 
 	// Dependencies for signing
 	if String(a.overridableProperties.Key) == "" {
@@ -3282,7 +3283,7 @@
 	nativeSharedLibsLabelList := android.BazelLabelForModuleDeps(ctx, nativeSharedLibs)
 	nativeSharedLibsLabelListAttribute := bazel.MakeLabelListAttribute(nativeSharedLibsLabelList)
 
-	prebuilts := module.properties.Prebuilts
+	prebuilts := module.overridableProperties.Prebuilts
 	prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, prebuilts)
 	prebuiltsLabelListAttribute := bazel.MakeLabelListAttribute(prebuiltsLabelList)
 
diff --git a/apex/apex_test.go b/apex/apex_test.go
index daaa5cb..5c7c90b 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -6080,6 +6080,7 @@
 			key: "myapex.key",
 			apps: ["app"],
 			bpfs: ["bpf"],
+			prebuilts: ["myetc"],
 			overrides: ["oldapex"],
 			updatable: false,
 		}
@@ -6089,6 +6090,7 @@
 			base: "myapex",
 			apps: ["override_app"],
 			bpfs: ["override_bpf"],
+			prebuilts: ["override_myetc"],
 			overrides: ["unknownapex"],
 			logging_parent: "com.foo.bar",
 			package_name: "test.overridden.package",
@@ -6137,6 +6139,16 @@
 			name: "override_bpf",
 			srcs: ["override_bpf.c"],
 		}
+
+		prebuilt_etc {
+			name: "myetc",
+			src: "myprebuilt",
+		}
+
+		prebuilt_etc {
+			name: "override_myetc",
+			src: "override_myprebuilt",
+		}
 	`, withManifestPackageNameOverrides([]string{"myapex:com.android.myapex"}))
 
 	originalVariant := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(android.OverridableModule)
@@ -6158,6 +6170,9 @@
 	ensureNotContains(t, copyCmds, "image.apex/etc/bpf/bpf.o")
 	ensureContains(t, copyCmds, "image.apex/etc/bpf/override_bpf.o")
 
+	ensureNotContains(t, copyCmds, "image.apex/etc/myetc")
+	ensureContains(t, copyCmds, "image.apex/etc/override_myetc")
+
 	apexBundle := module.Module().(*apexBundle)
 	name := apexBundle.Name()
 	if name != "override_myapex" {
diff --git a/bpfix/cmd_lib/bpfix.go b/bpfix/cmd_lib/bpfix.go
index f90f65b..1106d4a 100644
--- a/bpfix/cmd_lib/bpfix.go
+++ b/bpfix/cmd_lib/bpfix.go
@@ -114,7 +114,7 @@
 
 func makeFileVisitor(fixRequest bpfix.FixRequest) func(string, os.FileInfo, error) error {
 	return func(path string, f os.FileInfo, err error) error {
-		if err == nil && (f.Name() == "Blueprints" || f.Name() == "Android.bp") {
+		if err == nil && f.Name() == "Android.bp" {
 			err = openAndProcess(path, os.Stdout, fixRequest)
 		}
 		if err != nil {
diff --git a/cc/builder.go b/cc/builder.go
index d0527cb..748377b 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -205,11 +205,13 @@
 			Labels:       map[string]string{"type": "lint", "tool": "clang-tidy", "lang": "cpp"},
 			ExecStrategy: "${config.REClangTidyExecStrategy}",
 			Inputs:       []string{"$in"},
-			// OutputFile here is $in for remote-execution since its possible that
-			// clang-tidy modifies the given input file itself and $out refers to the
-			// ".tidy" file generated for ninja-dependency reasons.
-			OutputFiles: []string{"$in"},
-			Platform:    map[string]string{remoteexec.PoolKey: "${config.REClangTidyPool}"},
+			// Although clang-tidy has an option to "fix" source files, that feature is hardly useable
+			// under parallel compilation and RBE. So we assume no OutputFiles here.
+			// The clang-tidy fix option is best run locally in single thread.
+			// Copying source file back to local caused two problems:
+			// (1) New timestamps trigger clang and clang-tidy compilations again.
+			// (2) Changing source files caused concurrent clang or clang-tidy jobs to crash.
+			Platform: map[string]string{remoteexec.PoolKey: "${config.REClangTidyPool}"},
 		}, []string{"cFlags", "tidyFlags"}, []string{})
 
 	_ = pctx.SourcePathVariable("yasmCmd", "prebuilts/misc/${config.HostPrebuiltTag}/yasm/yasm")
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 51cdddf..704b03a 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -45,11 +45,17 @@
 	abidw = pctx.AndroidStaticRule("abidw",
 		blueprint.RuleParams{
 			Command: "$abidw --type-id-style hash --no-corpus-path " +
-				"--no-show-locs --no-comp-dir-path -w $symbolList $in | " +
-				"$abitidy --all -o $out",
-			CommandDeps: []string{"$abitidy", "$abidw"},
+				"--no-show-locs --no-comp-dir-path -w $symbolList " +
+				"$in --out-file $out",
+			CommandDeps: []string{"$abidw"},
 		}, "symbolList")
 
+	abitidy = pctx.AndroidStaticRule("abitidy",
+		blueprint.RuleParams{
+			Command:     "$abitidy --all -i $in -o $out",
+			CommandDeps: []string{"$abitidy"},
+		})
+
 	abidiff = pctx.AndroidStaticRule("abidiff",
 		blueprint.RuleParams{
 			// Need to create *some* output for ninja. We don't want to use tee
@@ -313,19 +319,28 @@
 
 func (this *stubDecorator) dumpAbi(ctx ModuleContext, symbolList android.Path) {
 	implementationLibrary := this.findImplementationLibrary(ctx)
-	this.abiDumpPath = getNdkAbiDumpInstallBase(ctx).Join(ctx,
+	abiRawPath := getNdkAbiDumpInstallBase(ctx).Join(ctx,
 		this.apiLevel.String(), ctx.Arch().ArchType.String(),
-		this.libraryName(ctx), "abi.xml")
+		this.libraryName(ctx), "abi.raw.xml")
 	ctx.Build(pctx, android.BuildParams{
 		Rule:        abidw,
 		Description: fmt.Sprintf("abidw %s", implementationLibrary),
-		Output:      this.abiDumpPath,
 		Input:       implementationLibrary,
+		Output:      abiRawPath,
 		Implicit:    symbolList,
 		Args: map[string]string{
 			"symbolList": symbolList.String(),
 		},
 	})
+	this.abiDumpPath = getNdkAbiDumpInstallBase(ctx).Join(ctx,
+		this.apiLevel.String(), ctx.Arch().ArchType.String(),
+		this.libraryName(ctx), "abi.xml")
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        abitidy,
+		Description: fmt.Sprintf("abitidy %s", implementationLibrary),
+		Input:       abiRawPath,
+		Output:      this.abiDumpPath,
+	})
 }
 
 func findNextApiLevel(ctx ModuleContext, apiLevel android.ApiLevel) *android.ApiLevel {
diff --git a/cc/test_data_test.go b/cc/test_data_test.go
index 426dfc5..a621166 100644
--- a/cc/test_data_test.go
+++ b/cc/test_data_test.go
@@ -127,7 +127,7 @@
 			ctx.RegisterModuleType("test", newTest)
 			ctx.Register()
 
-			_, errs := ctx.ParseBlueprintsFiles("Blueprints")
+			_, errs := ctx.ParseBlueprintsFiles("Android.bp")
 			android.FailIfErrored(t, errs)
 			_, errs = ctx.PrepareBuildActions(config)
 			android.FailIfErrored(t, errs)
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 16a4e1a..2cad785 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -35,7 +35,7 @@
 
 var (
 	topDir           string
-	outDir           string
+	soongOutDir      string
 	availableEnvFile string
 	usedEnvFile      string
 
@@ -55,13 +55,12 @@
 func init() {
 	// Flags that make sense in every mode
 	flag.StringVar(&topDir, "top", "", "Top directory of the Android source tree")
-	flag.StringVar(&outDir, "out", "", "Soong output directory (usually $TOP/out/soong)")
+	flag.StringVar(&soongOutDir, "soong_out", "", "Soong output directory (usually $TOP/out/soong)")
 	flag.StringVar(&availableEnvFile, "available_env", "", "File containing available environment variables")
 	flag.StringVar(&usedEnvFile, "used_env", "", "File containing used environment variables")
 	flag.StringVar(&globFile, "globFile", "build-globs.ninja", "the Ninja file of globs to output")
 	flag.StringVar(&globListDir, "globListDir", "", "the directory containing the glob list files")
-	flag.StringVar(&cmdlineArgs.SoongOutDir, "b", ".", "the build output directory")
-	flag.StringVar(&cmdlineArgs.OutDir, "n", "", "the ninja builddir directory")
+	flag.StringVar(&cmdlineArgs.OutDir, "out", "", "the ninja builddir directory")
 	flag.StringVar(&cmdlineArgs.ModuleListFile, "l", "", "file that lists filepaths to parse")
 
 	// Debug flags
@@ -113,8 +112,8 @@
 	return ctx
 }
 
-func newConfig(outDir string, availableEnv map[string]string) android.Config {
-	configuration, err := android.NewConfig(outDir, cmdlineArgs.ModuleListFile, availableEnv)
+func newConfig(cmdlineArgs bootstrap.Args, outDir string, availableEnv map[string]string) android.Config {
+	configuration, err := android.NewConfig(cmdlineArgs, outDir, availableEnv)
 	if err != nil {
 		fmt.Fprintf(os.Stderr, "%s", err)
 		os.Exit(1)
@@ -140,13 +139,13 @@
 		os.Exit(1)
 	}
 	// Second pass: Full analysis, using the bazel command results. Output ninja file.
-	secondConfig, err := android.ConfigForAdditionalRun(configuration)
+	secondArgs = cmdlineArgs
+	secondConfig, err := android.ConfigForAdditionalRun(secondArgs, configuration)
 	if err != nil {
 		fmt.Fprintf(os.Stderr, "%s", err)
 		os.Exit(1)
 	}
 	secondCtx := newContext(secondConfig, true)
-	secondArgs = cmdlineArgs
 	ninjaDeps := bootstrap.RunBlueprint(secondArgs, secondCtx.Context, secondConfig)
 	ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
 
@@ -157,13 +156,15 @@
 }
 
 // Run the code-generation phase to convert BazelTargetModules to BUILD files.
-func runQueryView(configuration android.Config, ctx *android.Context) {
+func runQueryView(queryviewDir, queryviewMarker string, configuration android.Config, ctx *android.Context) {
 	codegenContext := bp2build.NewCodegenContext(configuration, *ctx, bp2build.QueryView)
-	absoluteQueryViewDir := shared.JoinPath(topDir, bazelQueryViewDir)
+	absoluteQueryViewDir := shared.JoinPath(topDir, queryviewDir)
 	if err := createBazelQueryView(codegenContext, absoluteQueryViewDir); err != nil {
 		fmt.Fprintf(os.Stderr, "%s", err)
 		os.Exit(1)
 	}
+
+	touch(shared.JoinPath(topDir, queryviewMarker))
 }
 
 func runSoongDocs(configuration android.Config) {
@@ -245,8 +246,10 @@
 
 		// Convert the Soong module graph into Bazel BUILD files.
 		if generateQueryView {
-			runQueryView(configuration, ctx)
-			return cmdlineArgs.OutFile // TODO: This is a lie
+			queryviewMarkerFile := bazelQueryViewDir + ".marker"
+			runQueryView(bazelQueryViewDir, queryviewMarkerFile, configuration, ctx)
+			writeDepFile(queryviewMarkerFile, ninjaDeps)
+			return queryviewMarkerFile
 		} else if moduleGraphFile != "" {
 			writeJsonModuleGraph(ctx, moduleGraphFile)
 			writeDepFile(moduleGraphFile, ninjaDeps)
@@ -298,7 +301,7 @@
 
 	availableEnv := parseAvailableEnv()
 
-	configuration := newConfig(outDir, availableEnv)
+	configuration := newConfig(cmdlineArgs, soongOutDir, availableEnv)
 	extraNinjaDeps := []string{
 		configuration.ProductVariablesFileName,
 		usedEnvFile,
diff --git a/cmd/soong_build/queryview.go b/cmd/soong_build/queryview.go
index a8602de..98e27c6 100644
--- a/cmd/soong_build/queryview.go
+++ b/cmd/soong_build/queryview.go
@@ -15,14 +15,16 @@
 package main
 
 import (
-	"android/soong/android"
-	"android/soong/bp2build"
 	"io/ioutil"
 	"os"
 	"path/filepath"
+
+	"android/soong/android"
+	"android/soong/bp2build"
 )
 
 func createBazelQueryView(ctx *bp2build.CodegenContext, bazelQueryViewDir string) error {
+	os.RemoveAll(bazelQueryViewDir)
 	ruleShims := bp2build.CreateRuleShims(android.ModuleTypeFactories())
 
 	// Ignore metrics reporting and compat layers for queryview, since queryview
diff --git a/dexpreopt/dexpreopt_gen/dexpreopt_gen.go b/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
index 7dbe74c..ba05d94 100644
--- a/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
+++ b/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
@@ -87,7 +87,9 @@
 		usage("--module configuration file is required")
 	}
 
-	ctx := &builderContext{android.NullConfig(*outDir)}
+	// NOTE: duplicating --out_dir here is incorrect (one should be the another
+	// plus "/soong" but doing so apparently breaks dexpreopt
+	ctx := &builderContext{android.NullConfig(*outDir, *outDir)}
 
 	globalSoongConfigData, err := ioutil.ReadFile(*globalSoongConfigPath)
 	if err != nil {
diff --git a/java/app_import.go b/java/app_import.go
index b5a6084..3e5f972 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -204,9 +204,9 @@
 		return false
 	}
 
-	// Uncompress dex in APKs of privileged apps
-	if ctx.Config().UncompressPrivAppDex() && a.Privileged() {
-		return true
+	// Uncompress dex in APKs of priv-apps if and only if DONT_UNCOMPRESS_PRIV_APPS_DEXS is false.
+	if a.Privileged() {
+		return ctx.Config().UncompressPrivAppDex()
 	}
 
 	return shouldUncompressDex(ctx, &a.dexpreopter)
diff --git a/java/app_import_test.go b/java/app_import_test.go
index 024a3df..efa52c1 100644
--- a/java/app_import_test.go
+++ b/java/app_import_test.go
@@ -15,6 +15,7 @@
 package java
 
 import (
+	"fmt"
 	"reflect"
 	"regexp"
 	"strings"
@@ -656,3 +657,74 @@
 		}
 	}
 }
+
+func TestAndroidTestImport_UncompressDex(t *testing.T) {
+	testCases := []struct {
+		name string
+		bp   string
+	}{
+		{
+			name: "normal",
+			bp: `
+				android_app_import {
+					name: "foo",
+					presigned: true,
+					apk: "prebuilts/apk/app.apk",
+				}
+			`,
+		},
+		{
+			name: "privileged",
+			bp: `
+				android_app_import {
+					name: "foo",
+					presigned: true,
+					privileged: true,
+					apk: "prebuilts/apk/app.apk",
+				}
+			`,
+		},
+	}
+
+	test := func(t *testing.T, bp string, unbundled bool, dontUncompressPrivAppDexs bool) {
+		t.Helper()
+
+		result := android.GroupFixturePreparers(
+			prepareForJavaTest,
+			android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+				if unbundled {
+					variables.Unbundled_build = proptools.BoolPtr(true)
+				}
+				variables.UncompressPrivAppDex = proptools.BoolPtr(!dontUncompressPrivAppDexs)
+			}),
+		).RunTestWithBp(t, bp)
+
+		foo := result.ModuleForTests("foo", "android_common")
+		actual := foo.MaybeRule("uncompress-dex").Rule != nil
+
+		expect := !unbundled
+		if strings.Contains(bp, "privileged: true") {
+			if dontUncompressPrivAppDexs {
+				expect = false
+			} else {
+				// TODO(b/194504107): shouldn't priv-apps be always uncompressed unless
+				// DONT_UNCOMPRESS_PRIV_APPS_DEXS is true (regardless of unbundling)?
+				// expect = true
+			}
+		}
+
+		android.AssertBoolEquals(t, "uncompress dex", expect, actual)
+	}
+
+	for _, unbundled := range []bool{false, true} {
+		for _, dontUncompressPrivAppDexs := range []bool{false, true} {
+			for _, tt := range testCases {
+				name := fmt.Sprintf("%s,unbundled:%t,dontUncompressPrivAppDexs:%t",
+					tt.name, unbundled, dontUncompressPrivAppDexs)
+				t.Run(name, func(t *testing.T) {
+					test(t, tt.bp, unbundled, dontUncompressPrivAppDexs)
+				})
+			}
+		}
+	}
+}
diff --git a/mk2rbc/mk2rbc_test.go b/mk2rbc/mk2rbc_test.go
index 46212ee..ca7fe6f 100644
--- a/mk2rbc/mk2rbc_test.go
+++ b/mk2rbc/mk2rbc_test.go
@@ -414,7 +414,7 @@
 
 def init(g, handle):
   cfg = rblf.cfg(handle)
-  if rblf.filter(g.get("PRODUCT_LIST", ""), g["TARGET_PRODUCT"]):
+  if rblf.filter(g.get("PRODUCT_LIST", []), g["TARGET_PRODUCT"]):
     pass
 `,
 	},
diff --git a/mk2rbc/variable.go b/mk2rbc/variable.go
index 88d63c9..4bb9ed5 100644
--- a/mk2rbc/variable.go
+++ b/mk2rbc/variable.go
@@ -299,6 +299,10 @@
 					vt = vi.valueType
 				}
 			}
+			if strings.HasSuffix(name, "_LIST") && vt == starlarkTypeUnknown {
+				// Heuristics: Variables with "_LIST" suffix are lists
+				vt = starlarkTypeList
+			}
 			v = &otherGlobalVariable{baseVariable{nam: name, typ: vt}}
 		}
 		ctx.variables[name] = v
diff --git a/tests/bootstrap_test.sh b/tests/bootstrap_test.sh
index b37a7f8..95a193a 100755
--- a/tests/bootstrap_test.sh
+++ b/tests/bootstrap_test.sh
@@ -522,7 +522,7 @@
 
 function test_bp2build_smoke {
   setup
-  GENERATE_BAZEL_FILES=1 run_soong
+  run_soong bp2build
   [[ -e out/soong/.bootstrap/bp2build_workspace_marker ]] || fail "bp2build marker file not created"
   [[ -e out/soong/workspace ]] || fail "Bazel workspace not created"
 }
@@ -531,7 +531,7 @@
   setup
   create_mock_bazel
 
-  run_bp2build
+  run_soong bp2build
 
   if [[ ! -f "./out/soong/.bootstrap/bp2build_workspace_marker" ]]; then
     fail "Marker file was not generated"
@@ -551,7 +551,7 @@
 }
 EOF
 
-  GENERATE_BAZEL_FILES=1 run_soong
+  run_soong bp2build
   [[ -e out/soong/bp2build/a/${GENERATED_BUILD_FILE_NAME} ]] || fail "a/${GENERATED_BUILD_FILE_NAME} not created"
   [[ -L out/soong/workspace/a/${GENERATED_BUILD_FILE_NAME} ]] || fail "a/${GENERATED_BUILD_FILE_NAME} not symlinked"
 
@@ -565,7 +565,7 @@
 }
 EOF
 
-  GENERATE_BAZEL_FILES=1 run_soong
+  run_soong bp2build
   [[ -e out/soong/bp2build/b/${GENERATED_BUILD_FILE_NAME} ]] || fail "a/${GENERATED_BUILD_FILE_NAME} not created"
   [[ -L out/soong/workspace/b/${GENERATED_BUILD_FILE_NAME} ]] || fail "a/${GENERATED_BUILD_FILE_NAME} not symlinked"
 }
@@ -573,10 +573,10 @@
 function test_bp2build_null_build {
   setup
 
-  GENERATE_BAZEL_FILES=1 run_soong
+  run_soong bp2build
   local mtime1=$(stat -c "%y" out/soong/.bootstrap/bp2build_workspace_marker)
 
-  GENERATE_BAZEL_FILES=1 run_soong
+  run_soong bp2build
   local mtime2=$(stat -c "%y" out/soong/.bootstrap/bp2build_workspace_marker)
 
   if [[ "$mtime1" != "$mtime2" ]]; then
@@ -597,18 +597,35 @@
 }
 EOF
 
-  GENERATE_BAZEL_FILES=1 run_soong
+  run_soong bp2build
   grep -q a1.txt "out/soong/bp2build/a/${GENERATED_BUILD_FILE_NAME}" || fail "a1.txt not in ${GENERATED_BUILD_FILE_NAME} file"
 
   touch a/a2.txt
-  GENERATE_BAZEL_FILES=1 run_soong
+  run_soong bp2build
   grep -q a2.txt "out/soong/bp2build/a/${GENERATED_BUILD_FILE_NAME}" || fail "a2.txt not in ${GENERATED_BUILD_FILE_NAME} file"
 }
 
+function test_multiple_soong_build_modes() {
+  setup
+  run_soong json-module-graph bp2build nothing
+  if [[ ! -f "out/soong/.bootstrap/bp2build_workspace_marker" ]]; then
+    fail "bp2build marker file was not generated"
+  fi
+
+
+  if [[ ! -f "out/soong/module-graph.json" ]]; then
+    fail "JSON file was not created"
+  fi
+
+  if [[ ! -f "out/soong/build.ninja" ]]; then
+    fail "Main build.ninja file was not created"
+  fi
+}
+
 function test_dump_json_module_graph() {
   setup
-  GENERATE_JSON_MODULE_GRAPH=1 run_soong
-  if [[ ! -r "out/soong//module-graph.json" ]]; then
+  run_soong json-module-graph
+  if [[ ! -r "out/soong/module-graph.json" ]]; then
     fail "JSON file was not created"
   fi
 }
@@ -619,7 +636,7 @@
   run_soong
   local ninja_mtime1=$(stat -c "%y" out/soong/build.ninja)
 
-  GENERATE_JSON_MODULE_GRAPH=1 run_soong
+  run_soong json-module-graph
   local json_mtime1=$(stat -c "%y" out/soong/module-graph.json)
 
   run_soong
@@ -628,7 +645,7 @@
     fail "Output Ninja file changed after writing JSON module graph"
   fi
 
-  GENERATE_JSON_MODULE_GRAPH=1 run_soong
+  run_soong json-module-graph
   local json_mtime2=$(stat -c "%y" out/soong/module-graph.json)
   if [[ "$json_mtime1" != "$json_mtime2" ]]; then
     fail "JSON module graph file changed after writing Ninja file"
@@ -651,7 +668,7 @@
 }
 EOF
 
-  GENERATE_BAZEL_FILES=1 run_soong
+  run_soong bp2build
   [[ -e out/soong/workspace ]] || fail "Bazel workspace not created"
   [[ -d out/soong/workspace/a/b ]] || fail "module directory not a directory"
   [[ -L "out/soong/workspace/a/b/${GENERATED_BUILD_FILE_NAME}" ]] || fail "${GENERATED_BUILD_FILE_NAME} file not symlinked"
@@ -675,10 +692,10 @@
 }
 EOF
 
-  GENERATE_BAZEL_FILES=1 run_soong
+  run_soong bp2build
 
   touch a/a2.txt  # No reference in the .bp file needed
-  GENERATE_BAZEL_FILES=1 run_soong
+  run_soong bp2build
   [[ -L out/soong/workspace/a/a2.txt ]] || fail "a/a2.txt not symlinked"
 }
 
@@ -696,7 +713,7 @@
 }
 EOF
 
-  GENERATE_BAZEL_FILES=1 run_soong
+  run_soong bp2build
   [[ -L "out/soong/workspace/a/${GENERATED_BUILD_FILE_NAME}" ]] || fail "${GENERATED_BUILD_FILE_NAME} file not symlinked"
   [[ "$(readlink -f out/soong/workspace/a/${GENERATED_BUILD_FILE_NAME})" =~ "bp2build/a/${GENERATED_BUILD_FILE_NAME}"$ ]] \
     || fail "${GENERATED_BUILD_FILE_NAME} files symlinked to the wrong place"
@@ -725,7 +742,7 @@
 }
 EOF
 
-  if GENERATE_BAZEL_FILES=1 run_soong >& "$MOCK_TOP/errors"; then
+  if run_soong bp2build >& "$MOCK_TOP/errors"; then
     fail "Build should have failed"
   fi
 
@@ -739,7 +756,7 @@
   run_soong
   local output_mtime1=$(stat -c "%y" out/soong/build.ninja)
 
-  GENERATE_BAZEL_FILES=1 run_soong
+  run_soong bp2build
   local output_mtime2=$(stat -c "%y" out/soong/build.ninja)
   if [[ "$output_mtime1" != "$output_mtime2" ]]; then
     fail "Output Ninja file changed when switching to bp2build"
@@ -757,7 +774,7 @@
     fail "bp2build marker file changed when switching to regular build from bp2build"
   fi
 
-  GENERATE_BAZEL_FILES=1 run_soong
+  run_soong bp2build
   local output_mtime4=$(stat -c "%y" out/soong/build.ninja)
   local marker_mtime3=$(stat -c "%y" out/soong/.bootstrap/bp2build_workspace_marker)
   if [[ "$output_mtime1" != "$output_mtime4" ]]; then
@@ -768,6 +785,28 @@
   fi
 }
 
+function test_queryview_smoke() {
+  setup
+
+  run_soong queryview
+  [[ -e out/soong/queryview/WORKSPACE ]] || fail "queryview WORKSPACE file not created"
+
+}
+
+function test_queryview_null_build() {
+  setup
+
+  run_soong queryview
+  local output_mtime1=$(stat -c "%y" out/soong/queryview.marker)
+
+  run_soong queryview
+  local output_mtime2=$(stat -c "%y" out/soong/queryview.marker)
+
+  if [[ "$output_mtime1" != "$output_mtime2" ]]; then
+    fail "Queryview marker file changed on null build"
+  fi
+}
+
 test_smoke
 test_null_build
 test_null_build_after_docs
@@ -780,9 +819,12 @@
 test_add_file_to_soong_build
 test_glob_during_bootstrapping
 test_soong_build_rerun_iff_environment_changes
+test_multiple_soong_build_modes
 test_dump_json_module_graph
 test_json_module_graph_back_and_forth_null_build
 test_write_to_source_tree
+test_queryview_smoke
+test_queryview_null_build
 test_bp2build_smoke
 test_bp2build_generates_marker_file
 test_bp2build_null_build
diff --git a/tests/bp2build_bazel_test.sh b/tests/bp2build_bazel_test.sh
index 9bd85a4..379eb65 100755
--- a/tests/bp2build_bazel_test.sh
+++ b/tests/bp2build_bazel_test.sh
@@ -10,10 +10,10 @@
 
 function test_bp2build_null_build() {
   setup
-  run_bp2build
+  run_soong bp2build
   local output_mtime1=$(stat -c "%y" out/soong/.bootstrap/bp2build_workspace_marker)
 
-  run_bp2build
+  run_soong bp2build
   local output_mtime2=$(stat -c "%y" out/soong/.bootstrap/bp2build_workspace_marker)
 
   if [[ "$output_mtime1" != "$output_mtime2" ]]; then
@@ -35,10 +35,10 @@
 EOF
   touch foo/bar/a.txt foo/bar/b.txt
 
-  run_bp2build
+  run_soong bp2build
   local output_mtime1=$(stat -c "%y" out/soong/.bootstrap/bp2build_workspace_marker)
 
-  run_bp2build
+  run_soong bp2build
   local output_mtime2=$(stat -c "%y" out/soong/.bootstrap/bp2build_workspace_marker)
 
   if [[ "$output_mtime1" != "$output_mtime2" ]]; then
@@ -80,7 +80,7 @@
   }
 EOF
 
-  run_bp2build
+  run_soong bp2build
 
   if [[ ! -f "./out/soong/workspace/foo/convertible_soong_module/${GENERATED_BUILD_FILE_NAME}" ]]; then
     fail "./out/soong/workspace/foo/convertible_soong_module/${GENERATED_BUILD_FILE_NAME} was not generated"
diff --git a/tests/lib.sh b/tests/lib.sh
index 813a9dd..e777820 100644
--- a/tests/lib.sh
+++ b/tests/lib.sh
@@ -124,10 +124,6 @@
   tools/bazel "$@"
 }
 
-run_bp2build() {
-  GENERATE_BAZEL_FILES=true build/soong/soong_ui.bash --make-mode --skip-ninja --skip-make --skip-soong-tests nothing
-}
-
 run_ninja() {
   build/soong/soong_ui.bash --make-mode --skip-make --skip-soong-tests "$@"
 }
diff --git a/ui/build/build.go b/ui/build/build.go
index d869bf0..2e44aaa 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -248,6 +248,16 @@
 		what = what &^ RunNinja
 	}
 
+	if !config.SoongBuildInvocationNeeded() {
+		// This means that the output of soong_build is not needed and thus it would
+		// run unnecessarily. In addition, if this code wasn't there invocations
+		// with only special-cased target names like "m bp2build" would result in
+		// passing Ninja the empty target list and it would then build the default
+		// targets which is not what the user asked for.
+		what = what &^ RunNinja
+		what = what &^ RunKati
+	}
+
 	if config.StartGoma() {
 		startGoma(ctx, config)
 	}
@@ -278,16 +288,6 @@
 
 	if what&RunSoong != 0 {
 		runSoong(ctx, config)
-
-		if config.bazelBuildMode() == generateBuildFiles {
-			// Return early, if we're using Soong as solely the generator of BUILD files.
-			return
-		}
-
-		if config.bazelBuildMode() == generateJsonModuleGraph {
-			// Return early, if we're using Soong as solely the generator of the JSON module graph
-			return
-		}
 	}
 
 	if what&RunKati != 0 {
diff --git a/ui/build/config.go b/ui/build/config.go
index 6de7a05..2cd7d55 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -33,7 +33,8 @@
 type Config struct{ *configImpl }
 
 type configImpl struct {
-	// From the environment
+	// Some targets that are implemented in soong_build
+	// (bp2build, json-module-graph) are not here and have their own bits below.
 	arguments     []string
 	goma          bool
 	environ       *Environment
@@ -41,17 +42,20 @@
 	buildDateTime string
 
 	// From the arguments
-	parallel       int
-	keepGoing      int
-	verbose        bool
-	checkbuild     bool
-	dist           bool
-	skipConfig     bool
-	skipKati       bool
-	skipKatiNinja  bool
-	skipSoong      bool
-	skipNinja      bool
-	skipSoongTests bool
+	parallel        int
+	keepGoing       int
+	verbose         bool
+	checkbuild      bool
+	dist            bool
+	jsonModuleGraph bool
+	bp2build        bool
+	queryview       bool
+	skipConfig      bool
+	skipKati        bool
+	skipKatiNinja   bool
+	skipSoong       bool
+	skipNinja       bool
+	skipSoongTests  bool
 
 	// From the product config
 	katiArgs        []string
@@ -109,9 +113,6 @@
 	// Only generate build files (in a subdirectory of the out directory) and exit.
 	generateBuildFiles
 
-	// Only generate the Soong json module graph for use with jq, and exit.
-	generateJsonModuleGraph
-
 	// Generate synthetic build files and incorporate these files into a build which
 	// partially uses Bazel. Build metadata may come from Android.bp or BUILD files.
 	mixedBuild
@@ -639,6 +640,12 @@
 			c.environ.Set(k, v)
 		} else if arg == "dist" {
 			c.dist = true
+		} else if arg == "json-module-graph" {
+			c.jsonModuleGraph = true
+		} else if arg == "bp2build" {
+			c.bp2build = true
+		} else if arg == "queryview" {
+			c.queryview = true
 		} else {
 			if arg == "checkbuild" {
 				c.checkbuild = true
@@ -705,6 +712,26 @@
 	return c.arguments
 }
 
+func (c *configImpl) SoongBuildInvocationNeeded() bool {
+	if c.Dist() {
+		return true
+	}
+
+	if len(c.Arguments()) > 0 {
+		// Explicit targets requested that are not special targets like b2pbuild
+		// or the JSON module graph
+		return true
+	}
+
+	if !c.JsonModuleGraph() && !c.Bp2Build() && !c.Queryview() {
+		// Command line was empty, the default Ninja target is built
+		return true
+	}
+
+	// build.ninja doesn't need to be generated
+	return false
+}
+
 func (c *configImpl) OutDir() string {
 	if outDir, ok := c.environ.Get("OUT_DIR"); ok {
 		return outDir
@@ -761,6 +788,10 @@
 	return shared.JoinPath(c.SoongOutDir(), ".bootstrap/bp2build_workspace_marker")
 }
 
+func (c *configImpl) QueryviewMarkerFile() string {
+	return shared.JoinPath(c.SoongOutDir(), "queryview.marker")
+}
+
 func (c *configImpl) ModuleGraphFile() string {
 	return shared.JoinPath(c.SoongOutDir(), "module-graph.json")
 }
@@ -790,6 +821,18 @@
 	return c.dist
 }
 
+func (c *configImpl) JsonModuleGraph() bool {
+	return c.jsonModuleGraph
+}
+
+func (c *configImpl) Bp2Build() bool {
+	return c.bp2build
+}
+
+func (c *configImpl) Queryview() bool {
+	return c.queryview
+}
+
 func (c *configImpl) IsVerbose() bool {
 	return c.verbose
 }
@@ -935,10 +978,6 @@
 func (c *configImpl) bazelBuildMode() bazelBuildMode {
 	if c.Environment().IsEnvTrue("USE_BAZEL_ANALYSIS") {
 		return mixedBuild
-	} else if c.Environment().IsEnvTrue("GENERATE_BAZEL_FILES") {
-		return generateBuildFiles
-	} else if c.Environment().IsEnvTrue("GENERATE_JSON_MODULE_GRAPH") {
-		return generateJsonModuleGraph
 	} else {
 		return noBazel
 	}
diff --git a/ui/build/finder.go b/ui/build/finder.go
index 09d53cc..8f74969 100644
--- a/ui/build/finder.go
+++ b/ui/build/finder.go
@@ -15,15 +15,16 @@
 package build
 
 import (
-	"android/soong/finder"
-	"android/soong/finder/fs"
-	"android/soong/ui/logger"
 	"bytes"
 	"io/ioutil"
 	"os"
 	"path/filepath"
 	"strings"
 
+	"android/soong/finder"
+	"android/soong/finder/fs"
+	"android/soong/ui/logger"
+
 	"android/soong/ui/metrics"
 )
 
@@ -72,8 +73,6 @@
 			"AndroidProducts.mk",
 			// General Soong build definitions, using the Blueprint syntax.
 			"Android.bp",
-			// build/blueprint build definitions, using the Blueprint syntax.
-			"Blueprints",
 			// Bazel build definitions.
 			"BUILD.bazel",
 			// Bazel build definitions.
@@ -165,8 +164,6 @@
 
 	// Recursively look for all Android.bp files
 	androidBps := f.FindNamedAt(".", "Android.bp")
-	// The files are named "Blueprints" only in the build/blueprint directory.
-	androidBps = append(androidBps, f.FindNamedAt("build/blueprint", "Blueprints")...)
 	if len(androidBps) == 0 {
 		ctx.Fatalf("No Android.bp found")
 	}
diff --git a/ui/build/soong.go b/ui/build/soong.go
index a627dae..04d106b 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -71,10 +71,14 @@
 // A tiny struct used to tell Blueprint that it's in bootstrap mode. It would
 // probably be nicer to use a flag in bootstrap.Args instead.
 type BlueprintConfig struct {
-	toolDir          string
-	soongOutDir      string
-	outDir           string
-	debugCompilation bool
+	toolDir                   string
+	soongOutDir               string
+	outDir                    string
+	runGoTests                bool
+	useValidations            bool
+	debugCompilation          bool
+	subninjas                 []string
+	primaryBuilderInvocations []bootstrap.PrimaryBuilderInvocation
 }
 
 func (c BlueprintConfig) HostToolDir() string {
@@ -89,10 +93,26 @@
 	return c.outDir
 }
 
+func (c BlueprintConfig) RunGoTests() bool {
+	return c.runGoTests
+}
+
+func (c BlueprintConfig) UseValidationsForGoTests() bool {
+	return c.useValidations
+}
+
 func (c BlueprintConfig) DebugCompilation() bool {
 	return c.debugCompilation
 }
 
+func (c BlueprintConfig) Subninjas() []string {
+	return c.subninjas
+}
+
+func (c BlueprintConfig) PrimaryBuilderInvocations() []bootstrap.PrimaryBuilderInvocation {
+	return c.primaryBuilderInvocations
+}
+
 func environmentArgs(config Config, suffix string) []string {
 	return []string{
 		"--available_env", shared.JoinPath(config.SoongOutDir(), availableEnvFile),
@@ -122,6 +142,7 @@
 
 	bootstrapGlobFile := shared.JoinPath(config.SoongOutDir(), ".bootstrap/build-globs.ninja")
 	bp2buildGlobFile := shared.JoinPath(config.SoongOutDir(), ".bootstrap/build-globs.bp2build.ninja")
+	queryviewGlobFile := shared.JoinPath(config.SoongOutDir(), ".bootstrap/build-globs.queryview.ninja")
 	moduleGraphGlobFile := shared.JoinPath(config.SoongOutDir(), ".bootstrap/build-globs.modulegraph.ninja")
 
 	// The glob .ninja files are subninja'd. However, they are generated during
@@ -129,6 +150,9 @@
 	// fail on clean builds
 	writeEmptyGlobFile(ctx, bootstrapGlobFile)
 	writeEmptyGlobFile(ctx, bp2buildGlobFile)
+	writeEmptyGlobFile(ctx, queryviewGlobFile)
+	writeEmptyGlobFile(ctx, moduleGraphGlobFile)
+
 	bootstrapDepFile := shared.JoinPath(config.SoongOutDir(), ".bootstrap/build.ninja.d")
 
 	args.RunGoTests = !config.skipSoongTests
@@ -140,7 +164,7 @@
 	// The primary builder (aka soong_build) will use bootstrapGlobFile as the globFile to generate build.ninja(.d)
 	// Building soong_build does not require a glob file
 	// Using "" instead of "<soong_build_glob>.ninja" will ensure that an unused glob file is not written to out/soong/.bootstrap during StagePrimary
-	args.Subninjas = []string{bootstrapGlobFile, bp2buildGlobFile}
+	args.Subninjas = []string{bootstrapGlobFile, bp2buildGlobFile, moduleGraphGlobFile, queryviewGlobFile}
 	args.EmptyNinjaFile = config.EmptyNinjaFile()
 
 	args.DelveListen = os.Getenv("SOONG_DELVE")
@@ -186,6 +210,22 @@
 		Args:    bp2buildArgs,
 	}
 
+	queryviewArgs := []string{
+		"--bazel_queryview_dir", filepath.Join(config.SoongOutDir(), "queryview"),
+		"--globListDir", "queryview",
+		"--globFile", queryviewGlobFile,
+	}
+
+	queryviewArgs = append(queryviewArgs, commonArgs...)
+	queryviewArgs = append(queryviewArgs, environmentArgs(config, ".queryview")...)
+	queryviewArgs = append(queryviewArgs, "Android.bp")
+
+	queryviewInvocation := bootstrap.PrimaryBuilderInvocation{
+		Inputs:  []string{"Android.bp"},
+		Outputs: []string{config.QueryviewMarkerFile()},
+		Args:    queryviewArgs,
+	}
+
 	moduleGraphArgs := []string{
 		"--module_graph_file", config.ModuleGraphFile(),
 		"--globListDir", "modulegraph",
@@ -206,15 +246,20 @@
 		bp2buildInvocation,
 		mainSoongBuildInvocation,
 		moduleGraphInvocation,
+		queryviewInvocation,
 	}
 
 	blueprintCtx := blueprint.NewContext()
 	blueprintCtx.SetIgnoreUnknownModuleTypes(true)
 	blueprintConfig := BlueprintConfig{
-		soongOutDir:      config.SoongOutDir(),
-		toolDir:          config.HostToolDir(),
-		outDir:           config.OutDir(),
-		debugCompilation: os.Getenv("SOONG_DELVE") != "",
+		soongOutDir:               config.SoongOutDir(),
+		toolDir:                   config.HostToolDir(),
+		outDir:                    config.OutDir(),
+		runGoTests:                !config.skipSoongTests,
+		useValidations:            true,
+		debugCompilation:          os.Getenv("SOONG_DELVE") != "",
+		subninjas:                 args.Subninjas,
+		primaryBuilderInvocations: args.PrimaryBuilderInvocations,
 	}
 
 	args.EmptyNinjaFile = false
@@ -251,7 +296,7 @@
 	}
 
 	buildMode := config.bazelBuildMode()
-	integratedBp2Build := (buildMode == mixedBuild) || (buildMode == generateBuildFiles)
+	integratedBp2Build := buildMode == mixedBuild
 
 	// This is done unconditionally, but does not take a measurable amount of time
 	bootstrapBlueprint(ctx, config)
@@ -327,18 +372,26 @@
 		cmd.RunAndStreamOrFatal()
 	}
 
-	var target string
+	targets := make([]string, 0, 0)
 
-	if config.bazelBuildMode() == generateBuildFiles {
-		target = config.Bp2BuildMarkerFile()
-	} else if config.bazelBuildMode() == generateJsonModuleGraph {
-		target = config.ModuleGraphFile()
-	} else {
-		// This build generates <builddir>/build.ninja, which is used later by build/soong/ui/build/build.go#Build().
-		target = config.MainNinjaFile()
+	if config.JsonModuleGraph() {
+		targets = append(targets, config.ModuleGraphFile())
 	}
 
-	ninja("bootstrap", ".bootstrap/build.ninja", target)
+	if config.Bp2Build() {
+		targets = append(targets, config.Bp2BuildMarkerFile())
+	}
+
+	if config.Queryview() {
+		targets = append(targets, config.QueryviewMarkerFile())
+	}
+
+	if config.SoongBuildInvocationNeeded() {
+		// This build generates <builddir>/build.ninja, which is used later by build/soong/ui/build/build.go#Build().
+		targets = append(targets, config.MainNinjaFile())
+	}
+
+	ninja("bootstrap", ".bootstrap/build.ninja", targets...)
 
 	var soongBuildMetrics *soong_metrics_proto.SoongBuildMetrics
 	if shouldCollectBuildSoongMetrics(config) {
@@ -380,7 +433,7 @@
 func shouldCollectBuildSoongMetrics(config Config) bool {
 	// Do not collect metrics protobuf if the soong_build binary ran as the
 	// bp2build converter or the JSON graph dump.
-	return config.bazelBuildMode() != generateBuildFiles && config.bazelBuildMode() != generateJsonModuleGraph
+	return config.SoongBuildInvocationNeeded()
 }
 
 func loadSoongBuildMetrics(ctx Context, config Config) *soong_metrics_proto.SoongBuildMetrics {