Merge "Revert $(LOCAL_PATH) handling for `certificate` and `additional_certificates` properties."
diff --git a/Android.bp b/Android.bp
index 10e6a2e..4d73049 100644
--- a/Android.bp
+++ b/Android.bp
@@ -55,7 +55,6 @@
         "android/namespace.go",
         "android/neverallow.go",
         "android/onceper.go",
-        "android/override_module.go",
         "android/package_ctx.go",
         "android/paths.go",
         "android/prebuilt.go",
@@ -376,6 +375,7 @@
         "soong-android",
         "soong-cc",
         "soong-java",
+        "soong-python",
     ],
     srcs: [
         "apex/apex.go",
diff --git a/android/config.go b/android/config.go
index 33986f7..24be10a 100644
--- a/android/config.go
+++ b/android/config.go
@@ -895,30 +895,16 @@
 }
 
 func (c *deviceConfig) OverrideManifestPackageNameFor(name string) (manifestName string, overridden bool) {
-	if newManifestName, overridden := c.manifestPackageNameOverrides().Load(name); overridden {
-		return newManifestName.(string), true
-	}
 	return findOverrideValue(c.config.productVariables.ManifestPackageNameOverrides, name,
 		"invalid override rule %q in PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES should be <module_name>:<manifest_name>")
 }
 
 func (c *deviceConfig) OverrideCertificateFor(name string) (certificatePath string, overridden bool) {
-	if newCert, overridden := c.certificateOverrides().Load(name); overridden {
-		return newCert.(string), true
-	}
-	newCert, overridden := findOverrideValue(c.config.productVariables.CertificateOverrides, name,
+	return findOverrideValue(c.config.productVariables.CertificateOverrides, name,
 		"invalid override rule %q in PRODUCT_CERTIFICATE_OVERRIDES should be <module_name>:<certificate_module_name>")
-	if overridden {
-		// PRODUCT_CERTIFICATE_OVERRIDES only supports cert modules.
-		newCert = ":" + newCert
-	}
-	return newCert, overridden
 }
 
 func (c *deviceConfig) OverridePackageNameFor(name string) string {
-	if newName, overridden := c.moduleNameOverrides().Load(name); overridden {
-		return newName.(string)
-	}
 	newName, overridden := findOverrideValue(
 		c.config.productVariables.PackageNameOverrides,
 		name,
diff --git a/android/module.go b/android/module.go
index f2f1af1..2fa7d31 100644
--- a/android/module.go
+++ b/android/module.go
@@ -154,6 +154,7 @@
 	// Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
 	VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
 	WalkDeps(visit func(Module, Module) bool)
+	WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool)
 
 	Variable(pctx PackageContext, name, value string)
 	Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
@@ -1067,6 +1068,10 @@
 		})
 }
 
