Merge "Update build rule for updated script."
diff --git a/android/module.go b/android/module.go
index ffcbf32..a14e575 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1803,6 +1803,49 @@
 	OutputFiles(tag string) (Paths, error)
 }
 
+// OutputFilesForModule returns the paths from an OutputFileProducer with the given tag.  On error, including if the
+// module produced zero paths, it reports errors to the ctx and returns nil.
+func OutputFilesForModule(ctx PathContext, module blueprint.Module, tag string) Paths {
+	paths, err := outputFilesForModule(ctx, module, tag)
+	if err != nil {
+		reportPathError(ctx, err)
+		return nil
+	}
+	return paths
+}
+
+// OutputFileForModule returns the path from an OutputFileProducer with the given tag.  On error, including if the
+// module produced zero or multiple paths, it reports errors to the ctx and returns nil.
+func OutputFileForModule(ctx PathContext, module blueprint.Module, tag string) Path {
+	paths, err := outputFilesForModule(ctx, module, tag)
+	if err != nil {
+		reportPathError(ctx, err)
+		return nil
+	}
+	if len(paths) > 1 {
+		reportPathErrorf(ctx, "got multiple output files from module %q, expected exactly one",
+			pathContextName(ctx, module))
+		return nil
+	}
+	return paths[0]
+}
+
+func outputFilesForModule(ctx PathContext, module blueprint.Module, tag string) (Paths, error) {
+	if outputFileProducer, ok := module.(OutputFileProducer); ok {
+		paths, err := outputFileProducer.OutputFiles(tag)
+		if err != nil {
+			return nil, fmt.Errorf("failed to get output file from module %q: %s",
+				pathContextName(ctx, module), err.Error())
+		}
+		if len(paths) == 0 {
+			return nil, fmt.Errorf("failed to get output files from module %q", pathContextName(ctx, module))
+		}
+		return paths, nil
+	} else {
+		return nil, fmt.Errorf("module %q is not an OutputFileProducer", pathContextName(ctx, module))
+	}
+}
+
 type HostToolProvider interface {
 	HostToolPath() OptionalPath
 }
diff --git a/android/paths.go b/android/paths.go
index a04dc6b..024432e 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -89,6 +89,15 @@
 	}
 }
 
+func pathContextName(ctx PathContext, module blueprint.Module) string {
+	if x, ok := ctx.(interface{ ModuleName(blueprint.Module) string }); ok {
+		return x.ModuleName(module)
+	} else if x, ok := ctx.(interface{ OtherModuleName(blueprint.Module) string }); ok {
+		return x.OtherModuleName(module)
+	}
+	return "unknown"
+}
+
 type Path interface {
 	// Returns the path in string form
 	String() string
@@ -1304,12 +1313,6 @@
 	return p.path
 }
 
-type testWritablePath struct {
-	testPath
-}
-
-func (p testPath) writablePath() {}
-
 // PathForTesting returns a Path constructed from joining the elements of paths with '/'.  It should only be used from
 // within tests.
 func PathForTesting(paths ...string) Path {
@@ -1330,27 +1333,6 @@
 	return p
 }
 
-// WritablePathForTesting returns a Path constructed from joining the elements of paths with '/'.  It should only be
-// used from within tests.
-func WritablePathForTesting(paths ...string) WritablePath {
-	p, err := validateSafePath(paths...)
-	if err != nil {
-		panic(err)
-	}
-	return testWritablePath{testPath{basePath{path: p, rel: p}}}
-}
-
-// WritablePathsForTesting returns a Path constructed from each element in strs. It should only be used from within
-// tests.
-func WritablePathsForTesting(strs ...string) WritablePaths {
-	p := make(WritablePaths, len(strs))
-	for i, s := range strs {
-		p[i] = WritablePathForTesting(s)
-	}
-
-	return p
-}
-
 type testPathContext struct {
 	config Config
 }
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 0ee1201..2c99f1f 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -25,6 +25,11 @@
 // This file implements common functionality for handling modules that may exist as prebuilts,
 // source, or both.
 
+func RegisterPrebuiltMutators(ctx RegistrationContext) {
+	ctx.PreArchMutators(RegisterPrebuiltsPreArchMutators)
+	ctx.PostDepsMutators(RegisterPrebuiltsPostDepsMutators)
+}
+
 type prebuiltDependencyTag struct {
 	blueprint.BaseDependencyTag
 }
diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go
index 600f078..8648b93 100644
--- a/android/prebuilt_test.go
+++ b/android/prebuilt_test.go
@@ -141,8 +141,7 @@
 			config := TestConfig(buildDir, nil, bp, fs)
 
 			ctx := NewTestContext()
-			ctx.PreArchMutators(RegisterPrebuiltsPreArchMutators)
-			ctx.PostDepsMutators(RegisterPrebuiltsPostDepsMutators)
+			RegisterPrebuiltMutators(ctx)
 			ctx.RegisterModuleType("filegroup", FileGroupFactory)
 			ctx.RegisterModuleType("prebuilt", newPrebuiltModule)
 			ctx.RegisterModuleType("source", newSourceModule)
diff --git a/android/register.go b/android/register.go
index d79982a..b5defec 100644
--- a/android/register.go
+++ b/android/register.go
@@ -15,6 +15,8 @@
 package android
 
 import (
+	"fmt"
+
 	"github.com/google/blueprint"
 )
 
@@ -114,3 +116,72 @@
 	}
 	return ret
 }
+
+// Interface for registering build components.
+//
+// Provided to allow registration of build components to be shared between the runtime
+// and test environments.
+type RegistrationContext interface {
+	RegisterModuleType(name string, factory ModuleFactory)
+	RegisterSingletonType(name string, factory SingletonFactory)
+	PreArchMutators(f RegisterMutatorFunc)
+	PreDepsMutators(f RegisterMutatorFunc)
+	PostDepsMutators(f RegisterMutatorFunc)
+}
+
+// Used to register build components from an init() method, e.g.
+//
+// init() {
+//   RegisterBuildComponents(android.InitRegistrationContext)
+// }
+//
+// func RegisterBuildComponents(ctx android.RegistrationContext) {
+//   ctx.RegisterModuleType(...)
+//   ...
+// }
+//
+// Extracting the actual registration into a separate RegisterBuildComponents(ctx) function
+// allows it to be used to initialize test context, e.g.
+//
+//   ctx := android.NewTestContext()
+//   RegisterBuildComponents(ctx)
+var InitRegistrationContext RegistrationContext = &initRegistrationContext{
+	moduleTypes:    make(map[string]ModuleFactory),
+	singletonTypes: make(map[string]SingletonFactory),
+}
+
+// Make sure the TestContext implements RegistrationContext.
+var _ RegistrationContext = (*TestContext)(nil)
+
+type initRegistrationContext struct {
+	moduleTypes    map[string]ModuleFactory
+	singletonTypes map[string]SingletonFactory
+}
+
+func (ctx *initRegistrationContext) RegisterModuleType(name string, factory ModuleFactory) {
+	if _, present := ctx.moduleTypes[name]; present {
+		panic(fmt.Sprintf("module type %q is already registered", name))
+	}
+	ctx.moduleTypes[name] = factory
+	RegisterModuleType(name, factory)
+}
+
+func (ctx *initRegistrationContext) RegisterSingletonType(name string, factory SingletonFactory) {
+	if _, present := ctx.singletonTypes[name]; present {
+		panic(fmt.Sprintf("singleton type %q is already registered", name))
+	}
+	ctx.singletonTypes[name] = factory
+	RegisterSingletonType(name, factory)
+}
+
+func (ctx *initRegistrationContext) PreArchMutators(f RegisterMutatorFunc) {
+	PreArchMutators(f)
+}
+
+func (ctx *initRegistrationContext) PreDepsMutators(f RegisterMutatorFunc) {
+	PreDepsMutators(f)
+}
+
+func (ctx *initRegistrationContext) PostDepsMutators(f RegisterMutatorFunc) {
+	PostDepsMutators(f)
+}
diff --git a/android/sh_binary.go b/android/sh_binary.go
index 3293d4f..7d9dc67 100644
--- a/android/sh_binary.go
+++ b/android/sh_binary.go
@@ -16,6 +16,7 @@
 
 import (
 	"fmt"
+	"path/filepath"
 	"strings"
 )
 
