Merge "Add sortableComponent abstraction"
diff --git a/android/env.go b/android/env.go
index 58ad0b6..289d803 100644
--- a/android/env.go
+++ b/android/env.go
@@ -15,11 +15,6 @@
 package android
 
 import (
-	"fmt"
-	"os"
-	"strings"
-	"syscall"
-
 	"android/soong/shared"
 )
 
@@ -31,9 +26,6 @@
 // a manifest regeneration.
 
 var originalEnv map[string]string
-var soongDelveListen string
-var soongDelvePath string
-var isDebugging bool
 
 func InitEnvironment(envFile string) {
 	var err error
@@ -41,51 +33,6 @@
 	if err != nil {
 		panic(err)
 	}
-
-	soongDelveListen = originalEnv["SOONG_DELVE"]
-	soongDelvePath = originalEnv["SOONG_DELVE_PATH"]
-}
-
-// Returns whether the current process is running under Delve due to
-// ReexecWithDelveMaybe().
-func IsDebugging() bool {
-	return isDebugging
-}
-func ReexecWithDelveMaybe() {
-	isDebugging = os.Getenv("SOONG_DELVE_REEXECUTED") == "true"
-	if isDebugging || soongDelveListen == "" {
-		return
-	}
-
-	if soongDelvePath == "" {
-		fmt.Fprintln(os.Stderr, "SOONG_DELVE is set but failed to find dlv")
-		os.Exit(1)
-	}
-
-	soongDelveEnv := []string{}
-	for _, env := range os.Environ() {
-		idx := strings.IndexRune(env, '=')
-		if idx != -1 {
-			soongDelveEnv = append(soongDelveEnv, env)
-		}
-	}
-
-	soongDelveEnv = append(soongDelveEnv, "SOONG_DELVE_REEXECUTED=true")
-
-	dlvArgv := []string{
-		soongDelvePath,
-		"--listen=:" + soongDelveListen,
-		"--headless=true",
-		"--api-version=2",
-		"exec",
-		os.Args[0],
-		"--",
-	}
-	dlvArgv = append(dlvArgv, os.Args[1:]...)
-	os.Chdir(absSrcDir)
-	syscall.Exec(soongDelvePath, dlvArgv, soongDelveEnv)
-	fmt.Fprintln(os.Stderr, "exec() failed while trying to reexec with Delve")
-	os.Exit(1)
 }
 
 func EnvSingleton() Singleton {
diff --git a/android/queryview.go b/android/queryview.go
index 9e3e45a..b940202 100644
--- a/android/queryview.go
+++ b/android/queryview.go
@@ -67,10 +67,14 @@
 		blueprint.RuleParams{
 			Command: fmt.Sprintf(
 				"rm -rf ${outDir}/* && "+
-					"%s --bazel_queryview_dir ${outDir} %s && "+
+					"BUILDER=\"%s\" && "+
+					"cd $$(dirname \"$$BUILDER\") && "+
+					"ABSBUILDER=\"$$PWD/$$(basename \"$$BUILDER\")\" && "+
+					"cd / && "+
+					"env -i \"$$ABSBUILDER\" --bazel_queryview_dir ${outDir} \"%s\" && "+
 					"echo WORKSPACE: `cat %s` > ${outDir}/.queryview-depfile.d",
 				primaryBuilder.String(),
-				strings.Join(os.Args[1:], " "),
+				strings.Join(os.Args[1:], "\" \""),
 				moduleListFilePath.String(), // Use the contents of Android.bp.list as the depfile.
 			),
 			CommandDeps: []string{primaryBuilder.String()},
diff --git a/android/writedocs.go b/android/writedocs.go
index 6417690..6cb2f10 100644
--- a/android/writedocs.go
+++ b/android/writedocs.go
@@ -66,7 +66,9 @@
 	soongDocs := ctx.Rule(pctx, "soongDocs",
 		blueprint.RuleParams{
 			Command: fmt.Sprintf("rm -f ${outDir}/* && %s --soong_docs %s %s",
-				primaryBuilder.String(), docsFile.String(), strings.Join(os.Args[1:], " ")),
+				primaryBuilder.String(),
+				docsFile.String(),
+				"\""+strings.Join(os.Args[1:], "\" \"")+"\""),
 			CommandDeps: []string{primaryBuilder.String()},
 			Description: fmt.Sprintf("%s docs $out", primaryBuilder.Base()),
 		},
diff --git a/apex/allowed_deps.txt b/apex/allowed_deps.txt
index 476ac4a..047a0f3 100644
--- a/apex/allowed_deps.txt
+++ b/apex/allowed_deps.txt
@@ -192,7 +192,7 @@
 GoogleCellBroadcastApp(minSdkVersion:29)
 GoogleCellBroadcastServiceModule(minSdkVersion:29)
 GoogleExtServices(minSdkVersion:current)
-GooglePermissionController(minSdkVersion:28)
+GooglePermissionController(minSdkVersion:30)
 guava(minSdkVersion:current)
 gwp_asan_headers(minSdkVersion:(no version))
 i18n.module.public.api.stubs(minSdkVersion:(no version))
@@ -527,7 +527,7 @@
 no_op(minSdkVersion:current)
 note_memtag_heap_async(minSdkVersion:16)
 note_memtag_heap_sync(minSdkVersion:16)
-PermissionController(minSdkVersion:28)
+PermissionController(minSdkVersion:30)
 permissioncontroller-statsd(minSdkVersion:current)
 philox_random(minSdkVersion:(no version))
 philox_random_headers(minSdkVersion:(no version))
diff --git a/apex/apex_test.go b/apex/apex_test.go
index e3b7f95..991f5c9 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -67,14 +67,14 @@
 	t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
 }
 
-func testApex(t *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) {
+func testApex(t *testing.T, bp string, handlers ...testCustomizer) *android.TestContext {
 	t.Helper()
 	ctx, config := testApexContext(t, bp, handlers...)
 	_, errs := ctx.ParseBlueprintsFiles(".")
 	android.FailIfErrored(t, errs)
 	_, errs = ctx.PrepareBuildActions(config)
 	android.FailIfErrored(t, errs)
-	return ctx, config
+	return ctx
 }
 
 type testCustomizer func(fs map[string][]byte, config android.Config)
@@ -360,7 +360,7 @@
 
 // Minimal test
 func TestBasicApex(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex_defaults {
 			name: "myapex-defaults",
 			manifest: ":myapex.manifest",
@@ -666,7 +666,7 @@
 }
 
 func TestDefaults(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex_defaults {
 			name: "myapex-defaults",
 			key: "myapex.key",
@@ -741,7 +741,7 @@
 }
 
 func TestApexManifest(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -763,7 +763,7 @@
 }
 
 func TestBasicZipApex(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -814,7 +814,7 @@
 }
 
 func TestApexWithStubs(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -909,7 +909,7 @@
 
 func TestApexWithStubsWithMinSdkVersion(t *testing.T) {
 	t.Parallel()
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -1016,7 +1016,7 @@
 	//                                  |
 	//   <platform>                     |
 	//      libplatform ----------------'
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -1081,7 +1081,7 @@
 }
 
 func TestApexWithExplicitStubsDependency(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex2",
 			key: "myapex2.key",
@@ -1177,7 +1177,7 @@
 			    |
 			    `------> libbar
 	*/
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -1239,7 +1239,7 @@
 }
 
 func TestRuntimeApexShouldInstallHwasanIfLibcDependsOnIt(t *testing.T) {
-	ctx, _ := testApex(t, "", func(fs map[string][]byte, config android.Config) {
+	ctx := testApex(t, "", func(fs map[string][]byte, config android.Config) {
 		bp := `
 		apex {
 			name: "com.android.runtime",
@@ -1303,7 +1303,7 @@
 }
 
 func TestRuntimeApexShouldInstallHwasanIfHwaddressSanitized(t *testing.T) {
-	ctx, _ := testApex(t, "", func(fs map[string][]byte, config android.Config) {
+	ctx := testApex(t, "", func(fs map[string][]byte, config android.Config) {
 		bp := `
 		apex {
 			name: "com.android.runtime",
@@ -1389,7 +1389,7 @@
 	}
 	for _, tc := range testcases {
 		t.Run(tc.name, func(t *testing.T) {
-			ctx, _ := testApex(t, `
+			ctx := testApex(t, `
 			apex {
 				name: "myapex",
 				key: "myapex.key",
@@ -1456,7 +1456,7 @@
 }
 
 func TestApexWithSystemLibsStubs(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -1552,7 +1552,7 @@
 	// 1) myapex -> libx -> liba -> libz    : this should be #30 link
 	// 2) otherapex -> liby -> liba -> libz : this should be #30 link
 	// 3) (platform) -> liba -> libz        : this should be non-stub link
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -1634,7 +1634,7 @@
 }
 
 func TestApexMinSdkVersion_SupportsCodeNames(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -1683,7 +1683,7 @@
 }
 
 func TestApexMinSdkVersion_DefaultsToLatest(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -1729,7 +1729,7 @@
 }
 
 func TestPlatformUsesLatestStubsFromApexes(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -1777,7 +1777,7 @@
 }
 
 func TestQApexesUseLatestStubsInBundledBuildsAndHWASAN(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -1816,7 +1816,7 @@
 }
 
 func TestQTargetApexUsesStaticUnwinder(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -2143,7 +2143,7 @@
 }
 
 func TestApexMinSdkVersion_OkayEvenWhenDepIsNewer_IfItSatisfiesApexMinSdkVersion(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -2230,7 +2230,7 @@
 		config.TestProductVariables.Platform_sdk_codename = proptools.StringPtr("S")
 		config.TestProductVariables.Platform_version_active_codenames = []string{"S", "T"}
 	}
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -2264,7 +2264,7 @@
 }
 
 func TestFilesInSubDir(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -2327,7 +2327,7 @@
 }
 
 func TestFilesInSubDirWhenNativeBridgeEnabled(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -2386,7 +2386,7 @@
 }
 
 func TestUseVendor(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -2499,7 +2499,7 @@
 }
 
 func TestVendorApex(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -2546,7 +2546,7 @@
 }
 
 func TestVendorApex_use_vndk_as_stable(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -2610,7 +2610,7 @@
 	}
 	for _, tc := range testCases {
 		t.Run(tc.name, func(t *testing.T) {
-			ctx, _ := testApex(t, `
+			ctx := testApex(t, `
 				apex {
 					name: "myapex",
 					key: "myapex.key",
@@ -2638,7 +2638,7 @@
 }
 
 func TestAndroidMk_UseVendorRequired(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -2673,7 +2673,7 @@
 }
 
 func TestAndroidMk_VendorApexRequired(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -2705,7 +2705,7 @@
 }
 
 func TestAndroidMkWritesCommonProperties(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -2735,7 +2735,7 @@
 }
 
 func TestStaticLinking(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -2780,7 +2780,7 @@
 }
 
 func TestKeys(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex_keytest",
 			key: "myapex.key",
@@ -2838,7 +2838,7 @@
 
 func TestCertificate(t *testing.T) {
 	t.Run("if unspecified, it defaults to DefaultAppCertificate", func(t *testing.T) {
-		ctx, _ := testApex(t, `
+		ctx := testApex(t, `
 			apex {
 				name: "myapex",
 				key: "myapex.key",
@@ -2856,7 +2856,7 @@
 		}
 	})
 	t.Run("override when unspecified", func(t *testing.T) {
-		ctx, _ := testApex(t, `
+		ctx := testApex(t, `
 			apex {
 				name: "myapex_keytest",
 				key: "myapex.key",
@@ -2879,7 +2879,7 @@
 		}
 	})
 	t.Run("if specified as :module, it respects the prop", func(t *testing.T) {
-		ctx, _ := testApex(t, `
+		ctx := testApex(t, `
 			apex {
 				name: "myapex",
 				key: "myapex.key",
@@ -2902,7 +2902,7 @@
 		}
 	})
 	t.Run("override when specifiec as <:module>", func(t *testing.T) {
-		ctx, _ := testApex(t, `
+		ctx := testApex(t, `
 			apex {
 				name: "myapex_keytest",
 				key: "myapex.key",
@@ -2926,7 +2926,7 @@
 		}
 	})
 	t.Run("if specified as name, finds it from DefaultDevKeyDir", func(t *testing.T) {
-		ctx, _ := testApex(t, `
+		ctx := testApex(t, `
 			apex {
 				name: "myapex",
 				key: "myapex.key",
@@ -2945,7 +2945,7 @@
 		}
 	})
 	t.Run("override when specified as <name>", func(t *testing.T) {
-		ctx, _ := testApex(t, `
+		ctx := testApex(t, `
 			apex {
 				name: "myapex_keytest",
 				key: "myapex.key",
@@ -2971,7 +2971,7 @@
 }
 
 func TestMacro(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -3099,7 +3099,7 @@
 }
 
 func TestHeaderLibsDependency(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -3243,7 +3243,7 @@
 }
 
 func TestVndkApexCurrent(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex_vndk {
 			name: "com.android.vndk.current",
 			key: "com.android.vndk.current.key",
@@ -3300,7 +3300,7 @@
 }
 
 func TestVndkApexWithPrebuilt(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex_vndk {
 			name: "com.android.vndk.current",
 			key: "com.android.vndk.current.key",
@@ -3384,7 +3384,7 @@
 }
 
 func TestVndkApexVersion(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex_vndk {
 			name: "com.android.vndk.v27",
 			key: "myapex.key",
@@ -3453,7 +3453,7 @@
 }
 
 func TestVndkApexNameRule(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex_vndk {
 			name: "com.android.vndk.current",
 			key: "myapex.key",
@@ -3486,7 +3486,7 @@
 }
 
 func TestVndkApexSkipsNativeBridgeSupportedModules(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex_vndk {
 			name: "com.android.vndk.current",
 			key: "com.android.vndk.current.key",
@@ -3558,7 +3558,7 @@
 }
 
 func TestVndkApexWithBinder32(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex_vndk {
 			name: "com.android.vndk.v27",
 			key: "myapex.key",
@@ -3627,7 +3627,7 @@
 }
 
 func TestVndkApexShouldNotProvideNativeLibs(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex_vndk {
 			name: "com.android.vndk.current",
 			key: "com.android.vndk.current.key",
@@ -3663,7 +3663,7 @@
 }
 
 func TestDependenciesInApexManifest(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex_nodep",
 			key: "myapex.key",
@@ -3771,7 +3771,7 @@
 }
 
 func TestApexName(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -3816,7 +3816,7 @@
 }
 
 func TestNonTestApex(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -3869,7 +3869,7 @@
 }
 
 func TestTestApex(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex_test {
 			name: "myapex",
 			key: "myapex.key",
@@ -3918,7 +3918,7 @@
 }
 
 func TestApexWithTarget(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -4009,7 +4009,7 @@
 }
 
 func TestApexWithArch(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -4068,7 +4068,7 @@
 }
 
 func TestApexWithShBinary(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -4109,7 +4109,7 @@
 	}
 	for _, tc := range testcases {
 		t.Run(tc.propName+":"+tc.parition, func(t *testing.T) {
-			ctx, _ := testApex(t, `
+			ctx := testApex(t, `
 				apex {
 					name: "myapex",
 					key: "myapex.key",
@@ -4142,7 +4142,7 @@
 }
 
 func TestFileContexts_FindInDefaultLocationIfNotSet(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -4196,7 +4196,7 @@
 		}
 	`)
 
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -4219,7 +4219,7 @@
 }
 
 func TestFileContexts_SetViaFileGroup(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -4247,7 +4247,7 @@
 }
 
 func TestApexKeyFromOtherModule(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex_key {
 			name: "myapex.key",
 			public_key: ":my.avbpubkey",
@@ -4280,7 +4280,7 @@
 }
 
 func TestPrebuilt(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		prebuilt_apex {
 			name: "myapex",
 			arch: {
@@ -4303,7 +4303,7 @@
 }
 
 func TestPrebuiltFilenameOverride(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		prebuilt_apex {
 			name: "myapex",
 			src: "myapex-arm.apex",
@@ -4320,7 +4320,7 @@
 }
 
 func TestPrebuiltOverrides(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		prebuilt_apex {
 			name: "myapex.prebuilt",
 			src: "myapex-arm.apex",
@@ -4831,7 +4831,7 @@
 }
 
 func TestApexWithTests(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex_test {
 			name: "myapex",
 			key: "myapex.key",
@@ -4943,7 +4943,7 @@
 }
 
 func TestInstallExtraFlattenedApexes(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -5013,7 +5013,7 @@
 }
 
 func TestApexWithJavaImport(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -5042,7 +5042,7 @@
 }
 
 func TestApexWithApps(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -5121,7 +5121,7 @@
 }
 
 func TestApexWithAppImports(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -5170,7 +5170,7 @@
 }
 
 func TestApexWithAppImportsPrefer(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -5213,7 +5213,7 @@
 }
 
 func TestApexWithTestHelperApp(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -5424,7 +5424,7 @@
 }
 
 func TestApexAvailable_CheckForPlatform(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 	apex {
 		name: "myapex",
 		key: "myapex.key",
@@ -5487,7 +5487,7 @@
 }
 
 func TestApexAvailable_CreatedForApex(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 	apex {
 		name: "myapex",
 		key: "myapex.key",
@@ -5522,7 +5522,7 @@
 }
 
 func TestOverrideApex(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -5606,7 +5606,7 @@
 }
 
 func TestLegacyAndroid10Support(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -5666,7 +5666,7 @@
 }
 
 func TestJavaSDKLibrary(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -5704,7 +5704,7 @@
 }
 
 func TestJavaSDKLibrary_WithinApex(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -5757,7 +5757,7 @@
 }
 
 func TestJavaSDKLibrary_CrossBoundary(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -5808,7 +5808,7 @@
 }
 
 func TestJavaSDKLibrary_ImportPreferred(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		prebuilt_apis {
 			name: "sdk",
 			api_dirs: ["100"],
@@ -5925,7 +5925,7 @@
 }
 
 func TestCompatConfig(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -5986,7 +5986,7 @@
 }
 
 func TestCarryRequiredModuleNames(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -6130,7 +6130,7 @@
 
 	// For unbundled build, symlink shouldn't exist regardless of whether an APEX
 	// is updatable or not
-	ctx, _ := testApex(t, bp, withUnbundledBuild)
+	ctx := testApex(t, bp, withUnbundledBuild)
 	files := getFiles(t, ctx, "myapex", "android_common_myapex_image")
 	ensureRealfileExists(t, files, "javalib/myjar.jar")
 	ensureRealfileExists(t, files, "lib64/mylib.so")
@@ -6142,7 +6142,7 @@
 	ensureRealfileExists(t, files, "lib64/myotherlib.so")
 
 	// For bundled build, symlink to the system for the non-updatable APEXes only
-	ctx, _ = testApex(t, bp)
+	ctx = testApex(t, bp)
 	files = getFiles(t, ctx, "myapex", "android_common_myapex_image")
 	ensureRealfileExists(t, files, "javalib/myjar.jar")
 	ensureRealfileExists(t, files, "lib64/mylib.so")
@@ -6155,7 +6155,7 @@
 }
 
 func TestSymlinksFromApexToSystemRequiredModuleNames(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -6207,7 +6207,7 @@
 }
 
 func TestApexWithJniLibs(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -6249,7 +6249,7 @@
 }
 
 func TestApexMutatorsDontRunIfDisabled(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -6271,7 +6271,7 @@
 }
 
 func TestAppBundle(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -6302,7 +6302,7 @@
 }
 
 func TestAppSetBundle(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -6335,7 +6335,7 @@
 }
 
 func TestAppSetBundlePrebuilt(t *testing.T) {
-	ctx, _ := testApex(t, "", func(fs map[string][]byte, config android.Config) {
+	ctx := testApex(t, "", func(fs map[string][]byte, config android.Config) {
 		bp := `
 		apex_set {
 			name: "myapex",
@@ -6820,7 +6820,7 @@
 }
 
 func TestTestFor(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -6906,7 +6906,7 @@
 }
 
 func TestApexSet(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex_set {
 			name: "myapex",
 			set: "myapex.apks",
@@ -6982,7 +6982,7 @@
 }
 
 func TestApexKeysTxt(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -7023,7 +7023,7 @@
 }
 
 func TestAllowedFiles(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -7079,7 +7079,7 @@
 }
 
 func TestNonPreferredPrebuiltDependency(t *testing.T) {
-	_, _ = testApex(t, `
+	testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -7115,7 +7115,7 @@
 }
 
 func TestCompressedApex(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -7150,7 +7150,7 @@
 }
 
 func TestPreferredPrebuiltSharedLibDep(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -7202,7 +7202,7 @@
 }
 
 func TestExcludeDependency(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
@@ -7346,7 +7346,7 @@
 		t.Run(test.name, func(t *testing.T) {
 			for _, otherApexEnabled := range test.otherApexEnabled {
 				t.Run("otherapex_enabled_"+otherApexEnabled, func(t *testing.T) {
-					ctx, _ := testApex(t, fmt.Sprintf(bpBase, otherApexEnabled)+test.stublibBp)
+					ctx := testApex(t, fmt.Sprintf(bpBase, otherApexEnabled)+test.stublibBp)
 
 					type modAndMkEntries struct {
 						mod       *cc.Module
diff --git a/apex/boot_image_test.go b/apex/boot_image_test.go
index ff779e1..2e6ed82 100644
--- a/apex/boot_image_test.go
+++ b/apex/boot_image_test.go
@@ -28,7 +28,7 @@
 // modules from the ART apex.
 
 func TestBootImages(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		java_sdk_library {
 			name: "foo",
 			srcs: ["b.java"],
@@ -181,7 +181,7 @@
 }
 
 func TestBootImageInApex(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex {
 			name: "myapex",
 			key: "myapex.key",
diff --git a/apex/vndk_test.go b/apex/vndk_test.go
index 5e9a11f..34b9408 100644
--- a/apex/vndk_test.go
+++ b/apex/vndk_test.go
@@ -9,7 +9,7 @@
 )
 
 func TestVndkApexForVndkLite(t *testing.T) {
-	ctx, _ := testApex(t, `
+	ctx := testApex(t, `
 		apex_vndk {
 			name: "com.android.vndk.current",
 			key: "com.android.vndk.current.key",
@@ -100,7 +100,7 @@
 	}
 
 	t.Run("VNDK lib doesn't have an apex variant", func(t *testing.T) {
-		ctx, _ := testApex(t, bp)
+		ctx := testApex(t, bp)
 
 		// libfoo doesn't have apex variants
 		for _, variant := range ctx.ModuleVariantsForTests("libfoo") {
@@ -113,7 +113,7 @@
 	})
 
 	t.Run("VNDK APEX gathers only vendor variants even if product variants are available", func(t *testing.T) {
-		ctx, _ := testApex(t, bp, func(fs map[string][]byte, config android.Config) {
+		ctx := testApex(t, bp, func(fs map[string][]byte, config android.Config) {
 			// Now product variant is available
 			config.TestProductVariables.ProductVndkVersion = proptools.StringPtr("current")
 		})
@@ -123,7 +123,7 @@
 	})
 
 	t.Run("VNDK APEX supports coverage variants", func(t *testing.T) {
-		ctx, _ := testApex(t, bp, func(fs map[string][]byte, config android.Config) {
+		ctx := testApex(t, bp, func(fs map[string][]byte, config android.Config) {
 			config.TestProductVariables.GcovCoverage = proptools.BoolPtr(true)
 			config.TestProductVariables.Native_coverage = proptools.BoolPtr(true)
 		})
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index e7f995f..d022f49 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -33,11 +33,15 @@
 	outDir            string
 	docFile           string
 	bazelQueryViewDir string
+	delveListen       string
+	delvePath         string
 )
 
 func init() {
 	flag.StringVar(&topDir, "top", "", "Top directory of the Android source tree")
 	flag.StringVar(&outDir, "out", "", "Soong output directory (usually $TOP/out/soong)")
+	flag.StringVar(&delveListen, "delve_listen", "", "Delve port to listen on for debugging")
+	flag.StringVar(&delvePath, "delve_path", "", "Path to Delve. Only used if --delve_listen is set")
 	flag.StringVar(&docFile, "soong_docs", "", "build documentation file to output")
 	flag.StringVar(&bazelQueryViewDir, "bazel_queryview_dir", "", "path to the bazel queryview directory")
 }
@@ -87,9 +91,9 @@
 func main() {
 	flag.Parse()
 
+	shared.ReexecWithDelveMaybe(delveListen, delvePath)
 	android.InitSandbox(topDir)
 	android.InitEnvironment(shared.JoinPath(topDir, outDir, "soong.environment.available"))
-	android.ReexecWithDelveMaybe()
 
 	// The top-level Blueprints file is passed as the first argument.
 	srcDir := filepath.Dir(flag.Arg(0))
@@ -101,9 +105,7 @@
 	// user sets SOONG_DELVE the first time.
 	configuration.Getenv("SOONG_DELVE")
 	configuration.Getenv("SOONG_DELVE_PATH")
-	// Read the SOONG_DELVE again through configuration so that there is a dependency on the environment variable
-	// and soong_build will rerun when it is set for the first time.
-	if listen := configuration.Getenv("SOONG_DELVE"); listen != "" {
+	if shared.IsDebugging() {
 		// Add a non-existent file to the dependencies so that soong_build will rerun when the debugger is
 		// enabled even if it completed successfully.
 		extraNinjaDeps = append(extraNinjaDeps, filepath.Join(configuration.BuildDir(), "always_rerun_for_delve"))
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index 74ede68..1c5e78a 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -25,6 +25,7 @@
 	"strings"
 	"time"
 
+	"android/soong/shared"
 	"android/soong/ui/build"
 	"android/soong/ui/logger"
 	"android/soong/ui/metrics"
@@ -118,6 +119,8 @@
 // Command is the type of soong_ui execution. Only one type of
 // execution is specified. The args are specific to the command.
 func main() {
+	shared.ReexecWithDelveMaybe(os.Getenv("SOONG_UI_DELVE"), shared.ResolveDelveBinary())
+
 	buildStarted := time.Now()
 
 	c, args, err := getCommand(os.Args)
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 737773f..fdb00bd 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -288,12 +288,9 @@
 
 	} else {
 		// Other libraries or APKs for which the exact <uses-library> list is unknown.
-		// Pass special class loader context to skip the classpath and collision check.
-		// This will get removed once LOCAL_USES_LIBRARIES is enforced.
-		// Right now LOCAL_USES_LIBRARIES is opt in, for the case where it's not specified we still default
-		// to the &.
+		// We assume the class loader context is empty.
 		rule.Command().
-			Text(`class_loader_context_arg=--class-loader-context=\&`).
+			Text(`class_loader_context_arg=--class-loader-context=PCL[]`).
 			Text(`stored_class_loader_context_arg=""`)
 	}
 
diff --git a/java/robolectric.go b/java/robolectric.go
index 98bb710..00f233e 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -31,13 +31,15 @@
 }
 
 var robolectricDefaultLibs = []string{
-	"Robolectric_all-target",
 	"mockito-robolectric-prebuilt",
 	"truth-prebuilt",
 	// TODO(ccross): this is not needed at link time
 	"junitxml",
 }
 
+const robolectricCurrentLib = "Robolectric_all-target"
+const robolectricPrebuiltLibPattern = "platform-robolectric-%s-prebuilt"
+
 var (
 	roboCoverageLibsTag = dependencyTag{name: "roboCoverageLibs"}
 	roboRuntimesTag     = dependencyTag{name: "roboRuntimes"}
@@ -57,6 +59,10 @@
 		// Number of shards to use when running the tests.
 		Shards *int64
 	}
+
+	// The version number of a robolectric prebuilt to use from prebuilts/misc/common/robolectric
+	// instead of the one built from source in external/robolectric-shadows.
+	Robolectric_prebuilt_version *string
 }
 
 type robolectricTest struct {
@@ -94,6 +100,12 @@
 		ctx.PropertyErrorf("instrumentation_for", "missing required instrumented module")
 	}
 
+	if v := String(r.robolectricProperties.Robolectric_prebuilt_version); v != "" {
+		ctx.AddVariationDependencies(nil, libTag, fmt.Sprintf(robolectricPrebuiltLibPattern, v))
+	} else {
+		ctx.AddVariationDependencies(nil, libTag, robolectricCurrentLib)
+	}
+
 	ctx.AddVariationDependencies(nil, libTag, robolectricDefaultLibs...)
 
 	ctx.AddVariationDependencies(nil, roboCoverageLibsTag, r.robolectricProperties.Coverage_libs...)
@@ -298,7 +310,11 @@
 	if t := r.robolectricProperties.Test_options.Timeout; t != nil {
 		fmt.Fprintln(w, "LOCAL_ROBOTEST_TIMEOUT :=", *t)
 	}
-	fmt.Fprintln(w, "-include external/robolectric-shadows/run_robotests.mk")
+	if v := String(r.robolectricProperties.Robolectric_prebuilt_version); v != "" {
+		fmt.Fprintf(w, "-include prebuilts/misc/common/robolectric/%s/run_robotests.mk\n", v)
+	} else {
+		fmt.Fprintln(w, "-include external/robolectric-shadows/run_robotests.mk")
+	}
 }
 
 // An android_robolectric_test module compiles tests against the Robolectric framework that can run on the local host
diff --git a/shared/debug.go b/shared/debug.go
index 0c9ba4f..5392f2b 100644
--- a/shared/debug.go
+++ b/shared/debug.go
@@ -1,8 +1,15 @@
 package shared
 
 import (
+	"fmt"
 	"os"
 	"os/exec"
+	"strings"
+	"syscall"
+)
+
+var (
+	isDebugging bool
 )
 
 // Finds the Delve binary to use. Either uses the SOONG_DELVE_PATH environment
@@ -15,3 +22,48 @@
 
 	return result
 }
+
+// Returns whether the current process is running under Delve due to
+// ReexecWithDelveMaybe().
+func IsDebugging() bool {
+	return isDebugging
+}
+
+// Re-executes the binary in question under the control of Delve when
+// delveListen is not the empty string. delvePath gives the path to the Delve.
+func ReexecWithDelveMaybe(delveListen, delvePath string) {
+	isDebugging = os.Getenv("SOONG_DELVE_REEXECUTED") == "true"
+	if isDebugging || delveListen == "" {
+		return
+	}
+
+	if delvePath == "" {
+		fmt.Fprintln(os.Stderr, "Delve debugging requested but failed to find dlv")
+		os.Exit(1)
+	}
+
+	soongDelveEnv := []string{}
+	for _, env := range os.Environ() {
+		idx := strings.IndexRune(env, '=')
+		if idx != -1 {
+			soongDelveEnv = append(soongDelveEnv, env)
+		}
+	}
+
+	soongDelveEnv = append(soongDelveEnv, "SOONG_DELVE_REEXECUTED=true")
+
+	dlvArgv := []string{
+		delvePath,
+		"--listen=:" + delveListen,
+		"--headless=true",
+		"--api-version=2",
+		"exec",
+		os.Args[0],
+		"--",
+	}
+
+	dlvArgv = append(dlvArgv, os.Args[1:]...)
+	syscall.Exec(delvePath, dlvArgv, soongDelveEnv)
+	fmt.Fprintln(os.Stderr, "exec() failed while trying to reexec with Delve")
+	os.Exit(1)
+}
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 242282b..c2fa427 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -105,11 +105,6 @@
 	soongBuildEnv.Set("BAZEL_WORKSPACE", absPath(ctx, "."))
 	soongBuildEnv.Set("BAZEL_METRICS_DIR", config.BazelMetricsDir())
 
-	if os.Getenv("SOONG_DELVE") != "" {
-		// SOONG_DELVE is already in cmd.Environment
-		soongBuildEnv.Set("SOONG_DELVE_PATH", shared.ResolveDelveBinary())
-	}
-
 	err := writeEnvironmentFile(ctx, envFile, soongBuildEnv.AsMap())
 	if err != nil {
 		ctx.Fatalf("failed to write environment file %s: %s", envFile, err)
@@ -176,6 +171,11 @@
 			"-f", filepath.Join(config.SoongOutDir(), file))
 
 		cmd.Environment.Set("SOONG_OUTDIR", config.SoongOutDir())
+		if os.Getenv("SOONG_DELVE") != "" {
+			// SOONG_DELVE is already in cmd.Environment
+			cmd.Environment.Set("SOONG_DELVE_PATH", shared.ResolveDelveBinary())
+		}
+
 		cmd.Sandbox = soongSandbox
 		cmd.RunAndStreamOrFatal()
 	}