+func (a *androidModuleContext) WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool) {
+	a.ModuleContext.WalkDeps(visit)
+}
+
 func (a *androidModuleContext) WalkDeps(visit func(Module, Module) bool) {
 	a.ModuleContext.WalkDeps(func(child, parent blueprint.Module) bool {
 		childAndroidModule := a.validateAndroidModule(child)
diff --git a/android/override_module.go b/android/override_module.go
deleted file mode 100644
index 9fe5f21..0000000
--- a/android/override_module.go
+++ /dev/null
@@ -1,97 +0,0 @@
-package android
-
-import (
-	"github.com/google/blueprint/proptools"
-	"sync"
-)
-
-func init() {
-	RegisterModuleType("override_module", OverrideModuleFactory)
-}
-
-type OverrideModule struct {
-	ModuleBase
-	properties OverrideModuleProperties
-}
-
-type OverrideModuleProperties struct {
-	// base module to override
-	Base *string
-
-	// file path or module name (in the form ":module") of a certificate to override with
-	Certificate *string
-
-	// manifest package name to override with
-	Manifest_package_name *string
-}
-
-// TODO(jungjw): Work with the mainline team to see if we can deprecate all PRODUCT_*_OVERRIDES vars
-// and hand over overriding values directly to base module code.
-func processOverrides(ctx LoadHookContext, p *OverrideModuleProperties) {
-	base := proptools.String(p.Base)
-	if base == "" {
-		ctx.PropertyErrorf("base", "base module name must be provided")
-	}
-
-	config := ctx.DeviceConfig()
-	if other, loaded := config.moduleNameOverrides().LoadOrStore(base, ctx.ModuleName()); loaded {
-		ctx.ModuleErrorf("multiple overriding modules for %q, the other: %q", base, other.(string))
-	}
-
-	if p.Certificate != nil {
-		config.certificateOverrides().Store(base, *p.Certificate)
-	}
-
-	if p.Manifest_package_name != nil {
-		config.manifestPackageNameOverrides().Store(base, *p.Manifest_package_name)
-	}
-}
-
-func (i *OverrideModule) DepsMutator(ctx BottomUpMutatorContext) {
-	base := *i.properties.Base
-	// Right now, we add a dependency only to check the base module exists, and so are not using a tag here.
-	// TODO(jungjw): Add a tag and check the base module type once we finalize supported base module types.
-	ctx.AddDependency(ctx.Module(), nil, base)
-}
-
-func (i *OverrideModule) GenerateAndroidBuildActions(ctx ModuleContext) {
-	// All the overrides happen in the base module.
-	// TODO(jungjw): Check the base module type.
-}
-
-// override_module overrides an existing module with the specified properties.
-//
-// Currently, only android_app is officially supported.
-func OverrideModuleFactory() Module {
-	m := &OverrideModule{}
-	AddLoadHook(m, func(ctx LoadHookContext) {
-		processOverrides(ctx, &m.properties)
-	})
-	m.AddProperties(&m.properties)
-	InitAndroidModule(m)
-	return m
-}
-
-var moduleNameOverridesKey = NewOnceKey("moduleNameOverrides")
-
-func (c *deviceConfig) moduleNameOverrides() *sync.Map {
-	return c.Once(moduleNameOverridesKey, func() interface{} {
-		return &sync.Map{}
-	}).(*sync.Map)
-}
-
-var certificateOverridesKey = NewOnceKey("certificateOverrides")
-
-func (c *deviceConfig) certificateOverrides() *sync.Map {
-	return c.Once(certificateOverridesKey, func() interface{} {
-		return &sync.Map{}
-	}).(*sync.Map)
-}
-
-var manifestPackageNameOverridesKey = NewOnceKey("manifestPackageNameOverrides")
-
-func (c *deviceConfig) manifestPackageNameOverrides() *sync.Map {
-	return c.Once(manifestPackageNameOverridesKey, func() interface{} {
-		return &sync.Map{}
-	}).(*sync.Map)
-}
diff --git a/apex/apex.go b/apex/apex.go
index 5d0c52a..f72eef3 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -25,8 +25,10 @@
 	"android/soong/android"
 	"android/soong/cc"
 	"android/soong/java"
+	"android/soong/python"
 
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/bootstrap"
 	"github.com/google/blueprint/proptools"
 )
 
@@ -289,6 +291,8 @@
 	nativeSharedLib
 	nativeExecutable
 	shBinary
+	pyBinary
+	goBinary
 	javaSharedLib
 )
 
@@ -348,7 +352,7 @@
 		return "ETC"
 	case nativeSharedLib:
 		return "SHARED_LIBRARIES"
-	case nativeExecutable, shBinary:
+	case nativeExecutable, shBinary, pyBinary, goBinary:
 		return "EXECUTABLES"
 	case javaSharedLib:
 		return "JAVA_LIBRARIES"
@@ -534,7 +538,7 @@
 func (a *apexBundle) getCertString(ctx android.BaseContext) string {
 	certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
 	if overridden {
-		return certificate
+		return ":" + certificate
 	}
 	return String(a.properties.Certificate)
 }
@@ -624,6 +628,22 @@
 	return
 }
 