@@ -74,8 +75,11 @@
 
 	sourceFilePath Path
 	outputFilePath OutputPath
+	installedFile  InstallPath
 }
 
+var _ HostToolProvider = (*ShBinary)(nil)
+
 type ShTest struct {
 	ShBinary
 
@@ -84,16 +88,16 @@
 	data Paths
 }
 
+func (s *ShBinary) HostToolPath() OptionalPath {
+	return OptionalPathForPath(s.installedFile)
+}
+
 func (s *ShBinary) DepsMutator(ctx BottomUpMutatorContext) {
 	if s.properties.Src == nil {
 		ctx.PropertyErrorf("src", "missing prebuilt source file")
 	}
 }
 
-func (s *ShBinary) SourceFilePath(ctx ModuleContext) Path {
-	return PathForModuleSrc(ctx, String(s.properties.Src))
-}
-
 func (s *ShBinary) OutputFile() OutputPath {
 	return s.outputFilePath
 }
@@ -110,7 +114,7 @@
 	return s.properties.Symlinks
 }
 
-func (s *ShBinary) GenerateAndroidBuildActions(ctx ModuleContext) {
+func (s *ShBinary) generateAndroidBuildActions(ctx ModuleContext) {
 	s.sourceFilePath = PathForModuleSrc(ctx, String(s.properties.Src))
 	filename := String(s.properties.Filename)
 	filename_from_src := Bool(s.properties.Filename_from_src)
@@ -135,6 +139,12 @@
 	})
 }
 
+func (s *ShBinary) GenerateAndroidBuildActions(ctx ModuleContext) {
+	s.generateAndroidBuildActions(ctx)
+	installDir := PathForModuleInstall(ctx, "bin", String(s.properties.Sub_dir))
+	s.installedFile = ctx.InstallExecutable(installDir, s.outputFilePath.Base(), s.outputFilePath)
+}
+
 func (s *ShBinary) AndroidMkEntries() []AndroidMkEntries {
 	return []AndroidMkEntries{AndroidMkEntries{
 		Class:      "EXECUTABLES",
@@ -158,11 +168,26 @@
 }
 
 func (s *ShTest) GenerateAndroidBuildActions(ctx ModuleContext) {
-	s.ShBinary.GenerateAndroidBuildActions(ctx)
+	s.ShBinary.generateAndroidBuildActions(ctx)
+	testDir := "nativetest"
+	if ctx.Target().Arch.ArchType.Multilib == "lib64" {
+		testDir = "nativetest64"
+	}
+	if ctx.Target().NativeBridge == NativeBridgeEnabled {
+		testDir = filepath.Join(testDir, ctx.Target().NativeBridgeRelativePath)
+	} else if !ctx.Host() && ctx.Config().HasMultilibConflict(ctx.Arch().ArchType) {
+		testDir = filepath.Join(testDir, ctx.Arch().ArchType.String())
+	}
+	installDir := PathForModuleInstall(ctx, testDir, String(s.properties.Sub_dir))
+	s.installedFile = ctx.InstallExecutable(installDir, s.outputFilePath.Base(), s.outputFilePath)
 
 	s.data = PathsForModuleSrc(ctx, s.testProperties.Data)
 }
 
+func (s *ShTest) InstallInData() bool {
+	return true
+}
+
 func (s *ShTest) AndroidMkEntries() []AndroidMkEntries {
 	return []AndroidMkEntries{AndroidMkEntries{
 		Class:      "NATIVE_TESTS",
diff --git a/apex/androidmk.go b/apex/androidmk.go
index a231a90..7d1a301 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -22,7 +22,6 @@
 
 	"android/soong/android"
 	"android/soong/cc"
-	"android/soong/java"
 
 	"github.com/google/blueprint/proptools"
 )
@@ -119,7 +118,7 @@
 			}
 		}
 		if fi.class == javaSharedLib {
-			javaModule := fi.module.(*java.Library)
+			javaModule := fi.module.(javaLibrary)
 			// soong_java_prebuilt.mk sets LOCAL_MODULE_SUFFIX := .jar  Therefore
 			// we need to remove the suffix from LOCAL_MODULE_STEM, otherwise
 			// we will have foo.jar.jar
diff --git a/apex/apex.go b/apex/apex.go
index 8a336ba..f6997bf 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -872,10 +872,16 @@
 	return af
 }
 
-func apexFileForJavaLibrary(ctx android.BaseModuleContext, java *java.Library) apexFile {
+// TODO(b/146586360): replace javaLibrary(in apex/apex.go) with java.Dependency
+type javaLibrary interface {
+	android.Module
+	java.Dependency
+}
+
+func apexFileForJavaLibrary(ctx android.BaseModuleContext, lib javaLibrary) apexFile {
 	dirInApex := "javalib"
-	fileToCopy := java.DexJarFile()
-	return newApexFile(ctx, fileToCopy, java.Name(), dirInApex, javaSharedLib, java)
+	fileToCopy := lib.DexJar()
+	return newApexFile(ctx, fileToCopy, lib.Name(), dirInApex, javaSharedLib, lib)
 }
 
 func apexFileForPrebuiltJavaLibrary(ctx android.BaseModuleContext, java *java.Import) apexFile {
@@ -1022,6 +1028,21 @@
 						filesInfo = append(filesInfo, af)
 						return true // track transitive dependencies
 					}
+				} else if sdkLib, ok := child.(*java.SdkLibrary); ok {
+					af := apexFileForJavaLibrary(ctx, sdkLib)
+					if !af.Ok() {
+						ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
+						return false
+					}
+					filesInfo = append(filesInfo, af)
+
+					pf := sdkLib.PermissionFile()
+					if pf == nil {
+						ctx.PropertyErrorf("java_libs", "%q failed to generate permission XML", depName)
+						return false
+					}
+					filesInfo = append(filesInfo, newApexFile(ctx, pf, pf.Base(), "etc/permissions", etc, nil))
+					return true // track transitive dependencies
 				} else if javaLib, ok := child.(*java.Import); ok {
 					af := apexFileForPrebuiltJavaLibrary(ctx, javaLib)
 					if !af.Ok() {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index b2d891d..e8dc9aa 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -286,50 +286,25 @@
 	ctx.RegisterModuleType("prebuilt_apex", PrebuiltFactory)
 	ctx.RegisterModuleType("override_apex", overrideApexFactory)
 
-	ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
 	ctx.RegisterModuleType("cc_library_shared", cc.LibrarySharedFactory)
 	ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory)
-	ctx.RegisterModuleType("cc_prebuilt_library_shared", cc.PrebuiltSharedLibraryFactory)
-	ctx.RegisterModuleType("cc_prebuilt_library_static", cc.PrebuiltStaticLibraryFactory)
+	cc.RegisterRequiredBuildComponentsForTest(ctx)
 	ctx.RegisterModuleType("cc_binary", cc.BinaryFactory)
-	ctx.RegisterModuleType("cc_object", cc.ObjectFactory)
-	ctx.RegisterModuleType("cc_defaults", func() android.Module {
-		return cc.DefaultsFactory()
-	})
 	ctx.RegisterModuleType("cc_test", cc.TestFactory)
-	ctx.RegisterModuleType("llndk_library", cc.LlndkLibraryFactory)
 	ctx.RegisterModuleType("vndk_prebuilt_shared", cc.VndkPrebuiltSharedFactory)
 	ctx.RegisterModuleType("vndk_libraries_txt", cc.VndkLibrariesTxtFactory)
-	ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory)
 	ctx.RegisterModuleType("prebuilt_etc", android.PrebuiltEtcFactory)
 	ctx.RegisterModuleType("sh_binary", android.ShBinaryFactory)
-	ctx.RegisterModuleType("android_app_certificate", java.AndroidAppCertificateFactory)
 	ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
-	ctx.RegisterModuleType("java_library", java.LibraryFactory)
-	ctx.RegisterModuleType("java_import", java.ImportFactory)
-	ctx.RegisterModuleType("java_system_modules", java.SystemModulesFactory)
-	ctx.RegisterModuleType("android_app", java.AndroidAppFactory)
-	ctx.RegisterModuleType("android_app_import", java.AndroidAppImportFactory)
-	ctx.RegisterModuleType("override_android_app", java.OverrideAndroidAppModuleFactory)
+	java.RegisterJavaBuildComponents(ctx)
+	java.RegisterSystemModulesBuildComponents(ctx)
+	java.RegisterAppBuildComponents(ctx)
+	ctx.RegisterModuleType("java_sdk_library", java.SdkLibraryFactory)
 
 	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
-	ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
-		ctx.BottomUp("prebuilts", android.PrebuiltMutator).Parallel()
-	})
-	ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
-		ctx.BottomUp("vndk", cc.VndkMutator).Parallel()
-		ctx.BottomUp("link", cc.LinkageMutator).Parallel()
-		ctx.BottomUp("test_per_src", cc.TestPerSrcMutator).Parallel()
-		ctx.BottomUp("version", cc.VersionMutator).Parallel()
-		ctx.BottomUp("begin", cc.BeginMutator).Parallel()
-	})
 	ctx.PreDepsMutators(RegisterPreDepsMutators)
 	ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
 	ctx.PostDepsMutators(RegisterPostDepsMutators)
-	ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
-		ctx.TopDown("prebuilt_select", android.PrebuiltSelectModuleMutator).Parallel()
-		ctx.BottomUp("prebuilt_postdeps", android.PrebuiltPostDepsMutator).Parallel()
-	})
 
 	ctx.Register(config)
 
@@ -3257,6 +3232,44 @@
 	ensureContains(t, args["opt_flags"], "--manifest_json "+module.Output("apex_manifest.json").Output.String())
 }
 
+func TestJavaSDKLibrary(t *testing.T) {
+	ctx, _ := testApex(t, `
+		apex {
+			name: "myapex",
+			key: "myapex.key",
+			java_libs: ["foo"],
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		java_sdk_library {
+			name: "foo",
+			srcs: ["a.java"],
+			api_packages: ["foo"],
+		}
+	`, withFiles(map[string][]byte{
+		"api/current.txt":        nil,
+		"api/removed.txt":        nil,
+		"api/system-current.txt": nil,
+		"api/system-removed.txt": nil,
+		"api/test-current.txt":   nil,
+		"api/test-removed.txt":   nil,
+	}))
+
+	// java_sdk_library installs both impl jar and permission XML
+	ensureExactContents(t, ctx, "myapex", []string{
+		"javalib/foo.jar",
+		"etc/permissions/foo.xml",
+	})
+	// Permission XML should point to the activated path of impl jar of java_sdk_library
+	genXMLCommand := ctx.ModuleForTests("foo", "android_common_myapex").Output("foo.xml").RuleParams.Command
+	ensureContains(t, genXMLCommand, `<library name="foo" file="/apex/myapex/javalib/foo.jar"`)
+}
+
 func TestRejectNonInstallableJavaLibrary(t *testing.T) {
 	testApexError(t, `"myjar" is not configured to be compiled into dex`, `
 		apex {
diff --git a/cc/cc.go b/cc/cc.go
index 4c9d42b..14e7122 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -33,9 +33,15 @@
 )
 
 func init() {
-	android.RegisterModuleType("cc_defaults", defaultsFactory)
+	RegisterCCBuildComponents(android.InitRegistrationContext)
 
-	android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
+	pctx.Import("android/soong/cc/config")
+}
+
+func RegisterCCBuildComponents(ctx android.RegistrationContext) {
+	ctx.RegisterModuleType("cc_defaults", defaultsFactory)
+
+	ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
 		ctx.BottomUp("vndk", VndkMutator).Parallel()
 		ctx.BottomUp("link", LinkageMutator).Parallel()
 		ctx.BottomUp("ndk_api", NdkApiMutator).Parallel()
@@ -45,7 +51,7 @@
 		ctx.BottomUp("sysprop_cc", SyspropMutator).Parallel()
 	})
 
-	android.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
+	ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
 		ctx.TopDown("asan_deps", sanitizerDepsMutator(asan))
 		ctx.BottomUp("asan", sanitizerMutator(asan)).Parallel()
 
@@ -79,7 +85,6 @@
 	})
 
 	android.RegisterSingletonType("kythe_extract_all", kytheExtractAllFactory)
-	pctx.Import("android/soong/cc/config")
 }
 
 type Deps struct {
diff --git a/cc/cc_test.go b/cc/cc_test.go
index d73dac5..27ff38f 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -2478,7 +2478,7 @@
 			srcs: ["foo.c"],
 		}`)
 
-	variant := "android_arm64_armv8-a"
+	variant := "android_arm64_armv8-a_fuzzer"
 	ctx.ModuleForTests("fuzz_smoke_test", variant).Rule("cc")
 }
 
diff --git a/cc/compdb.go b/cc/compdb.go
index 519380f..dff14db 100644
--- a/cc/compdb.go
+++ b/cc/compdb.go
@@ -27,7 +27,7 @@
 // This singleton generates a compile_commands.json file. It does so for each
 // blueprint Android.bp resulting in a cc.Module when either make, mm, mma, mmm
 // or mmma is called. It will only create a single compile_commands.json file
-// at out/development/ide/compdb/compile_commands.json. It will also symlink it
+// at ${OUT_DIR}/soong/development/ide/compdb/compile_commands.json. It will also symlink it
 // to ${SOONG_LINK_COMPDB_TO} if set. In general this should be created by running
 // make SOONG_GEN_COMPDB=1 nothing to get all targets.
 
@@ -43,7 +43,7 @@
 
 const (
 	compdbFilename                = "compile_commands.json"
-	compdbOutputProjectsDirectory = "out/development/ide/compdb"
+	compdbOutputProjectsDirectory = "development/ide/compdb"
 
 	// Environment variables used to modify behavior of this singleton.
 	envVariableGenerateCompdb          = "SOONG_GEN_COMPDB"
@@ -78,12 +78,12 @@
 	})
 
 	// Create the output file.
-	dir := filepath.Join(getCompdbAndroidSrcRootDirectory(ctx), compdbOutputProjectsDirectory)
-	os.MkdirAll(dir, 0777)
-	compDBFile := filepath.Join(dir, compdbFilename)
-	f, err := os.Create(compdbFilename)
+	dir := android.PathForOutput(ctx, compdbOutputProjectsDirectory)
+	os.MkdirAll(dir.String(), 0777)
+	compDBFile := dir.Join(ctx, compdbFilename)
+	f, err := os.Create(compDBFile.String())
 	if err != nil {
-		log.Fatalf("Could not create file %s: %s", filepath.Join(dir, compdbFilename), err)
+		log.Fatalf("Could not create file %s: %s", compDBFile, err)
 	}
 	defer f.Close()
 