+func getCopyManifestForPyBinary(py *python.Module) (fileToCopy android.Path, dirInApex string) {
+	dirInApex = "bin"
+	fileToCopy = py.HostToolPath().Path()
+	return
+}
+func getCopyManifestForGoBinary(ctx android.ModuleContext, gb bootstrap.GoBinaryTool) (fileToCopy android.Path, dirInApex string) {
+	dirInApex = "bin"
+	s, err := filepath.Rel(android.PathForOutput(ctx).String(), gb.InstallPath())
+	if err != nil {
+		ctx.ModuleErrorf("Unable to use compiled binary at %s", gb.InstallPath())
+		return
+	}
+	fileToCopy = android.PathForOutput(ctx, s)
+	return
+}
+
 func getCopyManifestForShBinary(sh *android.ShBinary) (fileToCopy android.Path, dirInApex string) {
 	dirInApex = filepath.Join("bin", sh.SubDir())
 	fileToCopy = sh.OutputFile()
@@ -658,7 +678,7 @@
 
 	handleSpecialLibs := !android.Bool(a.properties.Ignore_system_library_special_case)
 
-	ctx.WalkDeps(func(child, parent android.Module) bool {
+	ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
 		if _, ok := parent.(*apexBundle); ok {
 			// direct dependencies
 			depTag := ctx.OtherModuleDependencyTag(child)
@@ -685,8 +705,17 @@
 				} else if sh, ok := child.(*android.ShBinary); ok {
 					fileToCopy, dirInApex := getCopyManifestForShBinary(sh)
 					filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, shBinary, sh, nil})
+				} else if py, ok := child.(*python.Module); ok && py.HostToolPath().Valid() {
+					fileToCopy, dirInApex := getCopyManifestForPyBinary(py)
+					filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, pyBinary, py, nil})
+				} else if gb, ok := child.(bootstrap.GoBinaryTool); ok && a.Host() {
+					fileToCopy, dirInApex := getCopyManifestForGoBinary(ctx, gb)
+					// NB: Since go binaries are static we don't need the module for anything here, which is
+					// good since the go tool is a blueprint.Module not an android.Module like we would
+					// normally use.
+					filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, goBinary, nil, nil})
 				} else {
-					ctx.PropertyErrorf("binaries", "%q is neithher cc_binary nor sh_binary", depName)
+					ctx.PropertyErrorf("binaries", "%q is neither cc_binary, (embedded) py_binary, (host) blueprint_go_binary, (host) bootstrap_go_binary, nor sh_binary", depName)
 				}
 			case javaLibTag:
 				if java, ok := child.(*java.Library); ok {
diff --git a/java/app.go b/java/app.go
index 08b2d91..2ff6c98 100644
--- a/java/app.go
+++ b/java/app.go
@@ -93,6 +93,8 @@
 
 	// the install APK name is normally the same as the module name, but can be overridden with PRODUCT_PACKAGE_NAME_OVERRIDES.
 	installApkName string
+
+	additionalAaptFlags []string
 }
 
 func (a *AndroidApp) ExportedProguardFlagFiles() android.Paths {
@@ -222,6 +224,8 @@
 		aaptLinkFlags = append(aaptLinkFlags, "--rename-manifest-package "+manifestPackageName)
 	}
 
+	aaptLinkFlags = append(aaptLinkFlags, a.additionalAaptFlags...)
+
 	a.aapt.buildActions(ctx, sdkContext(a), aaptLinkFlags...)
 
 	// apps manifests are handled by aapt, don't let Module see them
@@ -392,7 +396,7 @@
 func (a *AndroidApp) getCertString(ctx android.BaseContext) string {
 	certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
 	if overridden {
-		return certificate
+		return ":" + certificate
 	}
 	return String(a.appProperties.Certificate)
 }
@@ -441,6 +445,13 @@
 }
 
 func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	// Check if the instrumentation target package is overridden before generating build actions.
+	if a.appTestProperties.Instrumentation_for != nil {
+		manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(*a.appTestProperties.Instrumentation_for)
+		if overridden {
+			a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName)
+		}
+	}
 	a.generateAndroidBuildActions(ctx)
 
 	a.testConfig = tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config, a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites)
diff --git a/java/app_test.go b/java/app_test.go
index 313844f..1784fc3 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -748,56 +748,29 @@
 	}
 }
 