@@ -106,7 +106,7 @@
 	finalLinkPath := filepath.Join(ctx.Config().Getenv(envVariableCompdbLink), compdbFilename)
 	if finalLinkPath != "" {
 		os.Remove(finalLinkPath)
-		if err := os.Symlink(compDBFile, finalLinkPath); err != nil {
+		if err := os.Symlink(compDBFile.String(), finalLinkPath); err != nil {
 			log.Fatalf("Unable to symlink %s to %s: %s", compDBFile, finalLinkPath, err)
 		}
 	}
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 0d3cc74..8b84be8 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -27,9 +27,10 @@
 type FuzzConfig struct {
 	// Email address of people to CC on bugs or contact about this fuzz target.
 	Cc []string `json:"cc,omitempty"`
-	// Boolean specifying whether to disable the fuzz target from running
-	// automatically in continuous fuzzing infrastructure.
-	Disable *bool `json:"disable,omitempty"`
+	// Specify whether to enable continuous fuzzing on devices. Defaults to true.
+	Fuzz_on_haiku_device *bool `json:"fuzz_on_haiku_device,omitempty"`
+	// Specify whether to enable continuous fuzzing on host. Defaults to true.
+	Fuzz_on_haiku_host *bool `json:"fuzz_on_haiku_host,omitempty"`
 	// Component in Google's bug tracking system that bugs should be filed to.
 	Componentid *int64 `json:"componentid,omitempty"`
 	// Hotlists in Google's bug tracking system that bugs should be marked with.
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index f20616f..b0cf489 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -19,9 +19,13 @@
 )
 
 func init() {
-	android.RegisterModuleType("cc_prebuilt_library_shared", PrebuiltSharedLibraryFactory)
-	android.RegisterModuleType("cc_prebuilt_library_static", PrebuiltStaticLibraryFactory)
-	android.RegisterModuleType("cc_prebuilt_binary", prebuiltBinaryFactory)
+	RegisterPrebuiltBuildComponents(android.InitRegistrationContext)
+}
+
+func RegisterPrebuiltBuildComponents(ctx android.RegistrationContext) {
+	ctx.RegisterModuleType("cc_prebuilt_library_shared", PrebuiltSharedLibraryFactory)
+	ctx.RegisterModuleType("cc_prebuilt_library_static", PrebuiltStaticLibraryFactory)
+	ctx.RegisterModuleType("cc_prebuilt_binary", prebuiltBinaryFactory)
 }
 
 type prebuiltLinkerInterface interface {
diff --git a/cc/prebuilt_test.go b/cc/prebuilt_test.go
index 31db2df..3d809fc 100644
--- a/cc/prebuilt_test.go
+++ b/cc/prebuilt_test.go
@@ -72,13 +72,6 @@
 
 	ctx := CreateTestContext()
 
-	ctx.RegisterModuleType("cc_prebuilt_library_shared", PrebuiltSharedLibraryFactory)
-	ctx.RegisterModuleType("cc_prebuilt_library_static", PrebuiltStaticLibraryFactory)
-	ctx.RegisterModuleType("cc_prebuilt_binary", prebuiltBinaryFactory)
-
-	ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators)
-	ctx.PostDepsMutators(android.RegisterPrebuiltsPostDepsMutators)
-
 	ctx.Register(config)
 
 	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
diff --git a/cc/testing.go b/cc/testing.go
index 93f27cd..de4f1ec 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -18,6 +18,18 @@
 	"android/soong/android"
 )
 