-func TestOverrideModule(t *testing.T) {
-	ctx := testJava(t, `
+func TestInstrumentationTargetOverridden(t *testing.T) {
+	bp := `
 		android_app {
 			name: "foo",
 			srcs: ["a.java"],
 		}
 
-		override_module {
+		android_test {
 			name: "bar",
-			base: "foo",
-			certificate: ":new_certificate",
-			manifest_package_name: "org.dandroid.bp",
+			instrumentation_for: "foo",
 		}
+		`
+	config := testConfig(nil)
+	config.TestProductVariables.ManifestPackageNameOverrides = []string{"foo:org.dandroid.bp"}
+	ctx := testAppContext(config, bp, nil)
 
-		android_app_certificate {
-			name: "new_certificate",
-	    certificate: "cert/new_cert",
-		}
-		`)
+	run(t, ctx, config)
 
-	// The base module still contains all the final outputs after overrides.
-	foo := ctx.ModuleForTests("foo", "android_common")
-
-	// Check the final apk name
-	outputs := foo.AllOutputs()
-	e := buildDir + "/target/product/test_device/system/app/bar/bar.apk"
-	found := false
-	for _, o := range outputs {
-		if o == e {
-			found = true
-			break
-		}
-	}
-	if !found {
-		t.Errorf("Can't find %q in output files.\nAll outputs:%v", e, outputs)
-	}
-
-	// Check the certificate paths
-	signapk := foo.Output("foo.apk")
-	signFlags := signapk.Args["certificates"]
-	e = "cert/new_cert.x509.pem cert/new_cert.pk8"
-	if e != signFlags {
-		t.Errorf("Incorrect signing flags, expected: %q, got: %q", e, signFlags)
-	}
-
-	// Check the manifest package name
-	res := foo.Output("package-res.apk")
+	bar := ctx.ModuleForTests("bar", "android_common")
+	res := bar.Output("package-res.apk")
 	aapt2Flags := res.Args["flags"]
-	e = "--rename-manifest-package org.dandroid.bp"
+	e := "--rename-instrumentation-target-package org.dandroid.bp"
 	if !strings.Contains(aapt2Flags, e) {
-		t.Errorf("package renaming flag, %q is missing in aapt2 link flags, %q", e, aapt2Flags)
+		t.Errorf("target package renaming flag, %q is missing in aapt2 link flags, %q", e, aapt2Flags)
 	}
 }
diff --git a/java/config/config.go b/java/config/config.go
index 75be9e2..e607b1d 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -33,12 +33,6 @@
 	DefaultLambdaStubsLibrary     = "core-lambda-stubs"
 	SdkLambdaStubsPath            = "prebuilts/sdk/tools/core-lambda-stubs.jar"
 
-	// A list of the jars that provide information about usages of the hidden API.
-	HiddenAPIExtraAppUsageJars = []string{
-		// The core-oj-hiddenapi provides information for the core-oj jar.
-		"core-oj-hiddenapi",
-	}
-
 	DefaultJacocoExcludeFilter = []string{"org.junit.*", "org.jacoco.*", "org.mockito.*"}
 
 	InstrumentFrameworkModules = []string{
@@ -67,6 +61,7 @@
 
 	pctx.StaticVariable("JavacHeapSize", "2048M")
 	pctx.StaticVariable("JavacHeapFlags", "-J-Xmx${JavacHeapSize}")
+	pctx.StaticVariable("DexFlags", "-JXX:+TieredCompilation -JXX:TieredStopAtLevel=1")
 
 	pctx.StaticVariable("CommonJdkFlags", strings.Join([]string{
 		`-Xmaxerrs 9999999`,
diff --git a/java/config/makevars.go b/java/config/makevars.go
index 156ee26..30552da 100644
--- a/java/config/makevars.go
+++ b/java/config/makevars.go
@@ -81,4 +81,6 @@
 
 	ctx.Strict("CLASS2GREYLIST", "${Class2Greylist}")
 	ctx.Strict("HIDDENAPI", "${HiddenAPI}")
+
+	ctx.Strict("DEX_FLAGS", "${DexFlags}")
 }
diff --git a/java/dex.go b/java/dex.go
index 54b7bfc..987129e 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -25,7 +25,7 @@
 var d8 = pctx.AndroidStaticRule("d8",
 	blueprint.RuleParams{
 		Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
-			`${config.D8Cmd} --output $outDir $d8Flags $in && ` +
+			`${config.D8Cmd} ${config.DexFlags} --output $outDir $d8Flags $in && ` +
 			`${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` +
 			`${config.MergeZipsCmd} -D -stripFile "**/*.class" $out $outDir/classes.dex.jar $in`,
 		CommandDeps: []string{
@@ -40,7 +40,7 @@
 	blueprint.RuleParams{
 		Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
 			`rm -f "$outDict" && ` +
-			`${config.R8Cmd} -injars $in --output $outDir ` +
+			`${config.R8Cmd} ${config.DexFlags} -injars $in --output $outDir ` +
 			`--force-proguard-compatibility ` +
 			`--no-data-resources ` +
 			`-printmapping $outDict ` +
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index a35e011..ca68832 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -16,6 +16,7 @@
 
 import (
 	"path/filepath"
+	"sort"
 	"strings"
 
 	"android/soong/android"
@@ -137,6 +138,8 @@
 	if global.GenerateApexImage {
 		d.otherImages = append(d.otherImages, buildBootImage(ctx, apexBootImageConfig(ctx)))
 	}
+
+	dumpOatRules(ctx, d.defaultBootImage)
 }
 
 // buildBootImage takes a bootImageConfig, creates rules to build it, and returns a *bootImage.
@@ -389,6 +392,50 @@
 
 var bootImageProfileRuleKey = android.NewOnceKey("bootImageProfileRule")
 
+func dumpOatRules(ctx android.SingletonContext, image *bootImage) {
+	var archs []android.ArchType
+	for arch := range image.images {
+		archs = append(archs, arch)
+	}
+	sort.Slice(archs, func(i, j int) bool { return archs[i].String() < archs[j].String() })
+
+	var allPhonies android.Paths
+	for _, arch := range archs {
+		// Create a rule to call oatdump.
+		output := android.PathForOutput(ctx, "boot."+arch.String()+".oatdump.txt")
+		rule := android.NewRuleBuilder()
+		rule.Command().
+			// TODO: for now, use the debug version for better error reporting
+			Tool(ctx.Config().HostToolPath(ctx, "oatdumpd")).
+			FlagWithInputList("--runtime-arg -Xbootclasspath:", image.dexPaths.Paths(), ":").
+			FlagWithList("--runtime-arg -Xbootclasspath-locations:", image.dexLocations, ":").
+			FlagWithArg("--image=", dexpreopt.PathToLocation(image.images[arch], arch)).Implicit(image.images[arch]).
+			FlagWithOutput("--output=", output).
+			FlagWithArg("--instruction-set=", arch.String())
+		rule.Build(pctx, ctx, "dump-oat-boot-"+arch.String(), "dump oat boot "+arch.String())
+
+		// Create a phony rule that depends on the output file and prints the path.
+		phony := android.PathForPhony(ctx, "dump-oat-boot-"+arch.String())
+		rule = android.NewRuleBuilder()
+		rule.Command().
+			Implicit(output).
+			ImplicitOutput(phony).
+			Text("echo").FlagWithArg("Output in ", output.String())
+		rule.Build(pctx, ctx, "phony-dump-oat-boot-"+arch.String(), "dump oat boot "+arch.String())
+
+		allPhonies = append(allPhonies, phony)
+	}
+
+	phony := android.PathForPhony(ctx, "dump-oat-boot")
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        android.Phony,
+		Output:      phony,
+		Inputs:      allPhonies,
+		Description: "dump-oat-boot",
+	})
+
+}
+
 // Export paths for default boot image to Make
 func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) {
 	image := d.defaultBootImage
diff --git a/java/hiddenapi.go b/java/hiddenapi.go
index 51ed3dd..6020aba 100644
--- a/java/hiddenapi.go
+++ b/java/hiddenapi.go
@@ -15,10 +15,11 @@
 package java
 
 import (
+	"strings"
+
 	"github.com/google/blueprint"
 
 	"android/soong/android"
-	"android/soong/java/config"
 )
 
 var hiddenAPIGenerateCSVRule = pctx.AndroidStaticRule("hiddenAPIGenerateCSV", blueprint.RuleParams{
@@ -56,20 +57,39 @@
 	uncompressDex bool) android.ModuleOutPath {
 
 	if !ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
-		isBootJar := inList(ctx.ModuleName(), ctx.Config().BootJars())
-		if isBootJar || inList(ctx.ModuleName(), config.HiddenAPIExtraAppUsageJars) {
+		name := ctx.ModuleName()
+
+		// Modules whose names are of the format <x>-hiddenapi provide hiddenapi information
+		// for the boot jar module <x>. Otherwise, the module provides information for itself.
+		// Either way extract the name of the boot jar module.
+		bootJarName := strings.TrimSuffix(name, "-hiddenapi")
+
+		// If this module is on the boot jars list (or providing information for a module
+		// on the list) then extract the hiddenapi information from it, and if necessary
+		// encode that information in the generated dex file.
+		//
+		// It is important that hiddenapi information is only gathered for/from modules on
+		// that are actually on the boot jars list because the runtime only enforces access
+		// to the hidden API for the bootclassloader. If information is gathered for modules
+		// not on the list then that will cause failures in the CtsHiddenApiBlacklist...
+		// tests.
+		if inList(bootJarName, ctx.Config().BootJars()) {
 			// Derive the greylist from classes jar.
 			flagsCSV := android.PathForModuleOut(ctx, "hiddenapi", "flags.csv")
 			metadataCSV := android.PathForModuleOut(ctx, "hiddenapi", "metadata.csv")
 			hiddenAPIGenerateCSV(ctx, flagsCSV, metadataCSV, implementationJar)
 			h.flagsCSVPath = flagsCSV
 			h.metadataCSVPath = metadataCSV
-		}
-		if isBootJar {
-			hiddenAPIJar := android.PathForModuleOut(ctx, "hiddenapi", ctx.ModuleName()+".jar")
-			h.bootDexJarPath = dexJar
-			hiddenAPIEncodeDex(ctx, hiddenAPIJar, dexJar, uncompressDex)
-			dexJar = hiddenAPIJar
+
+			// If this module is actually on the boot jars list and not providing
+			// hiddenapi information for a module on the boot jars list then encode
+			// the gathered information in the generated dex file.
+			if name == bootJarName {
+				hiddenAPIJar := android.PathForModuleOut(ctx, "hiddenapi", name+".jar")
+				h.bootDexJarPath = dexJar
+				hiddenAPIEncodeDex(ctx, hiddenAPIJar, dexJar, uncompressDex)
+				dexJar = hiddenAPIJar
+			}
 		}
 	}
 
diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go
index 23f6cb0..ceafb59 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -89,7 +89,13 @@
 	// Public API stubs
 	publicStubModules := []string{
 		"android_stubs_current",
-		"android.test.base.stubs",
+	}
+
+	// Add the android.test.base to the set of stubs only if the android.test.base module is on
+	// the boot jars list as the runtime will only enforce hiddenapi access against modules on
+	// that list.
+	if inList("android.test.base", ctx.Config().BootJars()) {
+		publicStubModules = append(publicStubModules, "android.test.base.stubs")
 	}
 
 	// System API stubs
diff --git a/java/java_test.go b/java/java_test.go
index bbcc9ed..8d3efcb 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -81,13 +81,11 @@
 	ctx.RegisterModuleType("droiddoc_host", android.ModuleFactoryAdaptor(DroiddocHostFactory))
 	ctx.RegisterModuleType("droiddoc_template", android.ModuleFactoryAdaptor(ExportedDroiddocDirFactory))
 	ctx.RegisterModuleType("java_sdk_library", android.ModuleFactoryAdaptor(SdkLibraryFactory))
-	ctx.RegisterModuleType("override_module", android.ModuleFactoryAdaptor(android.OverrideModuleFactory))
 	ctx.RegisterModuleType("prebuilt_apis", android.ModuleFactoryAdaptor(PrebuiltApisFactory))
 	ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators)
 	ctx.PreArchMutators(android.RegisterPrebuiltsPostDepsMutators)
 	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
 	ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
-		ctx.TopDown("load_hooks", android.LoadHookMutator).Parallel()
 		ctx.TopDown("prebuilt_apis", PrebuiltApisMutator).Parallel()
 		ctx.TopDown("java_sdk_library", SdkLibraryMutator).Parallel()
 	})
diff --git a/java/sdk_library.go b/java/sdk_library.go
index f2df49b..df4e08b 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -607,6 +607,10 @@
 	dir := filepath.Join("prebuilts", "sdk", v, api)
 	jar := filepath.Join(dir, module.BaseModuleName()+".jar")
 	jarPath := android.ExistentPathForSource(ctx, jar)
+	if !jarPath.Valid() {
+		ctx.PropertyErrorf("sdk_library", "invalid sdk version %q, %q does not exist", v, jar)
+		return nil
+	}
 	return android.Paths{jarPath.Path()}
 }