+func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
+	RegisterPrebuiltBuildComponents(ctx)
+	ctx.RegisterModuleType("toolchain_library", ToolchainLibraryFactory)
+	ctx.RegisterModuleType("cc_library", LibraryFactory)
+	ctx.RegisterModuleType("llndk_library", LlndkLibraryFactory)
+	ctx.RegisterModuleType("cc_object", ObjectFactory)
+
+	android.RegisterPrebuiltMutators(ctx)
+
+	RegisterCCBuildComponents(ctx)
+}
+
 func GatherRequiredDepsForTest(os android.OsType) string {
 	ret := `
 		toolchain_library {
@@ -97,6 +109,14 @@
 			src: "",
 		}
 
+		// Needed for sanitizer
+		cc_prebuilt_library_shared {
+			name: "libclang_rt.ubsan_standalone-aarch64-android",
+			vendor_available: true,
+			recovery_available: true,
+			srcs: [""],
+		}
+
 		toolchain_library {
 			name: "libgcc",
 			vendor_available: true,
@@ -285,33 +305,20 @@
 
 func CreateTestContext() *android.TestContext {
 	ctx := android.NewTestArchContext()
-	ctx.RegisterModuleType("cc_defaults", defaultsFactory)
 	ctx.RegisterModuleType("cc_binary", BinaryFactory)
 	ctx.RegisterModuleType("cc_binary_host", binaryHostFactory)
 	ctx.RegisterModuleType("cc_fuzz", FuzzFactory)
-	ctx.RegisterModuleType("cc_library", LibraryFactory)
 	ctx.RegisterModuleType("cc_library_shared", LibrarySharedFactory)
 	ctx.RegisterModuleType("cc_library_static", LibraryStaticFactory)
 	ctx.RegisterModuleType("cc_library_headers", LibraryHeaderFactory)
 	ctx.RegisterModuleType("cc_test", TestFactory)
-	ctx.RegisterModuleType("toolchain_library", ToolchainLibraryFactory)
-	ctx.RegisterModuleType("llndk_library", LlndkLibraryFactory)
 	ctx.RegisterModuleType("llndk_headers", llndkHeadersFactory)
 	ctx.RegisterModuleType("ndk_library", NdkLibraryFactory)
 	ctx.RegisterModuleType("vendor_public_library", vendorPublicLibraryFactory)
-	ctx.RegisterModuleType("cc_object", ObjectFactory)
 	ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
 	ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory)
 	ctx.RegisterModuleType("vndk_libraries_txt", VndkLibrariesTxtFactory)
-	ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
-		ctx.BottomUp("link", LinkageMutator).Parallel()
-		ctx.BottomUp("vndk", VndkMutator).Parallel()
-		ctx.BottomUp("version", VersionMutator).Parallel()
-		ctx.BottomUp("begin", BeginMutator).Parallel()
-	})
-	ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
-		ctx.TopDown("double_loadable", checkDoubleLoadableLibraries).Parallel()
-	})
+	RegisterRequiredBuildComponentsForTest(ctx)
 	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
 	ctx.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton)
 
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index ee04dfd..fc1bae1 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -222,6 +222,14 @@
 
 	invocationPath := odexPath.ReplaceExtension(ctx, "invocation")
 
+	// TODO(skvadrik): fix this to use boot image location in the module config (currently it is broken
+	// in JIT-zygote builds, because "default" boot image is hard-coded in parts of the module config).
+	bootImage := module.DexPreoptImages[archIdx]
+	var bootImageLocation string
+	if bootImage != nil {
+		bootImageLocation = PathToLocation(bootImage, arch)
+	}
+
 	// The class loader context using paths in the build
 	var classLoaderContextHost android.Paths
 
@@ -349,7 +357,7 @@
 		Flag("--runtime-arg").FlagWithList("-Xbootclasspath-locations:", module.PreoptBootClassPathDexLocations, ":").
 		Flag("${class_loader_context_arg}").
 		Flag("${stored_class_loader_context_arg}").
-		FlagWithArg("--boot-image=", strings.Join(module.DexPreoptImageLocations, ":")).Implicits(module.DexPreoptImagesDeps[archIdx].Paths()).
+		FlagWithArg("--boot-image=", bootImageLocation).Implicits(module.DexPreoptImagesDeps[archIdx].Paths()).
 		FlagWithInput("--dex-file=", module.DexPath).
 		FlagWithArg("--dex-location=", dexLocationArg).
 		FlagWithOutput("--oat-file=", odexPath).ImplicitOutput(vdexPath).
diff --git a/java/aar.go b/java/aar.go
index e0bea5d..201e590 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -34,8 +34,12 @@
 }
 
 func init() {
-	android.RegisterModuleType("android_library_import", AARImportFactory)
-	android.RegisterModuleType("android_library", AndroidLibraryFactory)
+	RegisterAARBuildComponents(android.InitRegistrationContext)
+}
+
+func RegisterAARBuildComponents(ctx android.RegistrationContext) {
+	ctx.RegisterModuleType("android_library_import", AARImportFactory)
+	ctx.RegisterModuleType("android_library", AndroidLibraryFactory)
 }
 
 //
diff --git a/java/app.go b/java/app.go
index ae637fd..94f6bb1 100755
--- a/java/app.go
+++ b/java/app.go
@@ -33,18 +33,22 @@
 var supportedDpis = []string{"ldpi", "mdpi", "hdpi", "xhdpi", "xxhdpi", "xxxhdpi"}
 
 func init() {
-	android.RegisterModuleType("android_app", AndroidAppFactory)
-	android.RegisterModuleType("android_test", AndroidTestFactory)
-	android.RegisterModuleType("android_test_helper_app", AndroidTestHelperAppFactory)
-	android.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory)
-	android.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory)
-	android.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory)
-	android.RegisterModuleType("android_app_import", AndroidAppImportFactory)
-	android.RegisterModuleType("android_test_import", AndroidTestImportFactory)
+	RegisterAppBuildComponents(android.InitRegistrationContext)
 
 	initAndroidAppImportVariantGroupTypes()
 }
 
+func RegisterAppBuildComponents(ctx android.RegistrationContext) {
+	ctx.RegisterModuleType("android_app", AndroidAppFactory)
+	ctx.RegisterModuleType("android_test", AndroidTestFactory)
+	ctx.RegisterModuleType("android_test_helper_app", AndroidTestHelperAppFactory)
+	ctx.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory)
+	ctx.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory)
+	ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory)
+	ctx.RegisterModuleType("android_app_import", AndroidAppImportFactory)
+	ctx.RegisterModuleType("android_test_import", AndroidTestImportFactory)
+}
+
 // AndroidManifest.xml merging
 // package splits
 
diff --git a/java/config/config.go b/java/config/config.go
index 06c99f1..9738454 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -29,7 +29,7 @@
 
 	DefaultBootclasspathLibraries = []string{"core.platform.api.stubs", "core-lambda-stubs"}
 	DefaultSystemModules          = "core-platform-api-stubs-system-modules"
-	DefaultLibraries              = []string{"ext", "framework", "updatable_media_stubs"}
+	DefaultLibraries              = []string{"ext", "framework"}
 	DefaultLambdaStubsLibrary     = "core-lambda-stubs"
 	SdkLambdaStubsPath            = "prebuilts/sdk/tools/core-lambda-stubs.jar"
 
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 92f9246..3b7f772 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -27,19 +27,8 @@
 )
 
 func init() {
-	android.RegisterModuleType("doc_defaults", DocDefaultsFactory)
-	android.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
-
-	android.RegisterModuleType("droiddoc", DroiddocFactory)
-	android.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
-	android.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
-	android.RegisterModuleType("javadoc", JavadocFactory)
-	android.RegisterModuleType("javadoc_host", JavadocHostFactory)
-
-	android.RegisterModuleType("droidstubs", DroidstubsFactory)
-	android.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
-
-	android.RegisterModuleType("prebuilt_stubs_sources", PrebuiltStubsSourcesFactory)
+	RegisterDocsBuildComponents(android.InitRegistrationContext)
+	RegisterStubsBuildComponents(android.InitRegistrationContext)
 
 	// Register sdk member type.
 	android.RegisterSdkMemberType(&droidStubsSdkMemberType{
@@ -49,6 +38,25 @@
 	})
 }
 
+func RegisterDocsBuildComponents(ctx android.RegistrationContext) {
+	ctx.RegisterModuleType("doc_defaults", DocDefaultsFactory)
+
+	ctx.RegisterModuleType("droiddoc", DroiddocFactory)
+	ctx.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
+	ctx.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
+	ctx.RegisterModuleType("javadoc", JavadocFactory)
+	ctx.RegisterModuleType("javadoc_host", JavadocHostFactory)
+}
+
+func RegisterStubsBuildComponents(ctx android.RegistrationContext) {
+	ctx.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
+
+	ctx.RegisterModuleType("droidstubs", DroidstubsFactory)
+	ctx.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
+
+	ctx.RegisterModuleType("prebuilt_stubs_sources", PrebuiltStubsSourcesFactory)
+}
+
 var (
 	srcsLibTag = dependencyTag{name: "sources from javalib"}
 )
@@ -782,7 +790,7 @@
 		if t, ok := m.(*ExportedDroiddocDir); ok {
 			cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
 		} else {
-			ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
+			ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_exported_dir", ctx.OtherModuleName(m))
 		}
 	})
 
diff --git a/java/genrule.go b/java/genrule.go
index 25494ec..e0a9c8f 100644
--- a/java/genrule.go
+++ b/java/genrule.go
@@ -20,8 +20,12 @@
 )
 
 func init() {
-	android.RegisterModuleType("java_genrule", genRuleFactory)
-	android.RegisterModuleType("java_genrule_host", genRuleFactoryHost)
+	RegisterGenRuleBuildComponents(android.InitRegistrationContext)
+}
+
+func RegisterGenRuleBuildComponents(ctx android.RegistrationContext) {
+	ctx.RegisterModuleType("java_genrule", genRuleFactory)
+	ctx.RegisterModuleType("java_genrule_host", genRuleFactoryHost)
 }
 
 // java_genrule is a genrule that can depend on other java_* objects.
diff --git a/java/java.go b/java/java.go
index 052e06f..d0bf9d7 100644
--- a/java/java.go
+++ b/java/java.go
@@ -34,24 +34,7 @@
 )
 
 func init() {
-	android.RegisterModuleType("java_defaults", DefaultsFactory)
-
-	android.RegisterModuleType("java_library", LibraryFactory)
-	android.RegisterModuleType("java_library_static", LibraryStaticFactory)
-	android.RegisterModuleType("java_library_host", LibraryHostFactory)
-	android.RegisterModuleType("java_binary", BinaryFactory)
-	android.RegisterModuleType("java_binary_host", BinaryHostFactory)
-	android.RegisterModuleType("java_test", TestFactory)
-	android.RegisterModuleType("java_test_helper_library", TestHelperLibraryFactory)
-	android.RegisterModuleType("java_test_host", TestHostFactory)
-	android.RegisterModuleType("java_import", ImportFactory)
-	android.RegisterModuleType("java_import_host", ImportFactoryHost)
-	android.RegisterModuleType("java_device_for_host", DeviceForHostFactory)
-	android.RegisterModuleType("java_host_for_device", HostForDeviceFactory)
-	android.RegisterModuleType("dex_import", DexImportFactory)
-
-	android.RegisterSingletonType("logtags", LogtagsSingleton)
-	android.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory)
+	RegisterJavaBuildComponents(android.InitRegistrationContext)
 
 	// Register sdk member types.
 	android.RegisterSdkMemberType(&headerLibrarySdkMemberType{
@@ -71,6 +54,27 @@
 	})
 }
 
+func RegisterJavaBuildComponents(ctx android.RegistrationContext) {
+	ctx.RegisterModuleType("java_defaults", DefaultsFactory)
+
+	ctx.RegisterModuleType("java_library", LibraryFactory)
+	ctx.RegisterModuleType("java_library_static", LibraryStaticFactory)
+	ctx.RegisterModuleType("java_library_host", LibraryHostFactory)
+	ctx.RegisterModuleType("java_binary", BinaryFactory)
+	ctx.RegisterModuleType("java_binary_host", BinaryHostFactory)
+	ctx.RegisterModuleType("java_test", TestFactory)
+	ctx.RegisterModuleType("java_test_helper_library", TestHelperLibraryFactory)
+	ctx.RegisterModuleType("java_test_host", TestHostFactory)
+	ctx.RegisterModuleType("java_import", ImportFactory)
+	ctx.RegisterModuleType("java_import_host", ImportFactoryHost)
+	ctx.RegisterModuleType("java_device_for_host", DeviceForHostFactory)
+	ctx.RegisterModuleType("java_host_for_device", HostForDeviceFactory)
+	ctx.RegisterModuleType("dex_import", DexImportFactory)
+
+	ctx.RegisterSingletonType("logtags", LogtagsSingleton)
+	ctx.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory)
+}
+
 func (j *Module) checkSdkVersion(ctx android.ModuleContext) {
 	if j.SocSpecific() || j.DeviceSpecific() ||
 		(j.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
@@ -422,10 +426,6 @@
 	}
 }
 
-func (j *Module) DexJarFile() android.Path {
-	return j.dexJarFile
-}
-
 var _ android.OutputFileProducer = (*Module)(nil)
 
 type Dependency interface {
diff --git a/java/java_test.go b/java/java_test.go
index 49838c7..096cdb9 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -63,58 +63,28 @@
 func testContext() *android.TestContext {
 
 	ctx := android.NewTestArchContext()
-	ctx.RegisterModuleType("android_app", AndroidAppFactory)
-	ctx.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory)
-	ctx.RegisterModuleType("android_app_import", AndroidAppImportFactory)
-	ctx.RegisterModuleType("android_library", AndroidLibraryFactory)
-	ctx.RegisterModuleType("android_test", AndroidTestFactory)
-	ctx.RegisterModuleType("android_test_helper_app", AndroidTestHelperAppFactory)
-	ctx.RegisterModuleType("android_test_import", AndroidTestImportFactory)
-	ctx.RegisterModuleType("java_binary", BinaryFactory)
-	ctx.RegisterModuleType("java_binary_host", BinaryHostFactory)
-	ctx.RegisterModuleType("java_device_for_host", DeviceForHostFactory)
-	ctx.RegisterModuleType("java_host_for_device", HostForDeviceFactory)
-	ctx.RegisterModuleType("java_library", LibraryFactory)
-	ctx.RegisterModuleType("java_library_host", LibraryHostFactory)
-	ctx.RegisterModuleType("java_test", TestFactory)
-	ctx.RegisterModuleType("java_import", ImportFactory)
-	ctx.RegisterModuleType("java_import_host", ImportFactoryHost)
-	ctx.RegisterModuleType("java_defaults", DefaultsFactory)
-	ctx.RegisterModuleType("java_system_modules", SystemModulesFactory)
-	ctx.RegisterModuleType("java_genrule", genRuleFactory)
+	RegisterJavaBuildComponents(ctx)
+	RegisterAppBuildComponents(ctx)
+	RegisterAARBuildComponents(ctx)
+	RegisterGenRuleBuildComponents(ctx)
+	RegisterSystemModulesBuildComponents(ctx)
 	ctx.RegisterModuleType("java_plugin", PluginFactory)
-	ctx.RegisterModuleType("dex_import", DexImportFactory)
 	ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
 	ctx.RegisterModuleType("genrule", genrule.GenRuleFactory)
-	ctx.RegisterModuleType("droiddoc", DroiddocFactory)
-	ctx.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
-	ctx.RegisterModuleType("droiddoc_template", ExportedDroiddocDirFactory)
-	ctx.RegisterModuleType("prebuilt_stubs_sources", PrebuiltStubsSourcesFactory)
-	ctx.RegisterModuleType("java_sdk_library", SdkLibraryFactory)
-	ctx.RegisterModuleType("java_sdk_library_import", sdkLibraryImportFactory)
-	ctx.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory)
-	ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory)
-	ctx.RegisterModuleType("prebuilt_apis", PrebuiltApisFactory)
-	ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators)
-	ctx.PreArchMutators(android.RegisterPrebuiltsPostDepsMutators)
+	RegisterDocsBuildComponents(ctx)
+	RegisterStubsBuildComponents(ctx)
+	RegisterSdkLibraryBuildComponents(ctx)
 	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
-	ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
-		ctx.TopDown("prebuilt_apis", PrebuiltApisMutator).Parallel()
-	})
+
+	RegisterPrebuiltApisBuildComponents(ctx)
+
 	ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
 	ctx.RegisterPreSingletonType("overlay", android.SingletonFactoryAdaptor(OverlaySingletonFactory))
 	ctx.RegisterPreSingletonType("sdk_versions", android.SingletonFactoryAdaptor(sdkPreSingletonFactory))
 
 	// Register module types and mutators from cc needed for JNI testing
-	ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
-	ctx.RegisterModuleType("cc_object", cc.ObjectFactory)
-	ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory)
-	ctx.RegisterModuleType("llndk_library", cc.LlndkLibraryFactory)
+	cc.RegisterRequiredBuildComponentsForTest(ctx)
 	ctx.RegisterModuleType("ndk_prebuilt_shared_stl", cc.NdkPrebuiltSharedStlFactory)
-	ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
-		ctx.BottomUp("link", cc.LinkageMutator).Parallel()
-		ctx.BottomUp("begin", cc.BeginMutator).Parallel()
-	})
 
 	return ctx
 }
@@ -892,7 +862,7 @@
 
 func TestDroiddoc(t *testing.T) {
 	ctx, _ := testJava(t, `
-		droiddoc_template {
+		droiddoc_exported_dir {
 		    name: "droiddoc-templates-sdk",
 		    path: ".",
 		}
@@ -1038,7 +1008,7 @@
 
 func TestJavaSdkLibrary(t *testing.T) {
 	ctx, _ := testJava(t, `
-		droiddoc_template {
+		droiddoc_exported_dir {
 			name: "droiddoc-templates-sdk",
 			path: ".",
 		}
@@ -1244,7 +1214,7 @@
 		checkPatchModuleFlag(t, ctx, "foo", "")
 		expected := "java.base=.:" + buildDir
 		checkPatchModuleFlag(t, ctx, "bar", expected)
-		expected = "java.base=" + strings.Join([]string{".", buildDir, moduleToPath("ext"), moduleToPath("framework"), moduleToPath("updatable_media_stubs")}, ":")
+		expected = "java.base=" + strings.Join([]string{".", buildDir, moduleToPath("ext"), moduleToPath("framework")}, ":")
 		checkPatchModuleFlag(t, ctx, "baz", expected)
 	})
 }
diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go
index 0d5e31f..cb17fee 100644
--- a/java/prebuilt_apis.go
+++ b/java/prebuilt_apis.go
@@ -23,9 +23,13 @@
 )
 
 func init() {
-	android.RegisterModuleType("prebuilt_apis", PrebuiltApisFactory)
+	RegisterPrebuiltApisBuildComponents(android.InitRegistrationContext)
+}
 
-	android.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
+func RegisterPrebuiltApisBuildComponents(ctx android.RegistrationContext) {
+	ctx.RegisterModuleType("prebuilt_apis", PrebuiltApisFactory)
+
+	ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
 		ctx.TopDown("prebuilt_apis", PrebuiltApisMutator).Parallel()
 	})
 }
diff --git a/java/sdk_library.go b/java/sdk_library.go
index e204659..def2753 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -29,12 +29,31 @@
 	"github.com/google/blueprint/proptools"
 )
 
-var (
+const (
 	sdkStubsLibrarySuffix = ".stubs"
 	sdkSystemApiSuffix    = ".system"
 	sdkTestApiSuffix      = ".test"
 	sdkDocsSuffix         = ".docs"
 	sdkXmlFileSuffix      = ".xml"
+	permissionTemplate    = `<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+	Licensed under the Apache License, Version 2.0 (the "License");
+	you may not use this file except in compliance with the License.
+	You may obtain a copy of the License at
+
+		http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing, software
+	distributed under the License is distributed on an "AS IS" BASIS,
+	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+	See the License for the specific language governing permissions and
+	limitations under the License.
+-->
+<permissions>
+	<library name="%s" file="%s"/>
+</permissions>
+`
 )
 
 type stubsLibraryDependencyTag struct {
@@ -68,8 +87,7 @@
 // 2) HTML generation
 
 func init() {
-	android.RegisterModuleType("java_sdk_library", SdkLibraryFactory)
-	android.RegisterModuleType("java_sdk_library_import", sdkLibraryImportFactory)
+	RegisterSdkLibraryBuildComponents(android.InitRegistrationContext)
 
 	android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
 		javaSdkLibraries := javaSdkLibraries(ctx.Config())
@@ -78,6 +96,11 @@
 	})
 }
 
+func RegisterSdkLibraryBuildComponents(ctx android.RegistrationContext) {
+	ctx.RegisterModuleType("java_sdk_library", SdkLibraryFactory)
+	ctx.RegisterModuleType("java_sdk_library_import", sdkLibraryImportFactory)
+}
+
 type sdkLibraryProperties struct {
 	// List of Java libraries that will be in the classpath when building stubs
 	Stub_only_libs []string `android:"arch_variant"`
@@ -130,6 +153,8 @@
 	publicApiFilePath android.Path
 	systemApiFilePath android.Path
 	testApiFilePath   android.Path
+
+	permissionFile android.Path
 }
 
 var _ Dependency = (*SdkLibrary)(nil)
@@ -159,6 +184,10 @@
 func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	module.Library.GenerateAndroidBuildActions(ctx)
 
+	if module.ApexName() != "" {
+		module.buildPermissionFile(ctx)
+	}
+
 	// Record the paths to the header jars of the library (stubs and impl).
 	// When this java_sdk_library is dependened from others via "libs" property,
 	// the recorded paths will be returned depending on the link type of the caller.
@@ -194,6 +223,21 @@
 	})
 }
 
+func (module *SdkLibrary) buildPermissionFile(ctx android.ModuleContext) {
+	xmlContent := strings.ReplaceAll(fmt.Sprintf(permissionTemplate, module.BaseModuleName(), module.implPath()), "\n", "\\n")
+	permissionFile := android.PathForModuleOut(ctx, module.xmlFileName())
+
+	rule := android.NewRuleBuilder()
+	rule.Command().Text("echo -e ").Text(proptools.ShellEscape(xmlContent)).Text(">").Output(permissionFile)
+	rule.Build(pctx, ctx, "gen_permission_xml", "Generate permission")
+
+	module.permissionFile = permissionFile
+}
+
+func (module *SdkLibrary) PermissionFile() android.Path {
+	return module.permissionFile
+}
+
 func (module *SdkLibrary) AndroidMkEntries() []android.AndroidMkEntries {
 	entriesList := module.Library.AndroidMkEntries()
 	entries := &entriesList[0]
@@ -286,6 +330,12 @@
 
 // File path to the runtime implementation library
 func (module *SdkLibrary) implPath() string {
+	if apexName := module.ApexName(); apexName != "" {
+		// TODO(b/146468504): ApexName() is only a soong module name, not apex name.
+		// In most cases, this works fine. But when apex_name is set or override_apex is used
+		// this can be wrong.
+		return fmt.Sprintf("/apex/%s/javalib/%s.jar", apexName, module.implName())
+	}
 	partition := "system"
 	if module.SocSpecific() {
 		partition = "vendor"
@@ -528,31 +578,11 @@
 
 // Creates the xml file that publicizes the runtime library
 func (module *SdkLibrary) createXmlFile(mctx android.LoadHookContext) {
-	template := `
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
 
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<permissions>
-    <library name="%s" file="%s"/>
-</permissions>
-`
 	// genrule to generate the xml file content from the template above
 	// TODO: preserve newlines in the generate xml file. Newlines are being squashed
 	// in the ninja file. Do we need to have an external tool for this?
-	xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
+	xmlContent := fmt.Sprintf(permissionTemplate, module.BaseModuleName(), module.implPath())
 	genruleProps := struct {
 		Name *string
 		Cmd  *string
@@ -662,10 +692,12 @@
 func (module *SdkLibrary) CreateInternalModules(mctx android.LoadHookContext) {
 	if len(module.Library.Module.properties.Srcs) == 0 {
 		mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
+		return
 	}
 
 	if len(module.sdkLibraryProperties.Api_packages) == 0 {
 		mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
+		return
 	}
 
 	missing_current_api := false
@@ -741,6 +773,7 @@
 func SdkLibraryFactory() android.Module {
 	module := &SdkLibrary{}
 	module.InitSdkLibraryProperties()
+	android.InitApexModule(module)
 	InitJavaModule(module, android.HostAndDeviceSupported)
 	android.AddLoadHook(module, func(ctx android.LoadHookContext) { module.CreateInternalModules(ctx) })
 	return module
diff --git a/java/system_modules.go b/java/system_modules.go
index b56a401..ed2fc18 100644
--- a/java/system_modules.go
+++ b/java/system_modules.go
@@ -28,11 +28,15 @@
 // system modules in a runtime image using the jmod and jlink tools.
 
 func init() {
-	android.RegisterModuleType("java_system_modules", SystemModulesFactory)
+	RegisterSystemModulesBuildComponents(android.InitRegistrationContext)
 
 	pctx.SourcePathVariable("moduleInfoJavaPath", "build/soong/scripts/jars-to-module-info-java.sh")
 }
 
+func RegisterSystemModulesBuildComponents(ctx android.RegistrationContext) {
+	ctx.RegisterModuleType("java_system_modules", SystemModulesFactory)
+}
+
 var (
 	jarsTosystemModules = pctx.AndroidStaticRule("jarsTosystemModules", blueprint.RuleParams{
 		Command: `rm -rf ${outDir} ${workDir} && mkdir -p ${workDir}/jmod && ` +
diff --git a/java/testing.go b/java/testing.go
index c9f5905..e157dd0 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -138,7 +138,6 @@
 	extraModules := []string{
 		"core-lambda-stubs",
 		"ext",
-		"updatable_media_stubs",
 		"android_stubs_current",
 		"android_system_stubs_current",
 		"android_test_stubs_current",
diff --git a/rust/testing.go b/rust/testing.go
index 1dd16cf..f9adec8 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -75,97 +75,19 @@
 		//////////////////////////////
 		// Device module requirements
 
-		toolchain_library {
-			name: "libgcc",
-			no_libcrt: true,
-			nocrt: true,
-			src: "",
-			system_shared_libs: [],
-		}
-		cc_library {
-			name: "libc",
-			no_libcrt: true,
-			nocrt: true,
-			system_shared_libs: [],
-		}
-		cc_library {
-			name: "libm",
-			no_libcrt: true,
-			nocrt: true,
-			system_shared_libs: [],
-		}
-		cc_library {
-			name: "libdl",
-			no_libcrt: true,
-			nocrt: true,
-			system_shared_libs: [],
-		}
-		cc_object {
-			name: "crtbegin_dynamic",
-		}
-
-		cc_object {
-			name: "crtend_android",
-		}
 		cc_library {
 			name: "liblog",
 			no_libcrt: true,
 			nocrt: true,
 			system_shared_libs: [],
 		}
-
-		//////////////////////////////
-		// cc module requirements
-
-		toolchain_library {
-			name: "libatomic",
-			src: "",
-		}
-		toolchain_library {
-			name: "libclang_rt.builtins-aarch64-android",
-			src: "",
-		}
-		toolchain_library {
-			name: "libgcc_stripped",
-			src: "",
-		}
-		cc_library {
-			name: "libc++_static",
-			no_libcrt: true,
-			nocrt: true,
-			system_shared_libs: [],
-			stl: "none",
-		}
-		cc_library {
-			name: "libc++demangle",
-			no_libcrt: true,
-			nocrt: true,
-			system_shared_libs: [],
-			stl: "none",
-			host_supported: false,
-		}
-		cc_library {
-			name: "libc++",
-			no_libcrt: true,
-			nocrt: true,
-			system_shared_libs: [],
-			stl: "none",
-		}
-		cc_library {
-			name: "libunwind_llvm",
-			no_libcrt: true,
-			nocrt: true,
-			system_shared_libs: [],
-			stl: "none",
-		}
-		`
+` + cc.GatherRequiredDepsForTest(android.NoOsType)
 	return bp
 }
 
 func CreateTestContext() *android.TestContext {
 	ctx := android.NewTestArchContext()
-	ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
-	ctx.RegisterModuleType("cc_object", cc.ObjectFactory)
+	cc.RegisterRequiredBuildComponentsForTest(ctx)
 	ctx.RegisterModuleType("rust_binary", RustBinaryFactory)
 	ctx.RegisterModuleType("rust_binary_host", RustBinaryHostFactory)
 	ctx.RegisterModuleType("rust_test", RustTestFactory)
@@ -182,13 +104,7 @@
 	ctx.RegisterModuleType("rust_library_host_static", RustLibraryStaticHostFactory)
 	ctx.RegisterModuleType("rust_proc_macro", ProcMacroFactory)
 	ctx.RegisterModuleType("rust_prebuilt_dylib", PrebuiltDylibFactory)
-	ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory)
 	ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
-		// cc mutators
-		ctx.BottomUp("link", cc.LinkageMutator).Parallel()
-		ctx.BottomUp("version", cc.VersionMutator).Parallel()
-		ctx.BottomUp("begin", cc.BeginMutator).Parallel()
-
 		// rust mutators
 		ctx.BottomUp("rust_libraries", LibraryMutator).Parallel()
 		ctx.BottomUp("rust_unit_tests", TestPerSrcMutator).Parallel()
diff --git a/sdk/testing.go b/sdk/testing.go
index 77ba2e6..eec7f01 100644
--- a/sdk/testing.go
+++ b/sdk/testing.go
@@ -68,39 +68,17 @@
 	ctx.PreArchMutators(android.RegisterVisibilityRuleGatherer)
 	ctx.PostDepsMutators(android.RegisterVisibilityRuleEnforcer)
 
-	ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
-		ctx.BottomUp("prebuilts", android.PrebuiltMutator).Parallel()
-	})
-	ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
-		ctx.TopDown("prebuilt_select", android.PrebuiltSelectModuleMutator).Parallel()
-		ctx.BottomUp("prebuilt_postdeps", android.PrebuiltPostDepsMutator).Parallel()
-	})
 	ctx.RegisterModuleType("package", android.PackageFactory)
 
 	// from java package
-	ctx.RegisterModuleType("android_app_certificate", java.AndroidAppCertificateFactory)
-	ctx.RegisterModuleType("java_defaults", java.DefaultsFactory)
-	ctx.RegisterModuleType("java_library", java.LibraryFactory)
-	ctx.RegisterModuleType("java_import", java.ImportFactory)
-	ctx.RegisterModuleType("droidstubs", java.DroidstubsFactory)
-	ctx.RegisterModuleType("prebuilt_stubs_sources", java.PrebuiltStubsSourcesFactory)
+	java.RegisterJavaBuildComponents(ctx)
+	java.RegisterAppBuildComponents(ctx)
+	java.RegisterStubsBuildComponents(ctx)
 
 	// from cc package
-	ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
+	cc.RegisterRequiredBuildComponentsForTest(ctx)
 	ctx.RegisterModuleType("cc_library_shared", cc.LibrarySharedFactory)
 	ctx.RegisterModuleType("cc_library_static", cc.LibraryStaticFactory)
-	ctx.RegisterModuleType("cc_object", cc.ObjectFactory)
-	ctx.RegisterModuleType("cc_prebuilt_library_shared", cc.PrebuiltSharedLibraryFactory)
-	ctx.RegisterModuleType("cc_prebuilt_library_static", cc.PrebuiltStaticLibraryFactory)
-	ctx.RegisterModuleType("llndk_library", cc.LlndkLibraryFactory)
-	ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory)
-	ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
-		ctx.BottomUp("link", cc.LinkageMutator).Parallel()
-		ctx.BottomUp("vndk", cc.VndkMutator).Parallel()
-		ctx.BottomUp("test_per_src", cc.TestPerSrcMutator).Parallel()
-		ctx.BottomUp("version", cc.VersionMutator).Parallel()
-		ctx.BottomUp("begin", cc.BeginMutator).Parallel()
-	})
 
 	// from apex package
 	ctx.RegisterModuleType("apex", apex.BundleFactory)
diff --git a/sysprop/sysprop_test.go b/sysprop/sysprop_test.go
index 6ac3f4c..0c0f222 100644
--- a/sysprop/sysprop_test.go
+++ b/sysprop/sysprop_test.go
@@ -56,28 +56,19 @@
 func testContext(config android.Config) *android.TestContext {
 
 	ctx := android.NewTestArchContext()
-	ctx.RegisterModuleType("android_app", java.AndroidAppFactory)
-	ctx.RegisterModuleType("java_library", java.LibraryFactory)
-	ctx.RegisterModuleType("java_system_modules", java.SystemModulesFactory)
-	ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators)
-	ctx.PreArchMutators(android.RegisterPrebuiltsPostDepsMutators)
+	java.RegisterJavaBuildComponents(ctx)
+	java.RegisterAppBuildComponents(ctx)
+	java.RegisterSystemModulesBuildComponents(ctx)
+
 	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
 	ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
 		ctx.BottomUp("sysprop_deps", syspropDepsMutator).Parallel()
 	})
 
-	ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
+	cc.RegisterRequiredBuildComponentsForTest(ctx)
 	ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory)
 	ctx.RegisterModuleType("cc_library_static", cc.LibraryFactory)
-	ctx.RegisterModuleType("cc_object", cc.ObjectFactory)
-	ctx.RegisterModuleType("llndk_library", cc.LlndkLibraryFactory)
-	ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory)
 	ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
-		ctx.BottomUp("link", cc.LinkageMutator).Parallel()
-		ctx.BottomUp("vndk", cc.VndkMutator).Parallel()
-		ctx.BottomUp("version", cc.VersionMutator).Parallel()
-		ctx.BottomUp("begin", cc.BeginMutator).Parallel()
-		ctx.BottomUp("sysprop_cc", cc.SyspropMutator).Parallel()
 		ctx.BottomUp("sysprop_java", java.SyspropMutator).Parallel()
 	})
 
diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
index 90ff706..711a9c7 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -94,7 +94,6 @@
 	"patch":    Allowed,
 	"pstree":   Allowed,
 	"python3":  Allowed,
-	"realpath": Allowed,
 	"rsync":    Allowed,
 	"sh":       Allowed,
 	"tr":       Allowed,