Merge "build: Link the unwinder dynamically into platform and vendor binaries."
diff --git a/Android.bp b/Android.bp
index 45180c3..ab03a36 100644
--- a/Android.bp
+++ b/Android.bp
@@ -69,6 +69,7 @@
         "android/proto.go",
         "android/register.go",
         "android/rule_builder.go",
+        "android/sandbox.go",
         "android/sdk.go",
         "android/sh_binary.go",
         "android/singleton.go",
diff --git a/android/androidmk.go b/android/androidmk.go
index f3c15e4..dbf3aa8 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -323,7 +323,7 @@
 		return
 	}
 
-	err := translateAndroidMk(ctx, transMk.String(), androidMkModulesList)
+	err := translateAndroidMk(ctx, absolutePath(transMk.String()), androidMkModulesList)
 	if err != nil {
 		ctx.Errorf(err.Error())
 	}
@@ -364,8 +364,8 @@
 	}
 
 	// Don't write to the file if it hasn't changed
-	if _, err := os.Stat(mkFile); !os.IsNotExist(err) {
-		if data, err := ioutil.ReadFile(mkFile); err == nil {
+	if _, err := os.Stat(absolutePath(mkFile)); !os.IsNotExist(err) {
+		if data, err := ioutil.ReadFile(absolutePath(mkFile)); err == nil {
 			matches := buf.Len() == len(data)
 
 			if matches {
@@ -383,7 +383,7 @@
 		}
 	}
 
-	return ioutil.WriteFile(mkFile, buf.Bytes(), 0666)
+	return ioutil.WriteFile(absolutePath(mkFile), buf.Bytes(), 0666)
 }
 
 func translateAndroidMkModule(ctx SingletonContext, w io.Writer, mod blueprint.Module) error {
diff --git a/android/apex.go b/android/apex.go
index 8482dc2..a4b6956 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -82,7 +82,10 @@
 }
 
 type ApexProperties struct {
-	// Availability of this module in APEXes. Only the listed APEXes can include this module.
+	// Availability of this module in APEXes. Only the listed APEXes can contain
+	// this module. If the module has stubs then other APEXes and the platform may
+	// access it through them (subject to visibility).
+	//
 	// "//apex_available:anyapex" is a pseudo APEX name that matches to any APEX.
 	// "//apex_available:platform" refers to non-APEX partitions like "system.img".
 	// Default is ["//apex_available:platform", "//apex_available:anyapex"].
@@ -144,9 +147,9 @@
 
 func CheckAvailableForApex(what string, apex_available []string) bool {
 	if len(apex_available) == 0 {
-		// apex_available defaults to ["//apex_available:platform", "//apex_available:anyapex"],
-		// which means 'available to everybody'.
-		return true
+		// apex_available defaults to ["//apex_available:platform"],
+		// which means 'available to the platform but no apexes'.
+		return what == AvailableToPlatform
 	}
 	return InList(what, apex_available) ||
 		(what != AvailableToPlatform && InList(availableToAnyApex, apex_available))
diff --git a/android/config.go b/android/config.go
index 101f457..1cb543d 100644
--- a/android/config.go
+++ b/android/config.go
@@ -135,12 +135,12 @@
 }
 
 func loadConfig(config *config) error {
-	err := loadFromConfigFile(&config.FileConfigurableOptions, config.ConfigFileName)
+	err := loadFromConfigFile(&config.FileConfigurableOptions, absolutePath(config.ConfigFileName))
 	if err != nil {
 		return err
 	}
 
-	return loadFromConfigFile(&config.productVariables, config.ProductVariablesFileName)
+	return loadFromConfigFile(&config.productVariables, absolutePath(config.ProductVariablesFileName))
 }
 
 // loads configuration options from a JSON file in the cwd.
@@ -204,6 +204,17 @@
 	return nil
 }
 
+// NullConfig returns a mostly empty Config for use by standalone tools like dexpreopt_gen that
+// use the android package.
+func NullConfig(buildDir string) Config {
+	return Config{
+		config: &config{
+			buildDir: buildDir,
+			fs:       pathtools.OsFs,
+		},
+	}
+}
+
 // TestConfig returns a Config object suitable for using for tests
 func TestConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config {
 	envCopy := make(map[string]string)
@@ -320,7 +331,7 @@
 		buildDir:          buildDir,
 		multilibConflicts: make(map[ArchType]bool),
 
-		fs: pathtools.OsFs,
+		fs: pathtools.NewOsFs(absSrcDir),
 	}
 
 	config.deviceConfig = &deviceConfig{
@@ -350,7 +361,7 @@
 	}
 
 	inMakeFile := filepath.Join(buildDir, ".soong.in_make")
-	if _, err := os.Stat(inMakeFile); err == nil {
+	if _, err := os.Stat(absolutePath(inMakeFile)); err == nil {
 		config.inMake = true
 	}
 
@@ -398,6 +409,8 @@
 	return Config{config}, nil
 }
 
+var TestConfigOsFs = map[string][]byte{}
+
 // mockFileSystem replaces all reads with accesses to the provided map of
 // filenames to contents stored as a byte slice.
 func (c *config) mockFileSystem(bp string, fs map[string][]byte) {
@@ -822,6 +835,14 @@
 	return c.Getenv("XREF_CORPUS")
 }
 
+// Returns Compilation Unit encoding to use. Can be 'json' (default), 'proto' or 'all'.
+func (c *config) XrefCuEncoding() string {
+	if enc := c.Getenv("KYTHE_KZIP_ENCODING"); enc != "" {
+		return enc
+	}
+	return "json"
+}
+
 func (c *config) EmitXrefRules() bool {
 	return c.XrefCorpusName() != ""
 }
@@ -901,8 +922,13 @@
 	return c.productVariables.BootJars
 }
 
-func (c *config) DexpreoptGlobalConfig() string {
-	return String(c.productVariables.DexpreoptGlobalConfig)
+func (c *config) DexpreoptGlobalConfig(ctx PathContext) ([]byte, error) {
+	if c.productVariables.DexpreoptGlobalConfig == nil {
+		return nil, nil
+	}
+	path := absolutePath(*c.productVariables.DexpreoptGlobalConfig)
+	ctx.AddNinjaFileDeps(path)
+	return ioutil.ReadFile(path)
 }
 
 func (c *config) FrameworksBaseDirExists(ctx PathContext) bool {
diff --git a/android/env.go b/android/env.go
index d9f2db2..46bd3d6 100644
--- a/android/env.go
+++ b/android/env.go
@@ -52,6 +52,17 @@
 	os.Clearenv()
 }
 
+// getenv checks either os.Getenv or originalEnv so that it works before or after the init()
+// function above.  It doesn't add any dependencies on the environment variable, so it should
+// only be used for values that won't change.  For values that might change use ctx.Config().Getenv.
+func getenv(key string) string {
+	if originalEnv == nil {
+		return os.Getenv(key)
+	} else {
+		return originalEnv[key]
+	}
+}
+
 func EnvSingleton() Singleton {
 	return &envSingleton{}
 }
@@ -66,7 +77,12 @@
 		return
 	}
 
-	err := env.WriteEnvFile(envFile.String(), envDeps)
+	data, err := env.EnvFileContents(envDeps)
+	if err != nil {
+		ctx.Errorf(err.Error())
+	}
+
+	err = WriteFileToOutputDir(envFile, data, 0666)
 	if err != nil {
 		ctx.Errorf(err.Error())
 	}
diff --git a/android/makevars.go b/android/makevars.go
index 38a028c..aba4cce 100644
--- a/android/makevars.go
+++ b/android/makevars.go
@@ -23,7 +23,6 @@
 	"strings"
 
 	"github.com/google/blueprint"
-	"github.com/google/blueprint/pathtools"
 	"github.com/google/blueprint/proptools"
 )
 
@@ -41,7 +40,6 @@
 	Config() Config
 	DeviceConfig() DeviceConfig
 	AddNinjaFileDeps(deps ...string)
-	Fs() pathtools.FileSystem
 
 	ModuleName(module blueprint.Module) string
 	ModuleDir(module blueprint.Module) string
@@ -151,7 +149,8 @@
 		return
 	}
 
-	outFile := PathForOutput(ctx, "make_vars"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String()
+	outFile := absolutePath(PathForOutput(ctx,
+		"make_vars"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String())
 
 	if ctx.Failed() {
 		return
@@ -175,15 +174,15 @@
 
 	outBytes := s.writeVars(vars)
 
-	if _, err := os.Stat(outFile); err == nil {
-		if data, err := ioutil.ReadFile(outFile); err == nil {
+	if _, err := os.Stat(absolutePath(outFile)); err == nil {
+		if data, err := ioutil.ReadFile(absolutePath(outFile)); err == nil {
 			if bytes.Equal(data, outBytes) {
 				return
 			}
 		}
 	}
 
-	if err := ioutil.WriteFile(outFile, outBytes, 0666); err != nil {
+	if err := ioutil.WriteFile(absolutePath(outFile), outBytes, 0666); err != nil {
 		ctx.Errorf(err.Error())
 	}
 }
diff --git a/android/module.go b/android/module.go
index c998007..05115d6 100644
--- a/android/module.go
+++ b/android/module.go
@@ -16,13 +16,13 @@
 
 import (
 	"fmt"
+	"os"
 	"path"
 	"path/filepath"
 	"strings"
 	"text/scanner"
 
 	"github.com/google/blueprint"
-	"github.com/google/blueprint/pathtools"
 	"github.com/google/blueprint/proptools"
 )
 
@@ -91,7 +91,8 @@
 
 	Glob(globPattern string, excludes []string) Paths
 	GlobFiles(globPattern string, excludes []string) Paths
-	Fs() pathtools.FileSystem
+	IsSymlink(path Path) bool
+	Readlink(path Path) string
 }
 
 // BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns
@@ -1172,6 +1173,22 @@
 	return pathsForModuleSrcFromFullPath(e, ret, false)
 }
 
+func (b *earlyModuleContext) IsSymlink(path Path) bool {
+	fileInfo, err := b.config.fs.Lstat(path.String())
+	if err != nil {
+		b.ModuleErrorf("os.Lstat(%q) failed: %s", path.String(), err)
+	}
+	return fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink
+}
+
+func (b *earlyModuleContext) Readlink(path Path) string {
+	dest, err := b.config.fs.Readlink(path.String())
+	if err != nil {
+		b.ModuleErrorf("os.Readlink(%q) failed: %s", path.String(), err)
+	}
+	return dest
+}
+
 func (e *earlyModuleContext) Module() Module {
 	module, _ := e.EarlyModuleContext.Module().(Module)
 	return module
@@ -1729,7 +1746,7 @@
 			Rule:        Symlink,
 			Description: "install symlink " + fullInstallPath.Base(),
 			Output:      fullInstallPath,
-			OrderOnly:   Paths{srcPath},
+			Input:       srcPath,
 			Default:     !m.Config().EmbeddedInMake(),
 			Args: map[string]string{
 				"fromPath": relPath,
diff --git a/android/mutator.go b/android/mutator.go
index f2f9663..3d1bb4f 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -27,6 +27,7 @@
 //   run Pre-deps mutators
 //   run depsMutator
 //   run PostDeps mutators
+//   run FinalDeps mutators (CreateVariations disallowed in this phase)
 //   continue on to GenerateAndroidBuildActions
 
 func registerMutatorsToContext(ctx *blueprint.Context, mutators []*mutator) {
@@ -43,7 +44,7 @@
 	}
 }
 
-func registerMutators(ctx *blueprint.Context, preArch, preDeps, postDeps []RegisterMutatorFunc) {
+func registerMutators(ctx *blueprint.Context, preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc) {
 	mctx := &registerMutatorsContext{}
 
 	register := func(funcs []RegisterMutatorFunc) {
@@ -60,11 +61,15 @@
 
 	register(postDeps)
 
+	mctx.finalPhase = true
+	register(finalDeps)
+
 	registerMutatorsToContext(ctx, mctx.mutators)
 }
 
 type registerMutatorsContext struct {
-	mutators []*mutator
+	mutators   []*mutator
+	finalPhase bool
 }
 
 type RegisterMutatorsContext interface {
@@ -102,6 +107,8 @@
 	RegisterOverridePostDepsMutators,
 }
 
+var finalDeps = []RegisterMutatorFunc{}
+
 func PreArchMutators(f RegisterMutatorFunc) {
 	preArch = append(preArch, f)
 }
@@ -114,6 +121,10 @@
 	postDeps = append(postDeps, f)
 }
 
+func FinalDepsMutators(f RegisterMutatorFunc) {
+	finalDeps = append(finalDeps, f)
+}
+
 type TopDownMutator func(TopDownMutatorContext)
 
 type TopDownMutatorContext interface {
@@ -156,14 +167,17 @@
 type bottomUpMutatorContext struct {
 	bp blueprint.BottomUpMutatorContext
 	baseModuleContext
+	finalPhase bool
 }
 
 func (x *registerMutatorsContext) BottomUp(name string, m BottomUpMutator) MutatorHandle {
+	finalPhase := x.finalPhase
 	f := func(ctx blueprint.BottomUpMutatorContext) {
 		if a, ok := ctx.Module().(Module); ok {
 			actx := &bottomUpMutatorContext{
 				bp:                ctx,
 				baseModuleContext: a.base().baseModuleContextFactory(ctx),
+				finalPhase:        finalPhase,
 			}
 			m(actx)
 		}
@@ -285,6 +299,10 @@
 }
 
 func (b *bottomUpMutatorContext) CreateVariations(variations ...string) []Module {
+	if b.finalPhase {
+		panic("CreateVariations not allowed in FinalDepsMutators")
+	}
+
 	modules := b.bp.CreateVariations(variations...)
 
 	aModules := make([]Module, len(modules))
@@ -299,6 +317,10 @@
 }
 
 func (b *bottomUpMutatorContext) CreateLocalVariations(variations ...string) []Module {
+	if b.finalPhase {
+		panic("CreateLocalVariations not allowed in FinalDepsMutators")
+	}
+
 	modules := b.bp.CreateLocalVariations(variations...)
 
 	aModules := make([]Module, len(modules))
diff --git a/android/mutator_test.go b/android/mutator_test.go
index d179f9d..191b535 100644
--- a/android/mutator_test.go
+++ b/android/mutator_test.go
@@ -15,9 +15,12 @@
 package android
 
 import (
+	"fmt"
 	"reflect"
+	"strings"
 	"testing"
 
+	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
 )
 
@@ -185,3 +188,110 @@
 		t.Errorf("want module String() values:\n%q\ngot:\n%q", want, moduleStrings)
 	}
 }
+
+func TestFinalDepsPhase(t *testing.T) {
+	ctx := NewTestContext()
+
+	finalGot := map[string]int{}
+
+	dep1Tag := struct {
+		blueprint.BaseDependencyTag
+	}{}
+	dep2Tag := struct {
+		blueprint.BaseDependencyTag
+	}{}
+
+	ctx.PostDepsMutators(func(ctx RegisterMutatorsContext) {
+		ctx.BottomUp("far_deps_1", func(ctx BottomUpMutatorContext) {
+			if !strings.HasPrefix(ctx.ModuleName(), "common_dep") {
+				ctx.AddFarVariationDependencies([]blueprint.Variation{}, dep1Tag, "common_dep_1")
+			}
+		})
+		ctx.BottomUp("variant", func(ctx BottomUpMutatorContext) {
+			ctx.CreateLocalVariations("a", "b")
+		})
+	})
+
+	ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) {
+		ctx.BottomUp("far_deps_2", func(ctx BottomUpMutatorContext) {
+			if !strings.HasPrefix(ctx.ModuleName(), "common_dep") {
+				ctx.AddFarVariationDependencies([]blueprint.Variation{}, dep2Tag, "common_dep_2")
+			}
+		})
+		ctx.BottomUp("final", func(ctx BottomUpMutatorContext) {
+			finalGot[ctx.Module().String()] += 1
+			ctx.VisitDirectDeps(func(mod Module) {
+				finalGot[fmt.Sprintf("%s -> %s", ctx.Module().String(), mod)] += 1
+			})
+		})
+	})
+
+	ctx.RegisterModuleType("test", mutatorTestModuleFactory)
+
+	bp := `
+		test {
+			name: "common_dep_1",
+		}
+		test {
+			name: "common_dep_2",
+		}
+		test {
+			name: "foo",
+		}
+	`
+
+	config := TestConfig(buildDir, nil, bp, nil)
+	ctx.Register(config)
+
+	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
+	FailIfErrored(t, errs)
+	_, errs = ctx.PrepareBuildActions(config)
+	FailIfErrored(t, errs)
+
+	finalWant := map[string]int{
+		"common_dep_1{variant:a}":                   1,
+		"common_dep_1{variant:b}":                   1,
+		"common_dep_2{variant:a}":                   1,
+		"common_dep_2{variant:b}":                   1,
+		"foo{variant:a}":                            1,
+		"foo{variant:a} -> common_dep_1{variant:a}": 1,
+		"foo{variant:a} -> common_dep_2{variant:a}": 1,
+		"foo{variant:b}":                            1,
+		"foo{variant:b} -> common_dep_1{variant:b}": 1,
+		"foo{variant:b} -> common_dep_2{variant:a}": 1,
+	}
+
+	if !reflect.DeepEqual(finalWant, finalGot) {
+		t.Errorf("want:\n%q\ngot:\n%q", finalWant, finalGot)
+	}
+}
+
+func TestNoCreateVariationsInFinalDeps(t *testing.T) {
+	ctx := NewTestContext()
+
+	checkErr := func() {
+		if err := recover(); err == nil || !strings.Contains(fmt.Sprintf("%s", err), "not allowed in FinalDepsMutators") {
+			panic("Expected FinalDepsMutators consistency check to fail")
+		}
+	}
+
+	ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) {
+		ctx.BottomUp("vars", func(ctx BottomUpMutatorContext) {
+			defer checkErr()
+			ctx.CreateVariations("a", "b")
+		})
+		ctx.BottomUp("local_vars", func(ctx BottomUpMutatorContext) {
+			defer checkErr()
+			ctx.CreateLocalVariations("a", "b")
+		})
+	})
+
+	ctx.RegisterModuleType("test", mutatorTestModuleFactory)
+	config := TestConfig(buildDir, nil, `test {name: "foo"}`, nil)
+	ctx.Register(config)
+
+	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
+	FailIfErrored(t, errs)
+	_, errs = ctx.PrepareBuildActions(config)
+	FailIfErrored(t, errs)
+}
diff --git a/android/override_module.go b/android/override_module.go
index 5bc787b..9f5127d 100644
--- a/android/override_module.go
+++ b/android/override_module.go
@@ -121,13 +121,13 @@
 	// override information is propagated and aggregated correctly.
 	overridesProperty *[]string
 
-	properties overridableModuleProperties
+	overridableModuleProperties overridableModuleProperties
 }
 
 func InitOverridableModule(m OverridableModule, overridesProperty *[]string) {
 	m.setOverridableProperties(m.(Module).GetProperties())
 	m.setOverridesProperty(overridesProperty)
-	m.AddProperties(&m.moduleBase().properties)
+	m.AddProperties(&m.moduleBase().overridableModuleProperties)
 }
 
 func (o *OverridableModuleBase) moduleBase() *OverridableModuleBase {
@@ -174,7 +174,7 @@
 	if b.overridesProperty != nil {
 		*b.overridesProperty = append(*b.overridesProperty, ctx.ModuleName())
 	}
-	b.properties.OverriddenBy = o.Name()
+	b.overridableModuleProperties.OverriddenBy = o.Name()
 }
 
 // GetOverriddenBy returns the name of the override module that has overridden this module.
@@ -182,7 +182,7 @@
 // of bar is created and its properties are overriden by foo. This method returns bar when called from
 // the new local variant. It returns "" when called from the original variant of bar.
 func (b *OverridableModuleBase) GetOverriddenBy() string {
-	return b.properties.OverriddenBy
+	return b.overridableModuleProperties.OverriddenBy
 }
 
 func (b *OverridableModuleBase) OverridablePropertiesDepsMutator(ctx BottomUpMutatorContext) {
diff --git a/android/package.go b/android/package.go
index ed604c6..077c4a4 100644
--- a/android/package.go
+++ b/android/package.go
@@ -22,7 +22,19 @@
 )
 
 func init() {
-	RegisterModuleType("package", PackageFactory)
+	RegisterPackageBuildComponents(InitRegistrationContext)
+}
+
+// Register the package module type and supporting mutators.
+//
+// This must be called in the correct order (relative to other methods that also
+// register mutators) to match the order of mutator registration in mutator.go.
+// Failing to do so will result in an unrealistic test environment.
+func RegisterPackageBuildComponents(ctx RegistrationContext) {
+	ctx.RegisterModuleType("package", PackageFactory)
+
+	// Register mutators that are hard coded in to mutator.go.
+	ctx.HardCodedPreArchMutators(RegisterPackageRenamer)
 }
 
 // The information maintained about each package.
diff --git a/android/package_ctx.go b/android/package_ctx.go
index d3527fa..a228910 100644
--- a/android/package_ctx.go
+++ b/android/package_ctx.go
@@ -19,7 +19,6 @@
 	"strings"
 
 	"github.com/google/blueprint"
-	"github.com/google/blueprint/pathtools"
 )
 
 // PackageContext is a wrapper for blueprint.PackageContext that adds
@@ -60,10 +59,6 @@
 	e.pctx.AddNinjaFileDeps(deps...)
 }
 
-func (e *configErrorWrapper) Fs() pathtools.FileSystem {
-	return nil
-}
-
 type PackageVarContext interface {
 	PathContext
 	errorfContext
diff --git a/android/package_test.go b/android/package_test.go
index bc66928..4710e39 100644
--- a/android/package_test.go
+++ b/android/package_test.go
@@ -87,8 +87,7 @@
 	config := TestArchConfig(buildDir, nil, "", fs)
 
 	ctx := NewTestArchContext()
-	ctx.RegisterModuleType("package", PackageFactory)
-	ctx.PreArchMutators(RegisterPackageRenamer)
+	RegisterPackageBuildComponents(ctx)
 	ctx.Register(config)
 
 	_, errs := ctx.ParseBlueprintsFiles(".")
diff --git a/android/paths.go b/android/paths.go
index a03fe17..02f56d0 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -16,6 +16,8 @@
 
 import (
 	"fmt"
+	"io/ioutil"
+	"os"
 	"path/filepath"
 	"reflect"
 	"sort"
@@ -25,10 +27,11 @@
 	"github.com/google/blueprint/pathtools"
 )
 
+var absSrcDir string
+
 // PathContext is the subset of a (Module|Singleton)Context required by the
 // Path methods.
 type PathContext interface {
-	Fs() pathtools.FileSystem
 	Config() Config
 	AddNinjaFileDeps(deps ...string)
 }
@@ -390,7 +393,7 @@
 		return PathsWithModuleSrcSubDir(ctx, paths, ""), nil
 	} else {
 		p := pathForModuleSrc(ctx, s)
-		if exists, _, err := ctx.Fs().Exists(p.String()); err != nil {
+		if exists, _, err := ctx.Config().fs.Exists(p.String()); err != nil {
 			reportPathErrorf(ctx, "%s: %s", p, err.Error())
 		} else if !exists {
 			reportPathErrorf(ctx, "module source path %q does not exist", p)
@@ -720,7 +723,7 @@
 		var deps []string
 		// We cannot add build statements in this context, so we fall back to
 		// AddNinjaFileDeps
-		files, deps, err = pathtools.Glob(path.String(), nil, pathtools.FollowSymlinks)
+		files, deps, err = ctx.Config().fs.Glob(path.String(), nil, pathtools.FollowSymlinks)
 		ctx.AddNinjaFileDeps(deps...)
 	}
 
@@ -752,7 +755,7 @@
 		if !exists {
 			modCtx.AddMissingDependencies([]string{path.String()})
 		}
-	} else if exists, _, err := ctx.Fs().Exists(path.String()); err != nil {
+	} else if exists, _, err := ctx.Config().fs.Exists(path.String()); err != nil {
 		reportPathErrorf(ctx, "%s: %s", path, err.Error())
 	} else if !exists {
 		reportPathErrorf(ctx, "source path %q does not exist", path)
@@ -1356,7 +1359,6 @@
 	config Config
 }
 
-func (x *testPathContext) Fs() pathtools.FileSystem   { return x.config.fs }
 func (x *testPathContext) Config() Config             { return x.config }
 func (x *testPathContext) AddNinjaFileDeps(...string) {}
 
@@ -1402,3 +1404,16 @@
 	}
 	return rel, true, nil
 }
+
+// Writes a file to the output directory.  Attempting to write directly to the output directory
+// will fail due to the sandbox of the soong_build process.
+func WriteFileToOutputDir(path WritablePath, data []byte, perm os.FileMode) error {
+	return ioutil.WriteFile(absolutePath(path.String()), data, perm)
+}
+
+func absolutePath(path string) string {
+	if filepath.IsAbs(path) {
+		return path
+	}
+	return filepath.Join(absSrcDir, path)
+}
diff --git a/android/paths_test.go b/android/paths_test.go
index ec5e598..46e3e1f 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -21,7 +21,6 @@
 	"strings"
 	"testing"
 
-	"github.com/google/blueprint/pathtools"
 	"github.com/google/blueprint/proptools"
 )
 
@@ -207,10 +206,6 @@
 	inRoot         bool
 }
 
-func (moduleInstallPathContextImpl) Fs() pathtools.FileSystem {
-	return pathtools.MockFs(nil)
-}
-
 func (m moduleInstallPathContextImpl) Config() Config {
 	return m.baseModuleContext.config
 }
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 2c99f1f..c780cb2 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -36,6 +36,9 @@
 
 var PrebuiltDepTag prebuiltDependencyTag
 
+// Mark this tag so dependencies that use it are excluded from visibility enforcement.
+func (t prebuiltDependencyTag) ExcludeFromVisibilityEnforcement() {}
+
 type PrebuiltProperties struct {
 	// When prefer is set to true the prebuilt will be used instead of any source module with
 	// a matching name.
diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go
index 8648b93..8ff5c40 100644
--- a/android/prebuilt_test.go
+++ b/android/prebuilt_test.go
@@ -141,10 +141,8 @@
 			config := TestConfig(buildDir, nil, bp, fs)
 
 			ctx := NewTestContext()
-			RegisterPrebuiltMutators(ctx)
+			registerTestPrebuiltBuildComponents(ctx)
 			ctx.RegisterModuleType("filegroup", FileGroupFactory)
-			ctx.RegisterModuleType("prebuilt", newPrebuiltModule)
-			ctx.RegisterModuleType("source", newSourceModule)
 			ctx.Register(config)
 
 			_, errs := ctx.ParseBlueprintsFiles("Android.bp")
@@ -212,6 +210,13 @@
 	}
 }
 
+func registerTestPrebuiltBuildComponents(ctx RegistrationContext) {
+	ctx.RegisterModuleType("prebuilt", newPrebuiltModule)
+	ctx.RegisterModuleType("source", newSourceModule)
+
+	RegisterPrebuiltMutators(ctx)
+}
+
 type prebuiltModule struct {
 	ModuleBase
 	prebuilt   Prebuilt
diff --git a/android/register.go b/android/register.go
index b5defec..ccfe01e 100644
--- a/android/register.go
+++ b/android/register.go
@@ -84,7 +84,9 @@
 }
 
 func NewContext() *Context {
-	return &Context{blueprint.NewContext()}
+	ctx := &Context{blueprint.NewContext()}
+	ctx.SetSrcDir(absSrcDir)
+	return ctx
 }
 
 func (ctx *Context) Register() {
@@ -100,7 +102,7 @@
 		ctx.RegisterSingletonType(t.name, t.factory)
 	}
 
-	registerMutators(ctx.Context, preArch, preDeps, postDeps)
+	registerMutators(ctx.Context, preArch, preDeps, postDeps, finalDeps)
 
 	// Register makevars after other singletons so they can export values through makevars
 	ctx.RegisterSingletonType("makevars", SingletonFactoryAdaptor(makeVarsSingletonFunc))
@@ -125,8 +127,15 @@
 	RegisterModuleType(name string, factory ModuleFactory)
 	RegisterSingletonType(name string, factory SingletonFactory)
 	PreArchMutators(f RegisterMutatorFunc)
+
+	// Register pre arch mutators that are hard coded into mutator.go.
+	//
+	// Only registers mutators for testing, is a noop on the InitRegistrationContext.
+	HardCodedPreArchMutators(f RegisterMutatorFunc)
+
 	PreDepsMutators(f RegisterMutatorFunc)
 	PostDepsMutators(f RegisterMutatorFunc)
+	FinalDepsMutators(f RegisterMutatorFunc)
 }
 
 // Used to register build components from an init() method, e.g.
@@ -178,6 +187,10 @@
 	PreArchMutators(f)
 }
 
+func (ctx *initRegistrationContext) HardCodedPreArchMutators(f RegisterMutatorFunc) {
+	// Nothing to do as the mutators are hard code in preArch in mutator.go
+}
+
 func (ctx *initRegistrationContext) PreDepsMutators(f RegisterMutatorFunc) {
 	PreDepsMutators(f)
 }
@@ -185,3 +198,7 @@
 func (ctx *initRegistrationContext) PostDepsMutators(f RegisterMutatorFunc) {
 	PostDepsMutators(f)
 }
+
+func (ctx *initRegistrationContext) FinalDepsMutators(f RegisterMutatorFunc) {
+	FinalDepsMutators(f)
+}
diff --git a/android/sandbox.go b/android/sandbox.go
new file mode 100644
index 0000000..ed022fb
--- /dev/null
+++ b/android/sandbox.go
@@ -0,0 +1,47 @@
+// Copyright 2020 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android
+
+import (
+	"fmt"
+	"os"
+)
+
+func init() {
+	// Stash the working directory in a private variable and then change the working directory
+	// to "/", which will prevent untracked accesses to files by Go Soong plugins. The
+	// SOONG_SANDBOX_SOONG_BUILD environment variable is set by soong_ui, and is not
+	// overrideable on the command line.
+
+	orig, err := os.Getwd()
+	if err != nil {
+		panic(fmt.Errorf("failed to get working directory: %s", err))
+	}
+	absSrcDir = orig
+
+	if getenv("SOONG_SANDBOX_SOONG_BUILD") == "true" {
+		err = os.Chdir("/")
+		if err != nil {
+			panic(fmt.Errorf("failed to change working directory to '/': %s", err))
+		}
+	}
+}
+
+// DO NOT USE THIS FUNCTION IN NEW CODE.
+// Deprecated: This function will be removed as soon as the existing use cases that use it have been
+// replaced.
+func AbsSrcDirForExistingUseCases() string {
+	return absSrcDir
+}
diff --git a/android/singleton.go b/android/singleton.go
index 5519ca0..91268ad 100644
--- a/android/singleton.go
+++ b/android/singleton.go
@@ -16,7 +16,6 @@
 
 import (
 	"github.com/google/blueprint"
-	"github.com/google/blueprint/pathtools"
 )
 
 // SingletonContext
@@ -74,8 +73,6 @@
 	// builder whenever a file matching the pattern as added or removed, without rerunning if a
 	// file that does not match the pattern is added to a searched directory.
 	GlobWithDeps(pattern string, excludes []string) ([]string, error)
-
-	Fs() pathtools.FileSystem
 }
 
 type singletonAdaptor struct {
diff --git a/android/testing.go b/android/testing.go
index 6663728..9aff039 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -50,15 +50,20 @@
 
 type TestContext struct {
 	*Context
-	preArch, preDeps, postDeps []RegisterMutatorFunc
-	NameResolver               *NameResolver
-	config                     Config
+	preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc
+	NameResolver                          *NameResolver
+	config                                Config
 }
 
 func (ctx *TestContext) PreArchMutators(f RegisterMutatorFunc) {
 	ctx.preArch = append(ctx.preArch, f)
 }
 
+func (ctx *TestContext) HardCodedPreArchMutators(f RegisterMutatorFunc) {
+	// Register mutator function as normal for testing.
+	ctx.PreArchMutators(f)
+}
+
 func (ctx *TestContext) PreDepsMutators(f RegisterMutatorFunc) {
 	ctx.preDeps = append(ctx.preDeps, f)
 }
@@ -67,12 +72,16 @@
 	ctx.postDeps = append(ctx.postDeps, f)
 }
 
+func (ctx *TestContext) FinalDepsMutators(f RegisterMutatorFunc) {
+	ctx.finalDeps = append(ctx.finalDeps, f)
+}
+
 func (ctx *TestContext) Register(config Config) {
 	ctx.SetFs(config.fs)
 	if config.mockBpList != "" {
 		ctx.SetModuleListFile(config.mockBpList)
 	}
-	registerMutators(ctx.Context.Context, ctx.preArch, ctx.preDeps, ctx.postDeps)
+	registerMutators(ctx.Context.Context, ctx.preArch, ctx.preDeps, ctx.postDeps, ctx.finalDeps)
 
 	ctx.RegisterSingletonType("env", EnvSingleton)
 
diff --git a/android/visibility.go b/android/visibility.go
index c28ec93..a597687 100644
--- a/android/visibility.go
+++ b/android/visibility.go
@@ -19,6 +19,8 @@
 	"regexp"
 	"strings"
 	"sync"
+
+	"github.com/google/blueprint"
 )
 
 // Enforces visibility rules between modules.
@@ -190,6 +192,15 @@
 	}).(*sync.Map)
 }
 
+// Marker interface that identifies dependencies that are excluded from visibility
+// enforcement.
+type ExcludeFromVisibilityEnforcementTag interface {
+	blueprint.DependencyTag
+
+	// Method that differentiates this interface from others.
+	ExcludeFromVisibilityEnforcement()
+}
+
 // The rule checker needs to be registered before defaults expansion to correctly check that
 // //visibility:xxx isn't combined with other packages in the same list in any one module.
 func RegisterVisibilityRuleChecker(ctx RegisterMutatorsContext) {
@@ -389,6 +400,12 @@
 
 	// Visit all the dependencies making sure that this module has access to them all.
 	ctx.VisitDirectDeps(func(dep Module) {
+		// Ignore dependencies that have an ExcludeFromVisibilityEnforcementTag
+		tag := ctx.OtherModuleDependencyTag(dep)
+		if _, ok := tag.(ExcludeFromVisibilityEnforcementTag); ok {
+			return
+		}
+
 		depName := ctx.OtherModuleName(dep)
 		depDir := ctx.OtherModuleDir(dep)
 		depQualified := qualifiedModuleName{depDir, depName}
diff --git a/android/visibility_test.go b/android/visibility_test.go
index fbf2fb7..6006072 100644
--- a/android/visibility_test.go
+++ b/android/visibility_test.go
@@ -853,6 +853,51 @@
 				` not visible to this module`,
 		},
 	},
+	{
+		name: "verify that prebuilt dependencies are ignored for visibility reasons (not preferred)",
+		fs: map[string][]byte{
+			"prebuilts/Blueprints": []byte(`
+				prebuilt {
+					name: "module",
+					visibility: ["//top/other"],
+				}`),
+			"top/sources/source_file": nil,
+			"top/sources/Blueprints": []byte(`
+				source {
+					name: "module",
+					visibility: ["//top/other"],
+				}`),
+			"top/other/source_file": nil,
+			"top/other/Blueprints": []byte(`
+				source {
+					name: "other",
+					deps: [":module"],
+				}`),
+		},
+	},
+	{
+		name: "verify that prebuilt dependencies are ignored for visibility reasons (preferred)",
+		fs: map[string][]byte{
+			"prebuilts/Blueprints": []byte(`
+				prebuilt {
+					name: "module",
+					visibility: ["//top/other"],
+					prefer: true,
+				}`),
+			"top/sources/source_file": nil,
+			"top/sources/Blueprints": []byte(`
+				source {
+					name: "module",
+					visibility: ["//top/other"],
+				}`),
+			"top/other/source_file": nil,
+			"top/other/Blueprints": []byte(`
+				source {
+					name: "other",
+					deps: [":module"],
+				}`),
+		},
+	},
 }
 
 func TestVisibility(t *testing.T) {
@@ -871,10 +916,12 @@
 	config := TestArchConfig(buildDir, nil, "", fs)
 
 	ctx := NewTestArchContext()
-	ctx.RegisterModuleType("package", PackageFactory)
 	ctx.RegisterModuleType("mock_library", newMockLibraryModule)
 	ctx.RegisterModuleType("mock_defaults", defaultsFactory)
-	ctx.PreArchMutators(RegisterPackageRenamer)
+
+	// Order of the following method calls is significant.
+	RegisterPackageBuildComponents(ctx)
+	registerTestPrebuiltBuildComponents(ctx)
 	ctx.PreArchMutators(RegisterVisibilityRuleChecker)
 	ctx.PreArchMutators(RegisterDefaultsPreArchMutators)
 	ctx.PreArchMutators(RegisterVisibilityRuleGatherer)
diff --git a/androidmk/Android.bp b/androidmk/Android.bp
index 4110073..70fc1f7 100644
--- a/androidmk/Android.bp
+++ b/androidmk/Android.bp
@@ -41,7 +41,6 @@
         "androidmk-parser",
         "blueprint-parser",
         "bpfix-lib",
-        "soong-android",
     ],
 }
 
diff --git a/androidmk/androidmk/android.go b/androidmk/androidmk/android.go
index 0082d8b..8860984 100644
--- a/androidmk/androidmk/android.go
+++ b/androidmk/androidmk/android.go
@@ -15,9 +15,9 @@
 package androidmk
 
 import (
-	"android/soong/android"
 	mkparser "android/soong/androidmk/parser"
 	"fmt"
+	"sort"
 	"strings"
 
 	bpparser "github.com/google/blueprint/parser"
@@ -350,7 +350,13 @@
 		return err
 	}
 
-	for _, nameClassification := range android.SortedStringKeys(namesByClassification) {
+	var classifications []string
+	for classification := range namesByClassification {
+		classifications = append(classifications, classification)
+	}
+	sort.Strings(classifications)
+
+	for _, nameClassification := range classifications {
 		name := namesByClassification[nameClassification]
 		if component, ok := lists[nameClassification]; ok && !emptyList(component) {
 			err = setVariable(ctx.file, ctx.append, ctx.prefix, name, component, true)
diff --git a/apex/androidmk.go b/apex/androidmk.go
index 9aa0894..ad7d2f1 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -117,6 +117,9 @@
 				fmt.Fprintln(w, "LOCAL_IS_HOST_MODULE := true")
 			}
 		}
+		if fi.jacocoReportClassesFile != nil {
+			fmt.Fprintln(w, "LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR :=", fi.jacocoReportClassesFile.String())
+		}
 		if fi.class == javaSharedLib {
 			javaModule := fi.module.(javaLibrary)
 			// soong_java_prebuilt.mk sets LOCAL_MODULE_SUFFIX := .jar  Therefore
@@ -128,6 +131,12 @@
 			fmt.Fprintln(w, "LOCAL_SOONG_DEX_JAR :=", fi.builtFile.String())
 			fmt.Fprintln(w, "LOCAL_DEX_PREOPT := false")
 			fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_java_prebuilt.mk")
+		} else if fi.class == app {
+			// soong_app_prebuilt.mk sets LOCAL_MODULE_SUFFIX := .apk  Therefore
+			// we need to remove the suffix from LOCAL_MODULE_STEM, otherwise
+			// we will have foo.apk.apk
+			fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", strings.TrimSuffix(fi.builtFile.Base(), ".apk"))
+			fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_app_prebuilt.mk")
 		} else if fi.class == nativeSharedLib || fi.class == nativeExecutable || fi.class == nativeTest {
 			fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", fi.builtFile.Base())
 			if cc, ok := fi.module.(*cc.Module); ok {
@@ -142,9 +151,19 @@
 			fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_cc_prebuilt.mk")
 		} else {
 			fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", fi.builtFile.Base())
-			// For flattened apexes, compat symlinks are attached to apex_manifest.json which is guaranteed for every apex
-			if a.primaryApexType && fi.builtFile == a.manifestPbOut && len(a.compatSymlinks) > 0 {
-				fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD :=", strings.Join(a.compatSymlinks, " && "))
+			if a.primaryApexType && fi.builtFile == a.manifestPbOut {
+				// Make apex_manifest.pb module for this APEX to override all other
+				// modules in the APEXes being overridden by this APEX
+				var patterns []string
+				for _, o := range a.overridableProperties.Overrides {
+					patterns = append(patterns, "%."+o+a.suffix)
+				}
+				fmt.Fprintln(w, "LOCAL_OVERRIDES_MODULES :=", strings.Join(patterns, " "))
+
+				if len(a.compatSymlinks) > 0 {
+					// For flattened apexes, compat symlinks are attached to apex_manifest.json which is guaranteed for every apex
+					fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD :=", strings.Join(a.compatSymlinks, " && "))
+				}
 			}
 			fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
 		}
@@ -207,8 +226,8 @@
 				if len(moduleNames) > 0 {
 					fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES +=", strings.Join(moduleNames, " "))
 				}
-				if len(a.externalDeps) > 0 {
-					fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES +=", strings.Join(a.externalDeps, " "))
+				if len(a.requiredDeps) > 0 {
+					fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES +=", strings.Join(a.requiredDeps, " "))
 				}
 				a.writeRequiredModules(w)
 				var postInstallCommands []string
@@ -226,6 +245,14 @@
 				if apexType == imageApex {
 					fmt.Fprintln(w, "ALL_MODULES.$(LOCAL_MODULE).BUNDLE :=", a.bundleModuleFile.String())
 				}
+
+				if a.installedFilesFile != nil {
+					goal := "droidcore"
+					distFile := name + "-installed-files.txt"
+					fmt.Fprintln(w, ".PHONY:", goal)
+					fmt.Fprintf(w, "$(call dist-for-goals,%s,%s:%s)\n",
+						goal, a.installedFilesFile.String(), distFile)
+				}
 			}
 		}}
 }
diff --git a/apex/apex.go b/apex/apex.go
index eb96142..33b1be3 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -57,8 +57,249 @@
 	certificateTag = dependencyTag{name: "certificate"}
 	usesTag        = dependencyTag{name: "uses"}
 	androidAppTag  = dependencyTag{name: "androidApp"}
+	apexAvailWl    = makeApexAvailableWhitelist()
 )
 
+// This is a map from apex to modules, which overrides the
+// apex_available setting for that particular module to make
+// it available for the apex regardless of its setting.
+// TODO(b/147364041): remove this
+func makeApexAvailableWhitelist() map[string][]string {
+	// The "Module separator"s below are employed to minimize merge conflicts.
+	m := make(map[string][]string)
+	//
+	// Module separator
+	//
+	m["com.android.adbd"] = []string{"adbd", "libcrypto"}
+	//
+	// Module separator
+	//
+	m["com.android.art"] = []string{
+		"jacocoagent",
+		"libadbconnection_server",
+		"libartd-disassembler",
+		"libbacktrace",
+		"libbase",
+		"libc++",
+		"libcrypto",
+		"libdexfile_support",
+		"libexpat",
+		"libicuuc",
+		"liblzma",
+		"libmeminfo",
+		"libprocinfo",
+		"libunwindstack",
+		"libvixl",
+		"libvixld",
+		"libz",
+		"libziparchive",
+		"prebuilt_libclang_rt",
+	}
+	//
+	// Module separator
+	//
+	m["com.android.bluetooth.updatable"] = []string{
+		"android.hardware.audio.common@5.0",
+		"android.hardware.bluetooth@1.0",
+		"android.hardware.bluetooth@1.1",
+		"android.hardware.bluetooth.a2dp@1.0",
+		"android.hardware.bluetooth.audio@2.0",
+		"android.hidl.safe_union@1.0",
+		"libbase",
+		"libbinderthreadstate",
+		"libbluetooth",
+		"libbluetooth_jni",
+		"libc++",
+		"libchrome",
+		"libcrypto",
+		"libcutils",
+		"libevent",
+		"libfmq",
+		"libhidlbase",
+		"libprocessgroup",
+		"libprotobuf-cpp-lite",
+		"libstatslog",
+		"libtinyxml2",
+		"libutils",
+		"libz",
+	}
+	//
+	// Module separator
+	//
+	m["com.android.conscrypt"] = []string{"boringssl_self_test", "libc++", "libcrypto", "libssl"}
+	//
+	// Module separator
+	//
+	m["com.android.cronet"] = []string{"org.chromium.net.cronet", "prebuilt_libcronet.80.0.3986.0"}
+	//
+	// Module separator
+	//
+	m["com.android.media"] = []string{
+		"android.hardware.cas@1.0",
+		"android.hardware.cas.native@1.0",
+		"android.hidl.allocator@1.0",
+		"android.hidl.memory@1.0",
+		"android.hidl.memory.token@1.0",
+		"android.hidl.token@1.0",
+		"android.hidl.token@1.0-utils",
+		"libaacextractor",
+		"libamrextractor",
+		"libbase",
+		"libbinderthreadstate",
+		"libc++",
+		"libcrypto",
+		"libcutils",
+		"libflacextractor",
+		"libhidlbase",
+		"libhidlmemory",
+		"libmidiextractor",
+		"libmkvextractor",
+		"libmp3extractor",
+		"libmp4extractor",
+		"libmpeg2extractor",
+		"liboggextractor",
+		"libprocessgroup",
+		"libutils",
+		"libwavextractor",
+		"updatable-media",
+	}
+	//
+	// Module separator
+	//
+	m["com.android.media.swcodec"] = []string{
+		"android.frameworks.bufferhub@1.0",
+		"android.hardware.configstore@1.0",
+		"android.hardware.configstore@1.1",
+		"android.hardware.configstore-utils",
+		"android.hardware.graphics.allocator@2.0",
+		"android.hardware.graphics.allocator@3.0",
+		"android.hardware.graphics.bufferqueue@1.0",
+		"android.hardware.graphics.bufferqueue@2.0",
+		"android.hardware.graphics.common@1.0",
+		"android.hardware.graphics.common@1.1",
+		"android.hardware.graphics.common@1.2",
+		"android.hardware.graphics.mapper@2.0",
+		"android.hardware.graphics.mapper@2.1",
+		"android.hardware.graphics.mapper@3.0",
+		"android.hardware.media@1.0",
+		"android.hardware.media.bufferpool@2.0",
+		"android.hardware.media.c2@1.0",
+		"android.hardware.media.omx@1.0",
+		"android.hidl.memory@1.0",
+		"android.hidl.memory.token@1.0",
+		"android.hidl.safe_union@1.0",
+		"android.hidl.token@1.0",
+		"android.hidl.token@1.0-utils",
+		"libavservices_minijail",
+		"libbacktrace",
+		"libbase",
+		"libbinderthreadstate",
+		"libc++",
+		"libcap",
+		"libcodec2",
+		"libcodec2_hidl@1.0",
+		"libcodec2_soft_aacdec",
+		"libcodec2_soft_aacenc",
+		"libcodec2_soft_amrnbdec",
+		"libcodec2_soft_amrnbenc",
+		"libcodec2_soft_amrwbdec",
+		"libcodec2_soft_amrwbenc",
+		"libcodec2_soft_av1dec_gav1",
+		"libcodec2_soft_avcdec",
+		"libcodec2_soft_avcenc",
+		"libcodec2_soft_common",
+		"libcodec2_soft_flacdec",
+		"libcodec2_soft_flacenc",
+		"libcodec2_soft_g711alawdec",
+		"libcodec2_soft_g711mlawdec",
+		"libcodec2_soft_gsmdec",
+		"libcodec2_soft_h263dec",
+		"libcodec2_soft_h263enc",
+		"libcodec2_soft_hevcdec",
+		"libcodec2_soft_hevcenc",
+		"libcodec2_soft_mp3dec",
+		"libcodec2_soft_mpeg2dec",
+		"libcodec2_soft_mpeg4dec",
+		"libcodec2_soft_mpeg4enc",
+		"libcodec2_soft_opusdec",
+		"libcodec2_soft_opusenc",
+		"libcodec2_soft_rawdec",
+		"libcodec2_soft_vorbisdec",
+		"libcodec2_soft_vp8dec",
+		"libcodec2_soft_vp8enc",
+		"libcodec2_soft_vp9dec",
+		"libcodec2_soft_vp9enc",
+		"libcodec2_vndk",
+		"libc_scudo",
+		"libcutils",
+		"libdexfile_support",
+		"libEGL",
+		"libfmq",
+		"libgraphicsenv",
+		"libhardware",
+		"libhidlbase",
+		"libhidlmemory",
+		"libion",
+		"liblzma",
+		"libmedia_codecserviceregistrant",
+		"libminijail",
+		"libnativebridge_lazy",
+		"libnativeloader_lazy",
+		"libopus",
+		"libprocessgroup",
+		"libscudo_wrapper",
+		"libsfplugin_ccodec_utils",
+		"libstagefright_amrnb_common",
+		"libstagefright_bufferpool@2.0.1",
+		"libstagefright_bufferqueue_helper",
+		"libstagefright_enc_common",
+		"libstagefright_flacdec",
+		"libstagefright_foundation",
+		"libsync",
+		"libui",
+		"libunwindstack",
+		"libutils",
+		"libvorbisidec",
+		"libvpx",
+		"mediaswcodec",
+		"prebuilt_libclang_rt",
+	}
+	//
+	// Module separator
+	//
+	m["com.android.runtime"] = []string{
+		"libbase",
+		"libc++",
+		"libdexfile_support",
+		"liblzma",
+		"libunwindstack",
+		"prebuilt_libclang_rt",
+	}
+	//
+	// Module separator
+	//
+	m["com.android.resolv"] = []string{"libcrypto", "libnetd_resolv", "libssl"}
+	//
+	// Module separator
+	//
+	m["com.android.tethering"] = []string{"libbase", "libc++", "libnativehelper_compat_libc++"}
+	//
+	// Module separator
+	//
+	m["com.android.vndk"] = []string{
+		"libbacktrace",
+		"libbinderthreadstate",
+		"libblas",
+		"libcompiler_rt",
+		"libgui",
+		"libunwind",
+	}
+	//
+	// Module separator
+	//
+	return m
+}
+
 func init() {
 	android.RegisterModuleType("apex", BundleFactory)
 	android.RegisterModuleType("apex_test", testApexBundleFactory)
@@ -341,6 +582,8 @@
 	// Whether this APEX should support Android10. Default is false. If this is set true, then apex_manifest.json is bundled as well
 	// because Android10 requires legacy apex_manifest.json instead of apex_manifest.pb
 	Legacy_android10_support *bool
+
+	IsCoverageVariant bool `blueprint:"mutated"`
 }
 
 type apexTargetBundleProperties struct {
@@ -465,6 +708,8 @@
 	requiredModuleNames       []string
 	targetRequiredModuleNames []string
 	hostRequiredModuleNames   []string
+
+	jacocoReportClassesFile android.Path // only for javalibs and apps
 }
 
 func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, moduleName string, installDir string, class apexFileClass, module android.Module) apexFile {
@@ -518,8 +763,13 @@
 	// list of files to be included in this apex
 	filesInfo []apexFile
 
-	// list of module names that this APEX is depending on
+	// list of module names that should be installed along with this APEX
+	requiredDeps []string
+
+	// list of module names that this APEX is depending on (to be shown via *-deps-info target)
 	externalDeps []string
+	// list of module names that this APEX is including (to be shown via *-deps-info target)
+	internalDeps []string
 
 	testApex        bool
 	vndkApex        bool
@@ -529,15 +779,17 @@
 	manifestJsonOut android.WritablePath
 	manifestPbOut   android.WritablePath
 
-	// list of commands to create symlinks for backward compatibility
+	// list of commands to create symlinks for backward compatibility.
 	// these commands will be attached as LOCAL_POST_INSTALL_CMD to
-	// apex package itself(for unflattened build) or apex_manifest.json(for flattened build)
+	// apex package itself(for unflattened build) or apex_manifest(for flattened build)
 	// so that compat symlinks are always installed regardless of TARGET_FLATTEN_APEX setting.
 	compatSymlinks []string
 
 	// Suffix of module name in Android.mk
 	// ".flattened", ".apex", ".zipapex", or ""
 	suffix string
+
+	installedFilesFile android.WritablePath
 }
 
 func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext,
@@ -815,6 +1067,10 @@
 	a.properties.HideFromMake = true
 }
 
+func (a *apexBundle) MarkAsCoverageVariant(coverage bool) {
+	a.properties.IsCoverageVariant = coverage
+}
+
 // TODO(jiyong) move apexFileFor* close to the apexFile type definition
 func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod *cc.Module, handleSpecialLibs bool) apexFile {
 	// Decide the APEX-local directory by the multilib of the library
@@ -895,7 +1151,9 @@
 func apexFileForJavaLibrary(ctx android.BaseModuleContext, lib javaLibrary) apexFile {
 	dirInApex := "javalib"
 	fileToCopy := lib.DexJar()
-	return newApexFile(ctx, fileToCopy, lib.Name(), dirInApex, javaSharedLib, lib)
+	af := newApexFile(ctx, fileToCopy, lib.Name(), dirInApex, javaSharedLib, lib)
+	af.jacocoReportClassesFile = lib.JacocoReportClassesFile()
+	return af
 }
 
 func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt android.PrebuiltEtcModule, depName string) apexFile {
@@ -908,6 +1166,7 @@
 	android.Module
 	Privileged() bool
 	OutputFile() android.Path
+	JacocoReportClassesFile() android.Path
 }, pkgName string) apexFile {
 	appDir := "app"
 	if aapp.Privileged() {
@@ -915,7 +1174,9 @@
 	}
 	dirInApex := filepath.Join(appDir, pkgName)
 	fileToCopy := aapp.OutputFile()
-	return newApexFile(ctx, fileToCopy, aapp.Name(), dirInApex, app, aapp)
+	af := newApexFile(ctx, fileToCopy, aapp.Name(), dirInApex, app, aapp)
+	af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
+	return af
 }
 
 // Context "decorator", overriding the InstallBypassMake method to always reply `true`.
@@ -938,7 +1199,7 @@
 			a.primaryApexType = true
 
 			if ctx.Config().InstallExtraFlattenedApexes() {
-				a.externalDeps = append(a.externalDeps, a.Name()+flattenedSuffix)
+				a.requiredDeps = append(a.requiredDeps, a.Name()+flattenedSuffix)
 			}
 		}
 	case zipApex:
@@ -997,6 +1258,9 @@
 		depTag := ctx.OtherModuleDependencyTag(child)
 		depName := ctx.OtherModuleName(child)
 		if _, isDirectDep := parent.(*apexBundle); isDirectDep {
+			if depTag != keyTag && depTag != certificateTag {
+				a.internalDeps = append(a.internalDeps, depName)
+			}
 			switch depTag {
 			case sharedLibTag:
 				if cc, ok := child.(*cc.Module); ok {
@@ -1127,9 +1391,10 @@
 							//
 							// Always include if we are a host-apex however since those won't have any
 							// system libraries.
-							if !android.DirectlyInAnyApex(ctx, cc.Name()) && !android.InList(cc.Name(), a.externalDeps) {
-								a.externalDeps = append(a.externalDeps, cc.Name())
+							if !android.DirectlyInAnyApex(ctx, cc.Name()) && !android.InList(cc.Name(), a.requiredDeps) {
+								a.requiredDeps = append(a.requiredDeps, cc.Name())
 							}
+							a.externalDeps = append(a.externalDeps, depName)
 							requireNativeLibs = append(requireNativeLibs, cc.OutputFile().Path().Base())
 							// Don't track further
 							return false
@@ -1137,6 +1402,8 @@
 						af := apexFileForNativeLibrary(ctx, cc, handleSpecialLibs)
 						af.transitiveDep = true
 						filesInfo = append(filesInfo, af)
+						a.internalDeps = append(a.internalDeps, depName)
+						a.internalDeps = append(a.internalDeps, cc.AllStaticDeps()...)
 						return true // track transitive dependencies
 					}
 				} else if cc.IsTestPerSrcDepTag(depTag) {
@@ -1152,8 +1419,10 @@
 						return true // track transitive dependencies
 					}
 				} else if java.IsJniDepTag(depTag) {
-					// Do nothing for JNI dep. JNI libraries are always embedded in APK-in-APEX.
+					a.externalDeps = append(a.externalDeps, depName)
 					return true
+				} else if java.IsStaticLibDepTag(depTag) {
+					a.internalDeps = append(a.internalDeps, depName)
 				} else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
 					ctx.ModuleErrorf("unexpected tag %q for indirect dependency %q", depTag, depName)
 				}
@@ -1205,7 +1474,12 @@
 	if !ctx.Host() && !a.testApex {
 		for _, fi := range filesInfo {
 			if am, ok := fi.module.(android.ApexModule); ok {
-				if !am.AvailableFor(ctx.ModuleName()) {
+				// vndk {enabled:true} implies visibility to the vndk apex
+				if ccm, ok := fi.module.(*cc.Module); ok && ccm.IsVndk() && a.vndkApex {
+					continue
+				}
+
+				if !am.AvailableFor(ctx.ModuleName()) && !whitelistedApexAvailable(ctx.ModuleName(), a.vndkApex, fi.module) {
 					ctx.ModuleErrorf("requires %q that is not available for the APEX", fi.module.Name())
 					// don't stop so that we can report other violations in the same run
 				}
@@ -1249,8 +1523,28 @@
 		a.buildUnflattenedApex(ctx)
 	}
 
-	apexName := proptools.StringDefault(a.properties.Apex_name, a.Name())
-	a.compatSymlinks = makeCompatSymlinks(apexName, ctx)
+	a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx)
+
+	a.buildApexDependencyInfo(ctx)
+}
+
+func whitelistedApexAvailable(apex string, is_vndk bool, module android.Module) bool {
+	key := apex
+	key = strings.Replace(key, "test_", "", 1)
+	key = strings.Replace(key, "com.android.art.debug", "com.android.art", 1)
+	key = strings.Replace(key, "com.android.art.release", "com.android.art", 1)
+
+	moduleName := module.Name()
+	if strings.Contains(moduleName, "prebuilt_libclang_rt") {
+		// This module has variants that depend on the product being built.
+		moduleName = "prebuilt_libclang_rt"
+	}
+
+	if val, ok := apexAvailWl[key]; ok && android.InList(moduleName, val) {
+		return true
+	}
+
+	return false
 }
 
 func newApexBundle() *apexBundle {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index cc346e9..2103b6e 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -219,6 +219,7 @@
 		"apex_manifest.json":                                  nil,
 		"AndroidManifest.xml":                                 nil,
 		"system/sepolicy/apex/myapex-file_contexts":           nil,
+		"system/sepolicy/apex/myapex2-file_contexts":          nil,
 		"system/sepolicy/apex/otherapex-file_contexts":        nil,
 		"system/sepolicy/apex/commonapex-file_contexts":       nil,
 		"system/sepolicy/apex/com.android.vndk-file_contexts": nil,
@@ -287,7 +288,6 @@
 	ctx.RegisterModuleType("override_apex", overrideApexFactory)
 
 	cc.RegisterRequiredBuildComponentsForTest(ctx)
-	ctx.RegisterModuleType("cc_binary", cc.BinaryFactory)
 	ctx.RegisterModuleType("cc_test", cc.TestFactory)
 	ctx.RegisterModuleType("vndk_prebuilt_shared", cc.VndkPrebuiltSharedFactory)
 	ctx.RegisterModuleType("vndk_libraries_txt", cc.VndkLibrariesTxtFactory)
@@ -402,6 +402,11 @@
 			shared_libs: ["mylib2"],
 			system_shared_libs: [],
 			stl: "none",
+			// TODO: remove //apex_available:platform
+			apex_available: [
+				"//apex_available:platform",
+				"myapex",
+			],
 		}
 
 		cc_binary {
@@ -421,6 +426,7 @@
 			system_shared_libs: [],
 			static_executable: true,
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library {
@@ -429,6 +435,11 @@
 			system_shared_libs: [],
 			stl: "none",
 			notice: "custom_notice",
+			// TODO: remove //apex_available:platform
+			apex_available: [
+				"//apex_available:platform",
+				"myapex",
+			],
 		}
 
 		java_library {
@@ -439,6 +450,11 @@
 			compile_dex: true,
 			static_libs: ["myotherjar"],
 			libs: ["mysharedjar"],
+			// TODO: remove //apex_available:platform
+			apex_available: [
+				"//apex_available:platform",
+				"myapex",
+			],
 		}
 
 		java_library {
@@ -520,6 +536,12 @@
 	}
 	ensureListContains(t, noticeInputs, "NOTICE")
 	ensureListContains(t, noticeInputs, "custom_notice")
+
+	depsInfo := strings.Split(ctx.ModuleForTests("myapex", "android_common_myapex_image").Output("myapex-deps-info.txt").Args["content"], "\\n")
+	ensureListContains(t, depsInfo, "internal myjar")
+	ensureListContains(t, depsInfo, "internal mylib")
+	ensureListContains(t, depsInfo, "internal mylib2")
+	ensureListContains(t, depsInfo, "internal myotherjar")
 }
 
 func TestDefaults(t *testing.T) {
@@ -553,6 +575,7 @@
 			name: "mylib",
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		java_library {
@@ -561,6 +584,7 @@
 			sdk_version: "none",
 			system_modules: "none",
 			compile_dex: true,
+			apex_available: [ "myapex" ],
 		}
 
 		android_app {
@@ -568,6 +592,7 @@
 			srcs: ["foo/bar/MyClass.java"],
 			sdk_version: "none",
 			system_modules: "none",
+			apex_available: [ "myapex" ],
 		}
 	`)
 	ensureExactContents(t, ctx, "myapex", []string{
@@ -620,6 +645,7 @@
 			shared_libs: ["mylib2"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library {
@@ -627,6 +653,7 @@
 			srcs: ["mylib.cpp"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 	`)
 
@@ -667,6 +694,7 @@
 			shared_libs: ["mylib2", "mylib3"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library {
@@ -689,6 +717,7 @@
 			stubs: {
 				versions: ["10", "11", "12"],
 			},
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library {
@@ -696,6 +725,7 @@
 			srcs: ["mylib.cpp"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 	`)
 
@@ -740,13 +770,13 @@
 func TestApexWithExplicitStubsDependency(t *testing.T) {
 	ctx, _ := testApex(t, `
 		apex {
-			name: "myapex",
-			key: "myapex.key",
+			name: "myapex2",
+			key: "myapex2.key",
 			native_shared_libs: ["mylib"],
 		}
 
 		apex_key {
-			name: "myapex.key",
+			name: "myapex2.key",
 			public_key: "testkey.avbpubkey",
 			private_key: "testkey.pem",
 		}
@@ -757,6 +787,7 @@
 			shared_libs: ["libfoo#10"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex2" ],
 		}
 
 		cc_library {
@@ -779,7 +810,7 @@
 
 	`)
 
-	apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
+	apexRule := ctx.ModuleForTests("myapex2", "android_common_myapex2_image").Rule("apexRule")
 	copyCmds := apexRule.Args["copy_commands"]
 
 	// Ensure that direct non-stubs dep is always included
@@ -791,7 +822,7 @@
 	// Ensure that dependency of stubs is not included
 	ensureNotContains(t, copyCmds, "image.apex/lib64/libbar.so")
 
-	mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_myapex").Rule("ld").Args["libFlags"]
+	mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_myapex2").Rule("ld").Args["libFlags"]
 
 	// Ensure that mylib is linking with version 10 of libfoo
 	ensureContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_shared_10/libfoo.so")
@@ -802,6 +833,12 @@
 
 	// Ensure that libfoo stubs is not linking to libbar (since it is a stubs)
 	ensureNotContains(t, libFooStubsLdFlags, "libbar.so")
+
+	depsInfo := strings.Split(ctx.ModuleForTests("myapex2", "android_common_myapex2_image").Output("myapex2-deps-info.txt").Args["content"], "\\n")
+	ensureListContains(t, depsInfo, "internal mylib")
+	ensureListContains(t, depsInfo, "external libfoo")
+	ensureListNotContains(t, depsInfo, "internal libfoo")
+	ensureListNotContains(t, depsInfo, "external mylib")
 }
 
 func TestApexWithRuntimeLibsDependency(t *testing.T) {
@@ -832,6 +869,7 @@
 			runtime_libs: ["libfoo", "libbar"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library {
@@ -849,6 +887,7 @@
 			srcs: ["mylib.cpp"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 	`)
@@ -893,6 +932,7 @@
 			shared_libs: ["libbar"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library {
@@ -943,6 +983,7 @@
 			srcs: ["mylib.cpp"],
 			shared_libs: ["libdl#27"],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library_shared {
@@ -950,6 +991,7 @@
 			srcs: ["mylib.cpp"],
 			shared_libs: ["libdl#27"],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library {
@@ -972,6 +1014,10 @@
 			stubs: {
 				versions: ["27", "28", "29"],
 			},
+			apex_available: [
+				"//apex_available:platform",
+				"myapex"
+			],
 		}
 
 		cc_library {
@@ -983,6 +1029,10 @@
 			stubs: {
 				versions: ["27", "28", "29"],
 			},
+			apex_available: [
+				"//apex_available:platform",
+				"myapex"
+			],
 		}
 
 		cc_library {
@@ -1074,6 +1124,7 @@
 			relative_install_path: "foo/bar",
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		cc_binary {
@@ -1083,6 +1134,7 @@
 			system_shared_libs: [],
 			static_executable: true,
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 	`)
 
@@ -1127,6 +1179,7 @@
 			system_shared_libs: [],
 			vendor_available: true,
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library {
@@ -1135,6 +1188,7 @@
 			system_shared_libs: [],
 			vendor_available: true,
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 	`, func(fs map[string][]byte, config android.Config) {
 		setUseVendorWhitelistForTest(config, []string{"myapex"})
@@ -1235,6 +1289,10 @@
 			stubs: {
 				versions: ["1", "2", "3"],
 			},
+			apex_available: [
+				"//apex_available:platform",
+				"myapex",
+			],
 		}
 
 		cc_binary {
@@ -1268,6 +1326,7 @@
 			srcs: ["mylib.cpp"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex_keytest" ],
 		}
 
 		apex_key {
@@ -1461,6 +1520,12 @@
 			srcs: ["mylib.cpp"],
 			system_shared_libs: [],
 			stl: "none",
+			// TODO: remove //apex_available:platform
+			apex_available: [
+				"//apex_available:platform",
+				"myapex",
+				"otherapex",
+			],
 		}
 	`)
 
@@ -1514,6 +1579,7 @@
 			stubs: {
 				versions: ["1", "2", "3"],
 			},
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library {
@@ -1616,6 +1682,7 @@
 			},
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library {
@@ -1628,6 +1695,7 @@
 			},
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 	`+vndkLibrariesTxtFiles("current"))
 
@@ -1665,6 +1733,7 @@
 			},
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		cc_prebuilt_library_shared {
@@ -1682,6 +1751,7 @@
 			},
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 		`+vndkLibrariesTxtFiles("current"),
 		withFiles(map[string][]byte{
@@ -1752,6 +1822,7 @@
 					srcs: ["libvndk27_arm64.so"],
 				},
 			},
+			apex_available: [ "myapex_v27" ],
 		}
 
 		vndk_prebuilt_shared {
@@ -1888,6 +1959,7 @@
 			},
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 		`+vndkLibrariesTxtFiles("current"),
 		withTargets(map[android.OsType][]android.Target{
@@ -1980,6 +2052,7 @@
 					srcs: ["libvndk27binder32.so"],
 				}
 			},
+			apex_available: [ "myapex_v27" ],
 		}
 		`+vndkLibrariesTxtFiles("27"),
 		withFiles(map[string][]byte{
@@ -2045,6 +2118,7 @@
 			srcs: ["mylib.cpp"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex_nodep" ],
 		}
 
 		cc_library {
@@ -2053,6 +2127,11 @@
 			shared_libs: ["libfoo"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [
+				"myapex_dep",
+				"myapex_provider",
+				"myapex_selfcontained",
+			],
 		}
 
 		cc_library {
@@ -2063,6 +2142,10 @@
 			},
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [
+				"myapex_provider",
+				"myapex_selfcontained",
+			],
 		}
 	`)
 
@@ -2135,6 +2218,10 @@
 			srcs: ["mylib.cpp"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [
+					"//apex_available:platform",
+				  "myapex",
+		  ],
 		}
 	`)
 
@@ -2186,6 +2273,11 @@
 			srcs: ["mylib.cpp"],
 			system_shared_libs: [],
 			stl: "none",
+			// TODO: remove //apex_available:platform
+			apex_available: [
+				"//apex_available:platform",
+				"myapex",
+			],
 		}
 	`)
 
@@ -2254,6 +2346,11 @@
 			srcs: ["mylib.cpp"],
 			system_shared_libs: [],
 			stl: "none",
+			// TODO: remove //apex_available:platform
+			apex_available: [
+				"//apex_available:platform",
+				"myapex",
+			],
 		}
 
 		cc_library {
@@ -2262,6 +2359,11 @@
 			system_shared_libs: [],
 			stl: "none",
 			compile_multilib: "first",
+			// TODO: remove //apex_available:platform
+			apex_available: [
+				"//apex_available:platform",
+				"myapex",
+			],
 		}
 
 		cc_library {
@@ -2652,7 +2754,7 @@
 		config.TestProductVariables.InstallExtraFlattenedApexes = proptools.BoolPtr(true)
 	})
 	ab := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
-	ensureListContains(t, ab.externalDeps, "myapex.flattened")
+	ensureListContains(t, ab.requiredDeps, "myapex.flattened")
 	mk := android.AndroidMkDataForTest(t, config, "", ab)
 	var builder strings.Builder
 	mk.Custom(&builder, ab.Name(), "TARGET_", "", mk)
@@ -2688,6 +2790,7 @@
 			shared_libs: ["libcommon"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library {
@@ -2695,6 +2798,12 @@
 			srcs: ["mylib_common.cpp"],
 			system_shared_libs: [],
 			stl: "none",
+			// TODO: remove //apex_available:platform
+			apex_available: [
+				"//apex_available:platform",
+				"commonapex",
+				"myapex",
+			],
 		}
 	`)
 
@@ -2846,6 +2955,7 @@
 			sdk_version: "none",
 			system_modules: "none",
 			jni_libs: ["libjni"],
+			apex_available: [ "myapex" ],
 		}
 
 		android_app {
@@ -2854,6 +2964,7 @@
 			sdk_version: "none",
 			system_modules: "none",
 			privileged: true,
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library_shared {
@@ -2947,6 +3058,7 @@
 		android_test_helper_app {
 			name: "TesterHelpAppFoo",
 			srcs: ["foo/bar/MyClass.java"],
+			apex_available: [ "myapex" ],
 		}
 
 	`)
@@ -3202,6 +3314,7 @@
 			package_name: "foo",
 			sdk_version: "none",
 			system_modules: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		override_android_app {
@@ -3265,6 +3378,7 @@
 	module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
 	args := module.Rule("apexRule").Args
 	ensureContains(t, args["opt_flags"], "--manifest_json "+module.Output("apex_manifest.json").Output.String())
+	ensureNotContains(t, args["opt_flags"], "--no_hashtree")
 }
 
 func TestJavaSDKLibrary(t *testing.T) {
@@ -3285,6 +3399,7 @@
 			name: "foo",
 			srcs: ["a.java"],
 			api_packages: ["foo"],
+			apex_available: [ "myapex" ],
 		}
 	`, withFiles(map[string][]byte{
 		"api/current.txt":        nil,
@@ -3350,6 +3465,7 @@
 			required: ["a", "b"],
 			host_required: ["c", "d"],
 			target_required: ["e", "f"],
+			apex_available: [ "myapex" ],
 		}
 	`)
 
diff --git a/apex/builder.go b/apex/builder.go
index 4a760b9..9122188 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -233,6 +233,19 @@
 	return android.BuildNoticeOutput(ctx, a.installDir, apexFileName, android.FirstUniquePaths(noticeFiles)).HtmlGzOutput
 }
 
+func (a *apexBundle) buildInstalledFilesFile(ctx android.ModuleContext, builtApex android.Path, imageDir android.Path) android.OutputPath {
+	output := android.PathForModuleOut(ctx, "installed-files.txt")
+	rule := android.NewRuleBuilder()
+	rule.Command().
+		Implicit(builtApex).
+		Text("(cd " + imageDir.String() + " ; ").
+		Text("find . -type f -printf \"%s %p\\n\") ").
+		Text(" | sort -nr > ").
+		Output(output)
+	rule.Build(pctx, ctx, "installed-files."+a.Name(), "Installed files")
+	return output.OutputPath
+}
+
 func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
 	var abis []string
 	for _, target := range ctx.MultiTargets() {
@@ -307,6 +320,7 @@
 	outHostBinDir := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "bin").String()
 	prebuiltSdkToolsBinDir := filepath.Join("prebuilts", "sdk", "tools", runtime.GOOS, "bin")
 
+	imageDir := android.PathForModuleOut(ctx, "image"+suffix)
 	if apexType == imageApex {
 		// files and dirs that will be created in APEX
 		var readOnlyPaths = []string{"apex_manifest.json", "apex_manifest.pb"}
@@ -383,7 +397,7 @@
 			ctx.PropertyErrorf("test_only_no_hashtree", "not available")
 			return
 		}
-		if (!ctx.Config().UnbundledBuild() && a.installable()) || a.testOnlyShouldSkipHashtreeGeneration() {
+		if !proptools.Bool(a.properties.Legacy_android10_support) || a.testOnlyShouldSkipHashtreeGeneration() {
 			// Apexes which are supposed to be installed in builtin dirs(/system, etc)
 			// don't need hashtree for activation. Therefore, by removing hashtree from
 			// apex bundle (filesystem image in it, to be specific), we can save storage.
@@ -408,7 +422,7 @@
 			Description: "apex (" + apexType.name() + ")",
 			Args: map[string]string{
 				"tool_path":        outHostBinDir + ":" + prebuiltSdkToolsBinDir,
-				"image_dir":        android.PathForModuleOut(ctx, "image"+suffix).String(),
+				"image_dir":        imageDir.String(),
 				"copy_commands":    strings.Join(copyCommands, " && "),
 				"manifest":         a.manifestPbOut.String(),
 				"file_contexts":    a.fileContexts.String(),
@@ -446,7 +460,7 @@
 			Description: "apex (" + apexType.name() + ")",
 			Args: map[string]string{
 				"tool_path":     outHostBinDir + ":" + prebuiltSdkToolsBinDir,
-				"image_dir":     android.PathForModuleOut(ctx, "image"+suffix).String(),
+				"image_dir":     imageDir.String(),
 				"copy_commands": strings.Join(copyCommands, " && "),
 				"manifest":      a.manifestPbOut.String(),
 			},
@@ -474,6 +488,9 @@
 		ctx.InstallFile(a.installDir, a.Name()+suffix, a.outputFile)
 	}
 	a.buildFilesInfo(ctx)
+
+	// installed-files.txt is dist'ed
+	a.installedFilesFile = a.buildInstalledFilesFile(ctx, a.outputFile, imageDir)
 }
 
 func (a *apexBundle) buildFlattenedApex(ctx android.ModuleContext) {
@@ -554,3 +571,51 @@
 	}
 	return ""
 }
+
+func (a *apexBundle) buildApexDependencyInfo(ctx android.ModuleContext) {
+	if !a.primaryApexType {
+		return
+	}
+
+	if a.properties.IsCoverageVariant {
+		// Otherwise, we will have duplicated rules for coverage and
+		// non-coverage variants of the same APEX
+		return
+	}
+
+	if ctx.Host() {
+		// No need to generate dependency info for host variant
+		return
+	}
+
+	internalDeps := a.internalDeps
+	externalDeps := a.externalDeps
+
+	internalDeps = android.SortedUniqueStrings(internalDeps)
+	externalDeps = android.SortedUniqueStrings(externalDeps)
+	externalDeps = android.RemoveListFromList(externalDeps, internalDeps)
+
+	var content strings.Builder
+	for _, name := range internalDeps {
+		fmt.Fprintf(&content, "internal %s\\n", name)
+	}
+	for _, name := range externalDeps {
+		fmt.Fprintf(&content, "external %s\\n", name)
+	}
+
+	depsInfoFile := android.PathForOutput(ctx, a.Name()+"-deps-info.txt")
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        android.WriteFile,
+		Description: "Dependency Info",
+		Output:      depsInfoFile,
+		Args: map[string]string{
+			"content": content.String(),
+		},
+	})
+
+	ctx.Build(pctx, android.BuildParams{
+		Rule:   android.Phony,
+		Output: android.PathForPhony(ctx, a.Name()+"-deps-info"),
+		Inputs: []android.Path{depsInfoFile},
+	})
+}
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index ba5a466..d089c28 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -33,6 +33,10 @@
 	installDir      android.InstallPath
 	installFilename string
 	outputApex      android.WritablePath
+
+	// list of commands to create symlinks for backward compatibility.
+	// these commands will be attached as LOCAL_POST_INSTALL_CMD
+	compatSymlinks []string
 }
 
 type PrebuiltProperties struct {
@@ -178,7 +182,12 @@
 		ctx.InstallFile(p.installDir, p.installFilename, p.inputApex)
 	}
 
-	// TODO(b/143192278): Add compat symlinks for prebuilt_apex
+	// in case that prebuilt_apex replaces source apex (using prefer: prop)
+	p.compatSymlinks = makeCompatSymlinks(p.BaseModuleName(), ctx)
+	// or that prebuilt_apex overrides other apexes (using overrides: prop)
+	for _, overridden := range p.properties.Overrides {
+		p.compatSymlinks = append(p.compatSymlinks, makeCompatSymlinks(overridden, ctx)...)
+	}
 }
 
 func (p *Prebuilt) AndroidMkEntries() []android.AndroidMkEntries {
@@ -192,6 +201,9 @@
 				entries.SetString("LOCAL_MODULE_STEM", p.installFilename)
 				entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !p.installable())
 				entries.AddStrings("LOCAL_OVERRIDES_MODULES", p.properties.Overrides...)
+				if len(p.compatSymlinks) > 0 {
+					entries.SetString("LOCAL_POST_INSTALL_CMD", strings.Join(p.compatSymlinks, " && "))
+				}
 			},
 		},
 	}}
diff --git a/apex/vndk.go b/apex/vndk.go
index 1f52d11..f2e913e 100644
--- a/apex/vndk.go
+++ b/apex/vndk.go
@@ -105,7 +105,8 @@
 	}
 }
 
-func makeCompatSymlinks(apexName string, ctx android.ModuleContext) (symlinks []string) {
+// name is module.BaseModuleName() which is used as LOCAL_MODULE_NAME and also LOCAL_OVERRIDES_*
+func makeCompatSymlinks(name string, ctx android.ModuleContext) (symlinks []string) {
 	// small helper to add symlink commands
 	addSymlink := func(target, dir, linkName string) {
 		link := filepath.Join(dir, linkName)
@@ -116,9 +117,13 @@
 	// When all hard-coded references are fixed, remove symbolic links
 	// Note that  we should keep following symlinks for older VNDKs (<=29)
 	// Since prebuilt vndk libs still depend on system/lib/vndk path
-	if strings.HasPrefix(apexName, vndkApexNamePrefix) {
+	if strings.HasPrefix(name, vndkApexName) {
+		vndkVersion := ctx.DeviceConfig().PlatformVndkVersion()
+		if strings.HasPrefix(name, vndkApexNamePrefix) {
+			vndkVersion = strings.TrimPrefix(name, vndkApexNamePrefix)
+		}
 		// the name of vndk apex is formatted "com.android.vndk.v" + version
-		vndkVersion := strings.TrimPrefix(apexName, vndkApexNamePrefix)
+		apexName := vndkApexNamePrefix + vndkVersion
 		if ctx.Config().Android64() {
 			addSymlink("/apex/"+apexName+"/lib64", "$(TARGET_OUT)/lib64", "vndk-sp-"+vndkVersion)
 			addSymlink("/apex/"+apexName+"/lib64", "$(TARGET_OUT)/lib64", "vndk-"+vndkVersion)
@@ -127,22 +132,25 @@
 			addSymlink("/apex/"+apexName+"/lib", "$(TARGET_OUT)/lib", "vndk-sp-"+vndkVersion)
 			addSymlink("/apex/"+apexName+"/lib", "$(TARGET_OUT)/lib", "vndk-"+vndkVersion)
 		}
+		return
 	}
 
 	// http://b/121248172 - create a link from /system/usr/icu to
 	// /apex/com.android.i18n/etc/icu so that apps can find the ICU .dat file.
 	// A symlink can't overwrite a directory and the /system/usr/icu directory once
 	// existed so the required structure must be created whatever we find.
-	if apexName == "com.android.i18n" {
-		addSymlink("/apex/"+apexName+"/etc/icu", "$(TARGET_OUT)/usr", "icu")
+	if name == "com.android.i18n" {
+		addSymlink("/apex/com.android.i18n/etc/icu", "$(TARGET_OUT)/usr", "icu")
+		return
 	}
 
 	// TODO(b/124106384): Clean up compat symlinks for ART binaries.
-	if strings.HasPrefix(apexName, "com.android.art.") {
+	if strings.HasPrefix(name, "com.android.art.") {
 		artBinaries := []string{"dalvikvm", "dex2oat"}
 		for _, b := range artBinaries {
 			addSymlink("/apex/com.android.art/bin/"+b, "$(TARGET_OUT)/bin", b)
 		}
+		return
 	}
 	return
 }
diff --git a/build_kzip.bash b/build_kzip.bash
index 02b346d..329825a 100755
--- a/build_kzip.bash
+++ b/build_kzip.bash
@@ -6,12 +6,14 @@
 # The following environment variables affect the result:
 #   BUILD_NUMBER          build number, used to generate unique ID (will use UUID if not set)
 #   DIST_DIR              where the resulting all.kzip will be placed
+#   KYTHE_KZIP_ENCODING   proto or json (proto is default)
 #   OUT_DIR               output directory (out if not specified})
 #   TARGET_BUILD_VARIANT  variant, e.g., `userdebug`
 #   TARGET_PRODUCT        target device name, e.g., 'aosp_blueline'
 #   XREF_CORPUS           source code repository URI, e.g., 'android.googlesource.com/platform/superproject'
 
 : ${BUILD_NUMBER:=$(uuidgen)}
+: ${KYTHE_KZIP_ENCODING:=proto}
 
 # The extraction might fail for some source files, so run with -k and then check that
 # sufficiently many files were generated.
@@ -20,13 +22,14 @@
 build/soong/soong_ui.bash --build-mode --all-modules --dir=$PWD -k merge_zips xref_cxx xref_java
 #Build extraction file for Go files in build/soong directory.
 declare -r abspath_out=$(realpath "${out}")
-(cd build/soong;
- ../../prebuilts/build-tools/linux-x86/bin/go_extractor \
-    --goroot="${PWD}/../../prebuilts/go/linux-x86" \
-    --rules=vnames.go.json \
-    --canonicalize_package_corpus \
-    --output "${abspath_out}/soong/all.go.kzip" \
-    ./... )
+declare -r go_extractor=$(realpath prebuilts/build-tools/linux-x86/bin/go_extractor)
+declare -r go_root=$(realpath prebuilts/go/linux-x86)
+for dir in blueprint soong; do
+  (cd "build/$dir";
+   "$go_extractor" --goroot="$go_root" --rules=vnames.go.json --canonicalize_package_corpus \
+    --output "${abspath_out}/soong/build_${dir}.go.kzip" ./...
+  )
+done
 
 declare -r kzip_count=$(find "$out" -name '*.kzip' | wc -l)
 (($kzip_count>100000)) || { printf "Too few kzip files were generated: %d\n" $kzip_count; exit 1; }
diff --git a/cc/androidmk.go b/cc/androidmk.go
index ff88091..c9cd01c 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -217,6 +217,9 @@
 			fmt.Fprintln(w, "LOCAL_NO_NOTICE_FILE := true")
 			fmt.Fprintln(w, "LOCAL_VNDK_DEPEND_ON_CORE_VARIANT := true")
 		}
+		if library.checkSameCoreVariant {
+			fmt.Fprintln(w, "LOCAL_CHECK_SAME_VNDK_VARIANTS := true")
+		}
 	})
 
 	if library.shared() && !library.buildStubs() {
diff --git a/cc/binary.go b/cc/binary.go
index 617d4dd..ba6ed5f 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -56,8 +56,12 @@
 }
 
 func init() {
-	android.RegisterModuleType("cc_binary", BinaryFactory)
-	android.RegisterModuleType("cc_binary_host", binaryHostFactory)
+	RegisterBinaryBuildComponents(android.InitRegistrationContext)
+}
+
+func RegisterBinaryBuildComponents(ctx android.RegistrationContext) {
+	ctx.RegisterModuleType("cc_binary", BinaryFactory)
+	ctx.RegisterModuleType("cc_binary_host", binaryHostFactory)
 }
 
 // cc_binary produces a binary that is runnable on a device.
diff --git a/cc/builder.go b/cc/builder.go
index 1ec323f..5f0da5f 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -238,9 +238,13 @@
 	_ = pctx.SourcePathVariable("kytheVnames", "build/soong/vnames.json")
 	_ = pctx.VariableFunc("kytheCorpus",
 		func(ctx android.PackageVarContext) string { return ctx.Config().XrefCorpusName() })
+	_ = pctx.VariableFunc("kytheCuEncoding",
+		func(ctx android.PackageVarContext) string { return ctx.Config().XrefCuEncoding() })
 	kytheExtract = pctx.StaticRule("kythe",
 		blueprint.RuleParams{
-			Command:     "rm -f $out && KYTHE_CORPUS=${kytheCorpus} KYTHE_OUTPUT_FILE=$out KYTHE_VNAMES=$kytheVnames $cxxExtractor $cFlags $in ",
+			Command: `rm -f $out && ` +
+				`KYTHE_CORPUS=${kytheCorpus} KYTHE_OUTPUT_FILE=$out KYTHE_VNAMES=$kytheVnames KYTHE_KZIP_ENCODING=${kytheCuEncoding} ` +
+				`$cxxExtractor $cFlags $in `,
 			CommandDeps: []string{"$cxxExtractor", "$kytheVnames"},
 		},
 		"cFlags")
diff --git a/cc/cc.go b/cc/cc.go
index 0c32225..022e350 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -398,6 +398,13 @@
 	return ok && ccDepTag.Shared
 }
 
+func IsStaticDepTag(depTag blueprint.DependencyTag) bool {
+	ccDepTag, ok := depTag.(DependencyTag)
+	return ok && (ccDepTag == staticExportDepTag ||
+		ccDepTag == lateStaticDepTag ||
+		ccDepTag == wholeStaticDepTag)
+}
+
 func IsRuntimeDepTag(depTag blueprint.DependencyTag) bool {
 	ccDepTag, ok := depTag.(DependencyTag)
 	return ok && ccDepTag == runtimeDepTag
@@ -463,6 +470,9 @@
 	makeLinkType string
 	// Kythe (source file indexer) paths for this compilation module
 	kytheFiles android.Paths
+
+	// name of the modules that are direct or indirect static deps of this module
+	allStaticDeps []string
 }
 
 func (c *Module) Toc() android.OptionalPath {
@@ -1103,7 +1113,7 @@
 		// Host modules do not need ABI dumps.
 		return false
 	}
-	if ctx.isStubs() {
+	if ctx.isStubs() || ctx.isNDKStubLibrary() {
 		// Stubs do not need ABI dumps.
 		return false
 	}
@@ -1258,6 +1268,15 @@
 	return results
 }
 
+func gatherTransitiveStaticDeps(staticDeps []LinkableInterface) []string {
+	var ret []string
+	for _, dep := range staticDeps {
+		ret = append(ret, dep.Module().Name())
+		ret = append(ret, dep.AllStaticDeps()...)
+	}
+	return android.FirstUniqueStrings(ret)
+}
+
 func (c *Module) IsTestPerSrcAllTestsVariation() bool {
 	test, ok := c.linker.(testPerSrc)
 	return ok && test.isAllTestsVariation()
@@ -2328,6 +2347,8 @@
 		c.sabi.Properties.ReexportedIncludes = android.FirstUniqueStrings(c.sabi.Properties.ReexportedIncludes)
 	}
 
+	c.allStaticDeps = gatherTransitiveStaticDeps(directStaticDeps)
+
 	return depPaths
 }
 
@@ -2460,7 +2481,29 @@
 }
 
 func (c *Module) installable() bool {
-	return c.installer != nil && !c.Properties.PreventInstall && c.IsForPlatform() && c.outputFile.Valid()
+	ret := c.installer != nil && !c.Properties.PreventInstall && c.outputFile.Valid()
+
+	// The platform variant doesn't need further condition. Apex variants however might not
+	// be installable because it will likely to be included in the APEX and won't appear
+	// in the system partition.
+	if c.IsForPlatform() {
+		return ret
+	}
+
+	// Special case for modules that are configured to be installed to /data, which includes
+	// test modules. For these modules, both APEX and non-APEX variants are considered as
+	// installable. This is because even the APEX variants won't be included in the APEX, but
+	// will anyway be installed to /data/*.
+	// See b/146995717
+	if c.InstallInData() {
+		return ret
+	}
+
+	return false
+}
+
+func (c *Module) AllStaticDeps() []string {
+	return c.allStaticDeps
 }
 
 func (c *Module) AndroidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) {
diff --git a/cc/ccdeps.go b/cc/ccdeps.go
index 9b89110..4e23a7b 100644
--- a/cc/ccdeps.go
+++ b/cc/ccdeps.go
@@ -142,7 +142,7 @@
 			compilerParams.HeaderSearchPath =
 				append(compilerParams.HeaderSearchPath, strings.TrimPrefix(param, "-I"))
 		case systemHeaderSearchPath:
-			if i < len(params)-1 {
+			if i < len(cparams)-1 {
 				compilerParams.SystemHeaderSearchPath = append(compilerParams.SystemHeaderSearchPath, cparams[i+1])
 			}
 			i = i + 1
diff --git a/cc/cmakelists.go b/cc/cmakelists.go
index 97d21f4..f7d9081 100644
--- a/cc/cmakelists.go
+++ b/cc/cmakelists.go
@@ -76,7 +76,7 @@
 	// Link all handmade CMakeLists.txt aggregate from
 	//     BASE/development/ide/clion to
 	// BASE/out/development/ide/clion.
-	dir := filepath.Join(getAndroidSrcRootDirectory(ctx), cLionAggregateProjectsDirectory)
+	dir := filepath.Join(android.AbsSrcDirForExistingUseCases(), cLionAggregateProjectsDirectory)
 	filepath.Walk(dir, linkAggregateCMakeListsFiles)
 
 	return
@@ -147,7 +147,7 @@
 	f.WriteString("# Tools > CMake > Change Project Root  \n\n")
 	f.WriteString(fmt.Sprintf("cmake_minimum_required(VERSION %s)\n", minimumCMakeVersionSupported))
 	f.WriteString(fmt.Sprintf("project(%s)\n", ccModule.ModuleBase.Name()))
-	f.WriteString(fmt.Sprintf("set(ANDROID_ROOT %s)\n\n", getAndroidSrcRootDirectory(ctx)))
+	f.WriteString(fmt.Sprintf("set(ANDROID_ROOT %s)\n\n", android.AbsSrcDirForExistingUseCases()))
 
 	pathToCC, _ := evalVariable(ctx, "${config.ClangBin}/")
 	f.WriteString(fmt.Sprintf("set(CMAKE_C_COMPILER \"%s%s\")\n", buildCMakePath(pathToCC), "clang"))
@@ -465,7 +465,7 @@
 }
 
 func getCMakeListsForModule(module *Module, ctx android.SingletonContext) string {
-	return filepath.Join(getAndroidSrcRootDirectory(ctx),
+	return filepath.Join(android.AbsSrcDirForExistingUseCases(),
 		cLionOutputProjectsDirectory,
 		path.Dir(ctx.BlueprintFile(module)),
 		module.ModuleBase.Name()+"-"+
@@ -473,8 +473,3 @@
 			module.ModuleBase.Os().Name,
 		cMakeListsFilename)
 }
-
-func getAndroidSrcRootDirectory(ctx android.SingletonContext) string {
-	srcPath, _ := filepath.Abs(android.PathForSource(ctx).String())
-	return srcPath
-}
diff --git a/cc/compdb.go b/cc/compdb.go
index dff14db..ea12443 100644
--- a/cc/compdb.go
+++ b/cc/compdb.go
@@ -79,9 +79,9 @@
 
 	// Create the output file.
 	dir := android.PathForOutput(ctx, compdbOutputProjectsDirectory)
-	os.MkdirAll(dir.String(), 0777)
+	os.MkdirAll(filepath.Join(android.AbsSrcDirForExistingUseCases(), dir.String()), 0777)
 	compDBFile := dir.Join(ctx, compdbFilename)
-	f, err := os.Create(compDBFile.String())
+	f, err := os.Create(filepath.Join(android.AbsSrcDirForExistingUseCases(), compDBFile.String()))
 	if err != nil {
 		log.Fatalf("Could not create file %s: %s", compDBFile, err)
 	}
@@ -103,8 +103,8 @@
 	}
 	f.Write(dat)
 
-	finalLinkPath := filepath.Join(ctx.Config().Getenv(envVariableCompdbLink), compdbFilename)
-	if finalLinkPath != "" {
+	if finalLinkDir := ctx.Config().Getenv(envVariableCompdbLink); finalLinkDir != "" {
+		finalLinkPath := filepath.Join(finalLinkDir, compdbFilename)
 		os.Remove(finalLinkPath)
 		if err := os.Symlink(compDBFile.String(), finalLinkPath); err != nil {
 			log.Fatalf("Unable to symlink %s to %s: %s", compDBFile, finalLinkPath, err)
@@ -174,18 +174,17 @@
 		return
 	}
 
-	rootDir := getCompdbAndroidSrcRootDirectory(ctx)
-	pathToCC, err := ctx.Eval(pctx, rootDir+"/${config.ClangBin}/")
+	pathToCC, err := ctx.Eval(pctx, "${config.ClangBin}")
 	ccPath := "/bin/false"
 	cxxPath := "/bin/false"
 	if err == nil {
-		ccPath = pathToCC + "clang"
-		cxxPath = pathToCC + "clang++"
+		ccPath = filepath.Join(pathToCC, "clang")
+		cxxPath = filepath.Join(pathToCC, "clang++")
 	}
 	for _, src := range srcs {
 		if _, ok := builds[src.String()]; !ok {
 			builds[src.String()] = compDbEntry{
-				Directory: rootDir,
+				Directory: android.AbsSrcDirForExistingUseCases(),
 				Arguments: getArguments(src, ctx, ccModule, ccPath, cxxPath),
 				File:      src.String(),
 			}
@@ -200,8 +199,3 @@
 	}
 	return []string{""}, err
 }
-
-func getCompdbAndroidSrcRootDirectory(ctx android.SingletonContext) string {
-	srcPath, _ := filepath.Abs(android.PathForSource(ctx).String())
-	return srcPath
-}
diff --git a/cc/config/OWNERS b/cc/config/OWNERS
new file mode 100644
index 0000000..b2f54e5
--- /dev/null
+++ b/cc/config/OWNERS
@@ -0,0 +1 @@
+per-file vndk.go = smoreland@google.com, victoryang@google.com
diff --git a/cc/config/global.go b/cc/config/global.go
index 87314dc..1ce29b9 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -166,6 +166,9 @@
 			flags = append(flags, "-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang")
 		} else if ctx.Config().IsEnvTrue("AUTO_PATTERN_INITIALIZE") {
 			flags = append(flags, "-ftrivial-auto-var-init=pattern")
+		} else {
+			// Default to pattern initialization.
+			flags = append(flags, "-ftrivial-auto-var-init=pattern")
 		}
 
 		return strings.Join(flags, " ")
diff --git a/cc/config/vndk.go b/cc/config/vndk.go
index 9feb5a3..3b16c78 100644
--- a/cc/config/vndk.go
+++ b/cc/config/vndk.go
@@ -71,6 +71,7 @@
 	"android.hardware.nfc@1.2",
 	"android.hardware.oemlock@1.0",
 	"android.hardware.power.stats@1.0",
+	"android.hardware.power-ndk_platform",
 	"android.hardware.power@1.0",
 	"android.hardware.power@1.1",
 	"android.hardware.radio@1.4",
@@ -131,6 +132,7 @@
 	"libsqlite",
 	"libssl",
 	"libstagefright_amrnb_common",
+	"libstagefright_bufferpool@2.0",
 	"libstagefright_bufferqueue_helper",
 	"libstagefright_enc_common",
 	"libstagefright_flacdec",
diff --git a/cc/coverage.go b/cc/coverage.go
index c03a568..b6451ee 100644
--- a/cc/coverage.go
+++ b/cc/coverage.go
@@ -163,6 +163,7 @@
 	IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool
 	PreventInstall()
 	HideFromMake()
+	MarkAsCoverageVariant(bool)
 }
 
 func coverageMutator(mctx android.BottomUpMutatorContext) {
@@ -191,6 +192,7 @@
 		// module which are split into "" and "cov" variants. e.g. when cc_test refers
 		// to an APEX via 'data' property.
 		m := mctx.CreateVariations("", "cov")
+		m[0].(Coverage).MarkAsCoverageVariant(true)
 		m[0].(Coverage).PreventInstall()
 		m[0].(Coverage).HideFromMake()
 	}
diff --git a/cc/library.go b/cc/library.go
index ae95bc5..f29c4d0 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -385,7 +385,8 @@
 
 	// If useCoreVariant is true, the vendor variant of a VNDK library is
 	// not installed.
-	useCoreVariant bool
+	useCoreVariant       bool
+	checkSameCoreVariant bool
 
 	// Decorated interafaces
 	*baseCompiler
@@ -1096,8 +1097,11 @@
 			if ctx.isVndkSp() {
 				library.baseInstaller.subDir = "vndk-sp"
 			} else if ctx.isVndk() {
-				if ctx.DeviceConfig().VndkUseCoreVariant() && !ctx.mustUseVendorVariant() {
-					library.useCoreVariant = true
+				if !ctx.mustUseVendorVariant() {
+					library.checkSameCoreVariant = true
+					if ctx.DeviceConfig().VndkUseCoreVariant() {
+						library.useCoreVariant = true
+					}
 				}
 				library.baseInstaller.subDir = "vndk"
 			}
diff --git a/cc/linkable.go b/cc/linkable.go
index 815d405..106092b 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -51,6 +51,8 @@
 	ToolchainLibrary() bool
 	NdkPrebuiltStl() bool
 	StubDecorator() bool
+
+	AllStaticDeps() []string
 }
 
 type DependencyTag struct {
diff --git a/cc/ndk_headers.go b/cc/ndk_headers.go
index b8423be..5744bb2 100644
--- a/cc/ndk_headers.go
+++ b/cc/ndk_headers.go
@@ -16,7 +16,6 @@
 
 import (
 	"fmt"
-	"os"
 	"path/filepath"
 	"strings"
 
@@ -255,16 +254,8 @@
 	depsPath := android.PathForSource(ctx, "bionic/libc/versioner-dependencies")
 	depsGlob := ctx.Glob(filepath.Join(depsPath.String(), "**/*"), nil)
 	for i, path := range depsGlob {
-		fileInfo, err := os.Lstat(path.String())
-		if err != nil {
-			ctx.ModuleErrorf("os.Lstat(%q) failed: %s", path.String, err)
-		}
-		if fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink {
-			dest, err := os.Readlink(path.String())
-			if err != nil {
-				ctx.ModuleErrorf("os.Readlink(%q) failed: %s",
-					path.String, err)
-			}
+		if ctx.IsSymlink(path) {
+			dest := ctx.Readlink(path)
 			// Additional .. to account for the symlink itself.
 			depsGlob[i] = android.PathForSource(
 				ctx, filepath.Clean(filepath.Join(path.String(), "..", dest)))
diff --git a/cc/pgo.go b/cc/pgo.go
index 0072355..e341d03 100644
--- a/cc/pgo.go
+++ b/cc/pgo.go
@@ -177,6 +177,10 @@
 		// if profileFile gets updated
 		flags.CFlagsDeps = append(flags.CFlagsDeps, profileFilePath)
 		flags.LdFlagsDeps = append(flags.LdFlagsDeps, profileFilePath)
+
+		if props.isSampling() {
+			flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-mllvm,-no-warn-sample-unused=true")
+		}
 	}
 	return flags
 }
diff --git a/cc/testing.go b/cc/testing.go
index d6f2391..ba8ed95 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -23,6 +23,7 @@
 	android.RegisterPrebuiltMutators(ctx)
 
 	RegisterCCBuildComponents(ctx)
+	RegisterBinaryBuildComponents(ctx)
 	RegisterLibraryBuildComponents(ctx)
 
 	ctx.RegisterModuleType("toolchain_library", ToolchainLibraryFactory)
@@ -308,8 +309,6 @@
 
 func CreateTestContext() *android.TestContext {
 	ctx := android.NewTestArchContext()
-	ctx.RegisterModuleType("cc_binary", BinaryFactory)
-	ctx.RegisterModuleType("cc_binary_host", binaryHostFactory)
 	ctx.RegisterModuleType("cc_fuzz", FuzzFactory)
 	ctx.RegisterModuleType("cc_test", TestFactory)
 	ctx.RegisterModuleType("llndk_headers", llndkHeadersFactory)
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index 0c79ccc..2a929c5 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -16,7 +16,6 @@
 
 import (
 	"encoding/json"
-	"io/ioutil"
 	"strings"
 
 	"android/soong/android"
@@ -185,7 +184,7 @@
 // soongConfig argument. LoadGlobalConfig is used directly in Soong and in
 // dexpreopt_gen called from Make to read the $OUT/dexpreopt.config written by
 // Make.
-func LoadGlobalConfig(ctx android.PathContext, path string, soongConfig GlobalSoongConfig) (GlobalConfig, []byte, error) {
+func LoadGlobalConfig(ctx android.PathContext, data []byte, soongConfig GlobalSoongConfig) (GlobalConfig, error) {
 	type GlobalJSONConfig struct {
 		GlobalConfig
 
@@ -196,9 +195,9 @@
 	}
 
 	config := GlobalJSONConfig{}
-	data, err := loadConfig(ctx, path, &config)
+	err := json.Unmarshal(data, &config)
 	if err != nil {
-		return config.GlobalConfig, nil, err
+		return config.GlobalConfig, err
 	}
 
 	// Construct paths that require a PathContext.
@@ -209,13 +208,13 @@
 	// either CreateGlobalSoongConfig or LoadGlobalSoongConfig).
 	config.GlobalConfig.SoongConfig = soongConfig
 
-	return config.GlobalConfig, data, nil
+	return config.GlobalConfig, nil
 }
 
 // LoadModuleConfig reads a per-module dexpreopt.config file into a ModuleConfig struct.  It is not used in Soong, which
 // receives a ModuleConfig struct directly from java/dexpreopt.go.  It is used in dexpreopt_gen called from oMake to
 // read the module dexpreopt.config written by Make.
-func LoadModuleConfig(ctx android.PathContext, path string) (ModuleConfig, error) {
+func LoadModuleConfig(ctx android.PathContext, data []byte) (ModuleConfig, error) {
 	type ModuleJSONConfig struct {
 		ModuleConfig
 
@@ -233,7 +232,7 @@
 
 	config := ModuleJSONConfig{}
 
-	_, err := loadConfig(ctx, path, &config)
+	err := json.Unmarshal(data, &config)
 	if err != nil {
 		return config.ModuleConfig, err
 	}
@@ -289,10 +288,10 @@
 
 // LoadGlobalSoongConfig reads the dexpreopt_soong.config file into a
 // GlobalSoongConfig struct. It is only used in dexpreopt_gen.
-func LoadGlobalSoongConfig(ctx android.PathContext, path string) (GlobalSoongConfig, error) {
+func LoadGlobalSoongConfig(ctx android.PathContext, data []byte) (GlobalSoongConfig, error) {
 	var jc globalJsonSoongConfig
 
-	_, err := loadConfig(ctx, path, &jc)
+	err := json.Unmarshal(data, &jc)
 	if err != nil {
 		return GlobalSoongConfig{}, err
 	}
@@ -352,26 +351,6 @@
 	}, " "))
 }
 
-func loadConfig(ctx android.PathContext, path string, config interface{}) ([]byte, error) {
-	r, err := ctx.Fs().Open(path)
-	if err != nil {
-		return nil, err
-	}
-	defer r.Close()
-
-	data, err := ioutil.ReadAll(r)
-	if err != nil {
-		return nil, err
-	}
-
-	err = json.Unmarshal(data, config)
-	if err != nil {
-		return nil, err
-	}
-
-	return data, nil
-}
-
 func GlobalConfigForTests(ctx android.PathContext) GlobalConfig {
 	return GlobalConfig{
 		DisablePreopt:                      false,
diff --git a/dexpreopt/dexpreopt_gen/dexpreopt_gen.go b/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
index d2faa00..e2818bb 100644
--- a/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
+++ b/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
@@ -18,6 +18,7 @@
 	"bytes"
 	"flag"
 	"fmt"
+	"io/ioutil"
 	"os"
 	"path/filepath"
 	"runtime"
@@ -41,7 +42,6 @@
 	config android.Config
 }
 
-func (x *pathContext) Fs() pathtools.FileSystem   { return pathtools.OsFs }
 func (x *pathContext) Config() android.Config     { return x.config }
 func (x *pathContext) AddNinjaFileDeps(...string) {}
 
@@ -76,21 +76,39 @@
 		usage("--module configuration file is required")
 	}
 
-	ctx := &pathContext{android.TestConfig(*outDir, nil, "", nil)}
+	ctx := &pathContext{android.NullConfig(*outDir)}
 
-	globalSoongConfig, err := dexpreopt.LoadGlobalSoongConfig(ctx, *globalSoongConfigPath)
+	globalSoongConfigData, err := ioutil.ReadFile(*globalSoongConfigPath)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "error reading global config %q: %s\n", *globalSoongConfigPath, err)
+		os.Exit(2)
+	}
+
+	globalSoongConfig, err := dexpreopt.LoadGlobalSoongConfig(ctx, globalSoongConfigData)
 	if err != nil {
 		fmt.Fprintf(os.Stderr, "error loading global config %q: %s\n", *globalSoongConfigPath, err)
 		os.Exit(2)
 	}
 
-	globalConfig, _, err := dexpreopt.LoadGlobalConfig(ctx, *globalConfigPath, globalSoongConfig)
+	globalConfigData, err := ioutil.ReadFile(*globalConfigPath)
 	if err != nil {
-		fmt.Fprintf(os.Stderr, "error loading global config %q: %s\n", *globalConfigPath, err)
+		fmt.Fprintf(os.Stderr, "error reading global config %q: %s\n", *globalConfigPath, err)
 		os.Exit(2)
 	}
 
-	moduleConfig, err := dexpreopt.LoadModuleConfig(ctx, *moduleConfigPath)
+	globalConfig, err := dexpreopt.LoadGlobalConfig(ctx, globalConfigData, globalSoongConfig)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "error parse global config %q: %s\n", *globalConfigPath, err)
+		os.Exit(2)
+	}
+
+	moduleConfigData, err := ioutil.ReadFile(*moduleConfigPath)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "error reading module config %q: %s\n", *moduleConfigPath, err)
+		os.Exit(2)
+	}
+
+	moduleConfig, err := dexpreopt.LoadModuleConfig(ctx, moduleConfigData)
 	if err != nil {
 		fmt.Fprintf(os.Stderr, "error loading module config %q: %s\n", *moduleConfigPath, err)
 		os.Exit(2)
diff --git a/env/env.go b/env/env.go
index bf58a99..a98e1f6 100644
--- a/env/env.go
+++ b/env/env.go
@@ -27,7 +27,7 @@
 type envFileEntry struct{ Key, Value string }
 type envFileData []envFileEntry
 
-func WriteEnvFile(filename string, envDeps map[string]string) error {
+func EnvFileContents(envDeps map[string]string) ([]byte, error) {
 	contents := make(envFileData, 0, len(envDeps))
 	for key, value := range envDeps {
 		contents = append(contents, envFileEntry{key, value})
@@ -37,17 +37,12 @@
 
 	data, err := json.MarshalIndent(contents, "", "    ")
 	if err != nil {
-		return err
+		return nil, err
 	}
 
 	data = append(data, '\n')
 
-	err = ioutil.WriteFile(filename, data, 0664)
-	if err != nil {
-		return err
-	}
-
-	return nil
+	return data, nil
 }
 
 func StaleEnvFile(filename string) (bool, error) {
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 57ca9bc..c5aaed2 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -30,10 +30,18 @@
 )
 
 func init() {
-	android.RegisterModuleType("genrule_defaults", defaultsFactory)
+	registerGenruleBuildComponents(android.InitRegistrationContext)
+}
 
-	android.RegisterModuleType("gensrcs", GenSrcsFactory)
-	android.RegisterModuleType("genrule", GenRuleFactory)
+func registerGenruleBuildComponents(ctx android.RegistrationContext) {
+	ctx.RegisterModuleType("genrule_defaults", defaultsFactory)
+
+	ctx.RegisterModuleType("gensrcs", GenSrcsFactory)
+	ctx.RegisterModuleType("genrule", GenRuleFactory)
+
+	ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
+		ctx.BottomUp("genrule_tool_deps", toolDepsMutator).Parallel()
+	})
 }
 
 var (
@@ -166,7 +174,7 @@
 	return g.outputDeps
 }
 
-func (g *Module) DepsMutator(ctx android.BottomUpMutatorContext) {
+func toolDepsMutator(ctx android.BottomUpMutatorContext) {
 	if g, ok := ctx.Module().(*Module); ok {
 		for _, tool := range g.properties.Tools {
 			tag := hostToolDependencyTag{label: tool}
diff --git a/genrule/genrule_test.go b/genrule/genrule_test.go
index ea49e08..7eb43ac 100644
--- a/genrule/genrule_test.go
+++ b/genrule/genrule_test.go
@@ -55,10 +55,10 @@
 
 	ctx := android.NewTestArchContext()
 	ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
-	ctx.RegisterModuleType("genrule", GenRuleFactory)
-	ctx.RegisterModuleType("gensrcs", GenSrcsFactory)
-	ctx.RegisterModuleType("genrule_defaults", defaultsFactory)
 	ctx.RegisterModuleType("tool", toolFactory)
+
+	registerGenruleBuildComponents(ctx)
+
 	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
 	ctx.Register(config)
 
diff --git a/java/aar.go b/java/aar.go
index 201e590..ae064e5 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -576,6 +576,10 @@
 	return a.prebuilt.Name(a.ModuleBase.Name())
 }
 
+func (a *AARImport) JacocoReportClassesFile() android.Path {
+	return nil
+}
+
 func (a *AARImport) DepsMutator(ctx android.BottomUpMutatorContext) {
 	if !ctx.Config().UnbundledBuildUsePrebuiltSdks() {
 		sdkDep := decodeSdkDep(ctx, sdkContext(a))
diff --git a/java/app.go b/java/app.go
index 2933ccb..e9941f2 100755
--- a/java/app.go
+++ b/java/app.go
@@ -644,22 +644,40 @@
 	}
 	a.generateAndroidBuildActions(ctx)
 
-	a.testConfig = tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
+	testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
 		a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites, a.testProperties.Auto_gen_config)
-	if a.overridableAppProperties.Package_name != nil {
-		fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", "AndroidTest.xml")
-		rule := android.NewRuleBuilder()
-		rule.Command().BuiltTool(ctx, "test_config_fixer").
-			FlagWithInput("--manifest ", a.manifestPath).
-			FlagWithArg("--package-name ", *a.overridableAppProperties.Package_name).
-			Input(a.testConfig).
-			Output(fixedConfig)
-		rule.Build(pctx, ctx, "fix_test_config", "fix test config")
-		a.testConfig = fixedConfig
-	}
+	a.testConfig = a.FixTestConfig(ctx, testConfig)
 	a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
 }
 
+func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path {
+	if testConfig == nil {
+		return nil
+	}
+
+	fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", "AndroidTest.xml")
+	rule := android.NewRuleBuilder()
+	command := rule.Command().BuiltTool(ctx, "test_config_fixer").Input(testConfig).Output(fixedConfig)
+	fixNeeded := false
+
+	if ctx.ModuleName() != a.installApkName {
+		fixNeeded = true
+		command.FlagWithArg("--test-file-name ", a.installApkName+".apk")
+	}
+
+	if a.overridableAppProperties.Package_name != nil {
+		fixNeeded = true
+		command.FlagWithInput("--manifest ", a.manifestPath).
+			FlagWithArg("--package-name ", *a.overridableAppProperties.Package_name)
+	}
+
+	if fixNeeded {
+		rule.Build(pctx, ctx, "fix_test_config", "fix test config")
+		return fixedConfig
+	}
+	return testConfig
+}
+
 func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) {
 	a.AndroidApp.DepsMutator(ctx)
 }
@@ -752,6 +770,7 @@
 
 	android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
 	android.InitDefaultableModule(module)
+	android.InitApexModule(module)
 	return module
 }
 
@@ -925,6 +944,16 @@
 
 func (a *AndroidAppImport) uncompressEmbeddedJniLibs(
 	ctx android.ModuleContext, inputPath android.Path, outputPath android.OutputPath) {
+	// Test apps don't need their JNI libraries stored uncompressed. As a matter of fact, messing
+	// with them may invalidate pre-existing signature data.
+	if ctx.InstallInTestcases() && Bool(a.properties.Presigned) {
+		ctx.Build(pctx, android.BuildParams{
+			Rule:   android.Cp,
+			Output: outputPath,
+			Input:  inputPath,
+		})
+		return
+	}
 	rule := android.NewRuleBuilder()
 	rule.Command().
 		Textf(`if (zipinfo %s 'lib/*.so' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then`, inputPath).
@@ -1002,6 +1031,8 @@
 	var installDir android.InstallPath
 	if Bool(a.properties.Privileged) {
 		installDir = android.PathForModuleInstall(ctx, "priv-app", a.BaseModuleName())
+	} else if ctx.InstallInTestcases() {
+		installDir = android.PathForModuleInstall(ctx, a.BaseModuleName(), ctx.DeviceConfig().DeviceArch())
 	} else {
 		installDir = android.PathForModuleInstall(ctx, "app", a.BaseModuleName())
 	}
@@ -1062,6 +1093,10 @@
 	return a.outputFile
 }
 
+func (a *AndroidAppImport) JacocoReportClassesFile() android.Path {
+	return nil
+}
+
 var dpiVariantGroupType reflect.Type
 var archVariantGroupType reflect.Type
 
@@ -1154,6 +1189,10 @@
 	a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
 }
 
+func (a *AndroidTestImport) InstallInTestcases() bool {
+	return true
+}
+
 // android_test_import imports a prebuilt test apk with additional processing specified in the
 // module. DPI or arch variant configurations can be made as with android_app_import.
 func AndroidTestImportFactory() android.Module {
diff --git a/java/app_test.go b/java/app_test.go
index 9bdef4e..6f89da4 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -1305,6 +1305,87 @@
 	}
 }
 
+func TestAndroidTest_FixTestConfig(t *testing.T) {
+	ctx, _ := testJava(t, `
+		android_app {
+			name: "foo",
+			srcs: ["a.java"],
+			package_name: "com.android.foo",
+			sdk_version: "current",
+		}
+
+		android_test {
+			name: "foo_test",
+			srcs: ["b.java"],
+			instrumentation_for: "foo",
+		}
+
+		android_test {
+			name: "bar_test",
+			srcs: ["b.java"],
+			package_name: "com.android.bar.test",
+			instrumentation_for: "foo",
+		}
+
+		override_android_test {
+			name: "baz_test",
+			base: "foo_test",
+			package_name: "com.android.baz.test",
+		}
+		`)
+
+	testCases := []struct {
+		moduleName    string
+		variantName   string
+		expectedFlags []string
+	}{
+		{
+			moduleName:  "foo_test",
+			variantName: "android_common",
+		},
+		{
+			moduleName:  "bar_test",
+			variantName: "android_common",
+			expectedFlags: []string{
+				"--manifest " + buildDir + "/.intermediates/bar_test/android_common/manifest_fixer/AndroidManifest.xml",
+				"--package-name com.android.bar.test",
+			},
+		},
+		{
+			moduleName:  "foo_test",
+			variantName: "android_common_baz_test",
+			expectedFlags: []string{
+				"--manifest " + buildDir +
+					"/.intermediates/foo_test/android_common_baz_test/manifest_fixer/AndroidManifest.xml",
+				"--package-name com.android.baz.test",
+				"--test-file-name baz_test.apk",
+			},
+		},
+	}
+
+	for _, test := range testCases {
+		variant := ctx.ModuleForTests(test.moduleName, test.variantName)
+		params := variant.MaybeOutput("test_config_fixer/AndroidTest.xml")
+
+		if len(test.expectedFlags) > 0 {
+			if params.Rule == nil {
+				t.Errorf("test_config_fixer was expected to run, but didn't")
+			} else {
+				for _, flag := range test.expectedFlags {
+					if !strings.Contains(params.RuleParams.Command, flag) {
+						t.Errorf("Flag %q was not found in command: %q", flag, params.RuleParams.Command)
+					}
+				}
+			}
+		} else {
+			if params.Rule != nil {
+				t.Errorf("test_config_fixer was not expected to run, but did: %q", params.RuleParams.Command)
+			}
+		}
+
+	}
+}
+
 func TestAndroidAppImport(t *testing.T) {
 	ctx, _ := testJava(t, `
 		android_app_import {
@@ -1628,6 +1709,40 @@
 	}
 }
 
+func TestAndroidTestImport_NoJinUncompressForPresigned(t *testing.T) {
+	ctx, _ := testJava(t, `
+		android_test_import {
+			name: "foo",
+			apk: "prebuilts/apk/app.apk",
+			certificate: "cert/new_cert",
+			data: [
+				"testdata/data",
+			],
+		}
+
+		android_test_import {
+			name: "foo_presigned",
+			apk: "prebuilts/apk/app.apk",
+			presigned: true,
+			data: [
+				"testdata/data",
+			],
+		}
+		`)
+
+	variant := ctx.ModuleForTests("foo", "android_common")
+	jniRule := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
+	if !strings.HasPrefix(jniRule, "if (zipinfo") {
+		t.Errorf("Unexpected JNI uncompress rule command: " + jniRule)
+	}
+
+	variant = ctx.ModuleForTests("foo_presigned", "android_common")
+	jniRule = variant.Output("jnis-uncompressed/foo_presigned.apk").BuildParams.Rule.String()
+	if jniRule != android.Cp.String() {
+		t.Errorf("Unexpected JNI uncompress rule: " + jniRule)
+	}
+}
+
 func TestStl(t *testing.T) {
 	ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
 		cc_library {
diff --git a/java/builder.go b/java/builder.go
index 417a7fa..26a49ea 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -64,6 +64,8 @@
 
 	_ = pctx.VariableFunc("kytheCorpus",
 		func(ctx android.PackageVarContext) string { return ctx.Config().XrefCorpusName() })
+	_ = pctx.VariableFunc("kytheCuEncoding",
+		func(ctx android.PackageVarContext) string { return ctx.Config().XrefCuEncoding() })
 	_ = pctx.SourcePathVariable("kytheVnames", "build/soong/vnames.json")
 	// Run it with -add-opens=java.base/java.nio=ALL-UNNAMED to avoid JDK9's warning about
 	// "Illegal reflective access by com.google.protobuf.Utf8$UnsafeProcessor ...
@@ -76,6 +78,7 @@
 				`KYTHE_ROOT_DIRECTORY=. KYTHE_OUTPUT_FILE=$out ` +
 				`KYTHE_CORPUS=${kytheCorpus} ` +
 				`KYTHE_VNAMES=${kytheVnames} ` +
+				`KYTHE_KZIP_ENCODING=${kytheCuEncoding} ` +
 				`${config.SoongJavacWrapper} ${config.JavaCmd} ` +
 				`--add-opens=java.base/java.nio=ALL-UNNAMED ` +
 				`-jar ${config.JavaKytheExtractorJar} ` +
diff --git a/java/config/config.go b/java/config/config.go
index 9738454..6da7279 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -45,7 +45,9 @@
 		"core-icu4j",
 		"core-oj",
 		"core-libart",
+		// TODO: Could this be all updatable bootclasspath jars?
 		"updatable-media",
+		"framework-sdkextensions",
 		"ike",
 	}
 )
diff --git a/java/device_host_converter.go b/java/device_host_converter.go
index 1524418..b40ab93 100644
--- a/java/device_host_converter.go
+++ b/java/device_host_converter.go
@@ -170,6 +170,10 @@
 	return d.srcJarArgs, d.srcJarDeps
 }
 
+func (d *DeviceHostConverter) JacocoReportClassesFile() android.Path {
+	return nil
+}
+
 func (d *DeviceHostConverter) AndroidMk() android.AndroidMkData {
 	return android.AndroidMkData{
 		Class:      "JAVA_LIBRARIES",
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 479dec6..da68660 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -85,6 +85,11 @@
 		return true
 	}
 
+	// Don't preopt APEX variant module
+	if am, ok := ctx.Module().(android.ApexModule); ok && !am.IsForPlatform() {
+		return true
+	}
+
 	// TODO: contains no java code
 
 	return false
@@ -101,9 +106,8 @@
 
 	global := dexpreoptGlobalConfig(ctx)
 	bootImage := defaultBootImageConfig(ctx)
-	defaultBootImage := bootImage
 	if global.UseApexImage {
-		bootImage = apexBootImageConfig(ctx)
+		bootImage = frameworkJZBootImageConfig(ctx)
 	}
 
 	var archs []android.ArchType
@@ -174,11 +178,8 @@
 		DexPreoptImagesDeps:     imagesDeps,
 		DexPreoptImageLocations: bootImage.imageLocations,
 
-		// We use the dex paths and dex locations of the default boot image, as it
-		// contains the full dexpreopt boot classpath. Other images may just contain a subset of
-		// the dexpreopt boot classpath.
-		PreoptBootClassPathDexFiles:     defaultBootImage.dexPathsDeps.Paths(),
-		PreoptBootClassPathDexLocations: defaultBootImage.dexLocationsDeps,
+		PreoptBootClassPathDexFiles:     bootImage.dexPathsDeps.Paths(),
+		PreoptBootClassPathDexLocations: bootImage.dexLocationsDeps,
 
 		PreoptExtractedApk: false,
 
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index fe5bed5..66840b5 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -220,7 +220,8 @@
 	d.otherImages = append(d.otherImages, buildBootImage(ctx, artBootImageConfig(ctx)))
 	if global.GenerateApexImage {
 		// Create boot images for the JIT-zygote experiment.
-		d.otherImages = append(d.otherImages, buildBootImage(ctx, apexBootImageConfig(ctx)))
+		d.otherImages = append(d.otherImages, buildBootImage(ctx, artJZBootImageConfig(ctx)))
+		d.otherImages = append(d.otherImages, buildBootImage(ctx, frameworkJZBootImageConfig(ctx)))
 	}
 
 	dumpOatRules(ctx, d.defaultBootImage)
diff --git a/java/dexpreopt_bootjars_test.go b/java/dexpreopt_bootjars_test.go
index 8f29e9e..4ce30f6 100644
--- a/java/dexpreopt_bootjars_test.go
+++ b/java/dexpreopt_bootjars_test.go
@@ -48,7 +48,7 @@
 
 	pathCtx := android.PathContextForTesting(config)
 	dexpreoptConfig := dexpreopt.GlobalConfigForTests(pathCtx)
-	dexpreoptConfig.ArtApexJars = []string{"foo", "bar", "baz"}
+	dexpreoptConfig.BootJars = []string{"foo", "bar", "baz"}
 	setDexpreoptTestGlobalConfig(config, dexpreoptConfig)
 
 	ctx := testContext()
@@ -59,9 +59,10 @@
 
 	dexpreoptBootJars := ctx.SingletonForTests("dex_bootjars")
 
-	bootArt := dexpreoptBootJars.Output("boot.art")
+	bootArt := dexpreoptBootJars.Output("boot-foo.art")
 
 	expectedInputs := []string{
+		"dex_artjars/apex/com.android.art/javalib/arm64/boot.art",
 		"dex_bootjars_input/foo.jar",
 		"dex_bootjars_input/bar.jar",
 		"dex_bootjars_input/baz.jar",
@@ -82,19 +83,19 @@
 	expectedOutputs := []string{
 		"dex_bootjars/system/framework/arm64/boot.invocation",
 
-		"dex_bootjars/system/framework/arm64/boot.art",
+		"dex_bootjars/system/framework/arm64/boot-foo.art",
 		"dex_bootjars/system/framework/arm64/boot-bar.art",
 		"dex_bootjars/system/framework/arm64/boot-baz.art",
 
-		"dex_bootjars/system/framework/arm64/boot.oat",
+		"dex_bootjars/system/framework/arm64/boot-foo.oat",
 		"dex_bootjars/system/framework/arm64/boot-bar.oat",
 		"dex_bootjars/system/framework/arm64/boot-baz.oat",
 
-		"dex_bootjars/system/framework/arm64/boot.vdex",
+		"dex_bootjars/system/framework/arm64/boot-foo.vdex",
 		"dex_bootjars/system/framework/arm64/boot-bar.vdex",
 		"dex_bootjars/system/framework/arm64/boot-baz.vdex",
 
-		"dex_bootjars_unstripped/system/framework/arm64/boot.oat",
+		"dex_bootjars_unstripped/system/framework/arm64/boot-foo.oat",
 		"dex_bootjars_unstripped/system/framework/arm64/boot-bar.oat",
 		"dex_bootjars_unstripped/system/framework/arm64/boot-baz.oat",
 	}
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index 35748b8..31bec93 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -36,10 +36,11 @@
 
 func dexpreoptGlobalConfigRaw(ctx android.PathContext) globalConfigAndRaw {
 	return ctx.Config().Once(dexpreoptGlobalConfigKey, func() interface{} {
-		if f := ctx.Config().DexpreoptGlobalConfig(); f != "" {
+		if data, err := ctx.Config().DexpreoptGlobalConfig(ctx); err != nil {
+			panic(err)
+		} else if data != nil {
 			soongConfig := dexpreopt.CreateGlobalSoongConfig(ctx)
-			ctx.AddNinjaFileDeps(f)
-			globalConfig, data, err := dexpreopt.LoadGlobalConfig(ctx, f, soongConfig)
+			globalConfig, err := dexpreopt.LoadGlobalConfig(ctx, data, soongConfig)
 			if err != nil {
 				panic(err)
 			}
@@ -121,10 +122,11 @@
 }
 
 var (
-	bootImageConfigKey     = android.NewOnceKey("bootImageConfig")
-	artBootImageName       = "art"
-	frameworkBootImageName = "boot"
-	apexBootImageName      = "apex"
+	bootImageConfigKey       = android.NewOnceKey("bootImageConfig")
+	artBootImageName         = "art"
+	frameworkBootImageName   = "boot"
+	artJZBootImageName       = "jitzygote-art"
+	frameworkJZBootImageName = "jitzygote-boot"
 )
 
 // Construct the global boot image configs.
@@ -167,33 +169,44 @@
 		}
 
 		// Framework config for the boot image extension.
-		// It includes both the Core libraries and framework.
+		// It includes framework libraries and depends on the ART config.
 		frameworkCfg := bootImageConfig{
-			extension:        false,
+			extension:        true,
 			name:             frameworkBootImageName,
 			stem:             "boot",
 			installSubdir:    frameworkSubdir,
-			modules:          concat(artModules, frameworkModules),
-			dexLocations:     concat(artLocations, frameworkLocations),
-			dexLocationsDeps: concat(artLocations, frameworkLocations),
+			modules:          frameworkModules,
+			dexLocations:     frameworkLocations,
+			dexLocationsDeps: append(artLocations, frameworkLocations...),
 		}
 
-		// Apex config for the  boot image used in the JIT-zygote experiment.
-		// It includes both the Core libraries and framework.
-		apexCfg := bootImageConfig{
+		// ART config for JIT-zygote boot image.
+		artJZCfg := bootImageConfig{
 			extension:        false,
-			name:             apexBootImageName,
+			name:             artJZBootImageName,
+			stem:             "apex",
+			installSubdir:    artSubdir,
+			modules:          artModules,
+			dexLocations:     artLocations,
+			dexLocationsDeps: artLocations,
+		}
+
+		// Framework config for JIT-zygote boot image extension.
+		frameworkJZCfg := bootImageConfig{
+			extension:        true,
+			name:             frameworkJZBootImageName,
 			stem:             "apex",
 			installSubdir:    frameworkSubdir,
-			modules:          concat(artModules, frameworkModules),
-			dexLocations:     concat(artLocations, frameworkLocations),
-			dexLocationsDeps: concat(artLocations, frameworkLocations),
+			modules:          frameworkModules,
+			dexLocations:     frameworkLocations,
+			dexLocationsDeps: append(artLocations, frameworkLocations...),
 		}
 
 		configs := map[string]*bootImageConfig{
-			artBootImageName:       &artCfg,
-			frameworkBootImageName: &frameworkCfg,
-			apexBootImageName:      &apexCfg,
+			artBootImageName:         &artCfg,
+			frameworkBootImageName:   &frameworkCfg,
+			artJZBootImageName:       &artJZCfg,
+			frameworkJZBootImageName: &frameworkJZCfg,
 		}
 
 		// common to all configs
@@ -231,6 +244,14 @@
 			c.zip = c.dir.Join(ctx, c.name+".zip")
 		}
 
+		// specific to the framework config
+		frameworkCfg.dexPathsDeps = append(artCfg.dexPathsDeps, frameworkCfg.dexPathsDeps...)
+		frameworkCfg.imageLocations = append(artCfg.imageLocations, frameworkCfg.imageLocations...)
+
+		// specific to the jitzygote-framework config
+		frameworkJZCfg.dexPathsDeps = append(artJZCfg.dexPathsDeps, frameworkJZCfg.dexPathsDeps...)
+		frameworkJZCfg.imageLocations = append(artJZCfg.imageLocations, frameworkJZCfg.imageLocations...)
+
 		return configs
 	}).(map[string]*bootImageConfig)
 }
@@ -243,8 +264,12 @@
 	return *genBootImageConfigs(ctx)[frameworkBootImageName]
 }
 
-func apexBootImageConfig(ctx android.PathContext) bootImageConfig {
-	return *genBootImageConfigs(ctx)[apexBootImageName]
+func artJZBootImageConfig(ctx android.PathContext) bootImageConfig {
+	return *genBootImageConfigs(ctx)[artJZBootImageName]
+}
+
+func frameworkJZBootImageConfig(ctx android.PathContext) bootImageConfig {
+	return *genBootImageConfigs(ctx)[frameworkJZBootImageName]
 }
 
 func defaultBootclasspath(ctx android.PathContext) []string {
diff --git a/java/java.go b/java/java.go
index a48b5a3..4c6a5a5 100644
--- a/java/java.go
+++ b/java/java.go
@@ -447,6 +447,7 @@
 	ExportedPlugins() (android.Paths, []string)
 	SrcJarArgs() ([]string, android.Paths)
 	BaseModuleName() string
+	JacocoReportClassesFile() android.Path
 }
 
 type SdkLibraryDependency interface {
@@ -499,6 +500,14 @@
 	usesLibTag            = dependencyTag{name: "uses-library"}
 )
 
+func IsLibDepTag(depTag blueprint.DependencyTag) bool {
+	return depTag == libTag
+}
+
+func IsStaticLibDepTag(depTag blueprint.DependencyTag) bool {
+	return depTag == staticLibTag
+}
+
 type sdkDep struct {
 	useModule, useFiles, useDefaultLibs, invalidVersion bool
 
@@ -618,12 +627,9 @@
 			}
 
 			linkType, _ := j.getLinkType(ctx.ModuleName())
-			if linkType == javaSystem {
+			// only platform modules can use internal props
+			if linkType != javaPlatform {
 				ret[idx] = stub
-			} else if linkType != javaPlatform {
-				ctx.PropertyErrorf("sdk_version",
-					"can't link against sysprop_library %q from a module using public or core API",
-					lib)
 			}
 		}
 
@@ -651,7 +657,14 @@
 		}
 	}
 
-	if j.shouldInstrumentStatic(ctx) {
+	// Framework libraries need special handling in static coverage builds: they should not have
+	// static dependency on jacoco, otherwise there would be multiple conflicting definitions of
+	// the same jacoco classes coming from different bootclasspath jars.
+	if inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
+		if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
+			j.properties.Instrument = true
+		}
+	} else if j.shouldInstrumentStatic(ctx) {
 		ctx.AddVariationDependencies(nil, staticLibTag, "jacocoagent")
 	}
 }
@@ -1454,12 +1467,6 @@
 		j.headerJarFile = j.implementationJarFile
 	}
 
-	if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
-		if inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
-			j.properties.Instrument = true
-		}
-	}
-
 	if j.shouldInstrument(ctx) {
 		outputFile = j.instrument(ctx, flags, outputFile, jarName)
 	}
@@ -1719,6 +1726,10 @@
 	return proptools.StringDefault(j.deviceProperties.Stem, j.Name())
 }
 
+func (j *Module) JacocoReportClassesFile() android.Path {
+	return j.jacocoReportClassesFile
+}
+
 //
 // Java libraries (.jar file)
 //
@@ -2295,6 +2306,10 @@
 	return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name())
 }
 
+func (a *Import) JacocoReportClassesFile() android.Path {
+	return nil
+}
+
 func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {
 	ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
 }
diff --git a/java/java_test.go b/java/java_test.go
index 30a8ca6..a2788cb 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1227,3 +1227,67 @@
 		checkPatchModuleFlag(t, ctx, "baz", expected)
 	})
 }
+
+func TestJavaSystemModules(t *testing.T) {
+	ctx, _ := testJava(t, `
+		java_system_modules {
+			name: "system-modules",
+			libs: ["system-module1", "system-module2"],
+		}
+		java_library {
+			name: "system-module1",
+			srcs: ["a.java"],
+			sdk_version: "none",
+			system_modules: "none",
+		}
+		java_library {
+			name: "system-module2",
+			srcs: ["b.java"],
+			sdk_version: "none",
+			system_modules: "none",
+		}
+		`)
+
+	// check the existence of the module
+	systemModules := ctx.ModuleForTests("system-modules", "android_common")
+
+	cmd := systemModules.Rule("jarsTosystemModules")
+
+	// make sure the command compiles against the supplied modules.
+	for _, module := range []string{"system-module1.jar", "system-module2.jar"} {
+		if !strings.Contains(cmd.Args["classpath"], module) {
+			t.Errorf("system modules classpath %v does not contain %q", cmd.Args["classpath"],
+				module)
+		}
+	}
+}
+
+func TestJavaSystemModulesImport(t *testing.T) {
+	ctx, _ := testJava(t, `
+		java_system_modules_import {
+			name: "system-modules",
+			libs: ["system-module1", "system-module2"],
+		}
+		java_import {
+			name: "system-module1",
+			jars: ["a.jar"],
+		}
+		java_import {
+			name: "system-module2",
+			jars: ["b.jar"],
+		}
+		`)
+
+	// check the existence of the module
+	systemModules := ctx.ModuleForTests("system-modules", "android_common")
+
+	cmd := systemModules.Rule("jarsTosystemModules")
+
+	// make sure the command compiles against the supplied modules.
+	for _, module := range []string{"system-module1.jar", "system-module2.jar"} {
+		if !strings.Contains(cmd.Args["classpath"], module) {
+			t.Errorf("system modules classpath %v does not contain %q", cmd.Args["classpath"],
+				module)
+		}
+	}
+}
diff --git a/java/jdeps.go b/java/jdeps.go
index fccc40f..49e3de3 100644
--- a/java/jdeps.go
+++ b/java/jdeps.go
@@ -17,7 +17,6 @@
 import (
 	"encoding/json"
 	"fmt"
-	"os"
 
 	"android/soong/android"
 )
@@ -92,23 +91,21 @@
 		moduleInfos[name] = dpInfo
 	})
 
-	jfpath := android.PathForOutput(ctx, jdepsJsonFileName).String()
+	jfpath := android.PathForOutput(ctx, jdepsJsonFileName)
 	err := createJsonFile(moduleInfos, jfpath)
 	if err != nil {
 		ctx.Errorf(err.Error())
 	}
 }
 
-func createJsonFile(moduleInfos map[string]android.IdeInfo, jfpath string) error {
-	file, err := os.Create(jfpath)
-	if err != nil {
-		return fmt.Errorf("Failed to create file: %s, relative: %v", jdepsJsonFileName, err)
-	}
-	defer file.Close()
+func createJsonFile(moduleInfos map[string]android.IdeInfo, jfpath android.WritablePath) error {
 	buf, err := json.MarshalIndent(moduleInfos, "", "\t")
 	if err != nil {
-		return fmt.Errorf("Write file failed: %s, relative: %v", jdepsJsonFileName, err)
+		return fmt.Errorf("JSON marshal of java deps failed: %s", err)
 	}
-	fmt.Fprintf(file, string(buf))
+	err = android.WriteFileToOutputDir(jfpath, buf, 0666)
+	if err != nil {
+		return fmt.Errorf("Writing java deps to %s failed: %s", jfpath.String(), err)
+	}
 	return nil
 }
diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go
index 715485f..d5c7579 100644
--- a/java/platform_compat_config.go
+++ b/java/platform_compat_config.go
@@ -80,6 +80,12 @@
 	p.metadata = outputPath
 }
 
+func (p *platformCompatConfigSingleton) MakeVars(ctx android.MakeVarsContext) {
+	if p.metadata != nil {
+		ctx.Strict("INTERNAL_PLATFORM_MERGED_COMPAT_CONFIG", p.metadata.String())
+	}
+}
+
 func (p *platformCompatConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	rule := android.NewRuleBuilder()
 
diff --git a/java/system_modules.go b/java/system_modules.go
index ed2fc18..92297c4 100644
--- a/java/system_modules.go
+++ b/java/system_modules.go
@@ -35,6 +35,7 @@
 
 func RegisterSystemModulesBuildComponents(ctx android.RegistrationContext) {
 	ctx.RegisterModuleType("java_system_modules", SystemModulesFactory)
+	ctx.RegisterModuleType("java_system_modules_import", systemModulesImportFactory)
 }
 
 var (
@@ -92,6 +93,9 @@
 	return outDir, outputs.Paths()
 }
 
+// java_system_modules creates a system module from a set of java libraries that can
+// be referenced from the system_modules property. It must contain at a minimum the
+// java.base module which must include classes from java.lang amongst other java packages.
 func SystemModulesFactory() android.Module {
 	module := &SystemModules{}
 	module.AddProperties(&module.properties)
@@ -157,3 +161,30 @@
 		},
 	}
 }
+
+// A prebuilt version of java_system_modules. It does not import the
+// generated system module, it generates the system module from imported
+// java libraries in the same way that java_system_modules does. It just
+// acts as a prebuilt, i.e. can have the same base name as another module
+// type and the one to use is selected at runtime.
+func systemModulesImportFactory() android.Module {
+	module := &systemModulesImport{}
+	module.AddProperties(&module.properties)
+	android.InitPrebuiltModule(module, &module.properties.Libs)
+	android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
+	android.InitDefaultableModule(module)
+	return module
+}
+
+type systemModulesImport struct {
+	SystemModules
+	prebuilt android.Prebuilt
+}
+
+func (system *systemModulesImport) Name() string {
+	return system.prebuilt.Name(system.ModuleBase.Name())
+}
+
+func (system *systemModulesImport) Prebuilt() *android.Prebuilt {
+	return &system.prebuilt
+}
diff --git a/python/python.go b/python/python.go
index c67c577..8b912be 100644
--- a/python/python.go
+++ b/python/python.go
@@ -340,6 +340,11 @@
 			// dependencies later.
 			ctx.AddFarVariationDependencies(ctx.Target().Variations(), launcherSharedLibTag, "libsqlite")
 
+			if ctx.Device() {
+				ctx.AddFarVariationDependencies(ctx.Target().Variations(), launcherSharedLibTag,
+					"liblog")
+			}
+
 			if ctx.Target().Os.Bionic() {
 				ctx.AddFarVariationDependencies(ctx.Target().Variations(), launcherSharedLibTag,
 					"libc", "libdl", "libm")
diff --git a/rust/config/global.go b/rust/config/global.go
index ad8eb3a..fb9b14b 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -29,7 +29,6 @@
 	DefaultEdition     = "2018"
 	Stdlibs            = []string{
 		"libstd",
-		"libterm",
 		"libtest",
 	}
 
diff --git a/rust/library.go b/rust/library.go
index 43819ce..0cf2dd0 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -323,6 +323,7 @@
 	return deps
 }
 func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
+	flags.RustFlags = append(flags.RustFlags, "-C metadata="+ctx.baseModuleName())
 	flags = library.baseCompiler.compilerFlags(ctx, flags)
 	if library.shared() || library.static() {
 		library.includeDirs = append(library.includeDirs, android.PathsForModuleSrc(ctx, library.Properties.Include_dirs)...)
@@ -337,7 +338,7 @@
 
 	flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
 
-	if library.dylib() || library.shared() {
+	if library.dylib() {
 		// We need prefer-dynamic for now to avoid linking in the static stdlib. See:
 		// https://github.com/rust-lang/rust/issues/19680
 		// https://github.com/rust-lang/rust/issues/34909
diff --git a/rust/rust.go b/rust/rust.go
index 0eab8d2..14513fb 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -346,6 +346,11 @@
 	return nil
 }
 
+func (mod *Module) AllStaticDeps() []string {
+	// TODO(jiyong): do this for rust?
+	return nil
+}
+
 func (mod *Module) Module() android.Module {
 	return mod
 }
diff --git a/scripts/test_config_fixer.py b/scripts/test_config_fixer.py
index 7bb4b52..32d5b17 100644
--- a/scripts/test_config_fixer.py
+++ b/scripts/test_config_fixer.py
@@ -37,6 +37,8 @@
                       help=('AndroidManifest.xml that contains the original package name'))
   parser.add_argument('--package-name', default='', dest='package_name',
                       help=('overwrite package fields in the test config'))
+  parser.add_argument('--test-file-name', default='', dest='test_file_name',
+                      help=('overwrite test file name in the test config'))
   parser.add_argument('input', help='input test config file')
   parser.add_argument('output', help='output test config file')
   return parser.parse_args()
@@ -46,7 +48,6 @@
 
   manifest = parse_manifest(manifest_doc)
   original_package = manifest.getAttribute('package')
-  print('package: ' + original_package)
 
   test_config = parse_test_config(test_config_doc)
   tests = get_children_with_tag(test_config, 'test')
@@ -57,6 +58,18 @@
       if option.getAttribute('name') == "package" and option.getAttribute('value') == original_package:
         option.setAttribute('value', package_name)
 
+def overwrite_test_file_name(test_config_doc, test_file_name):
+
+  test_config = parse_test_config(test_config_doc)
+  tests = get_children_with_tag(test_config, 'target_preparer')
+
+  for test in tests:
+    if test.getAttribute('class') == "com.android.tradefed.targetprep.TestAppInstallSetup":
+      options = get_children_with_tag(test, 'option')
+      for option in options:
+        if option.getAttribute('name') == "test-file-name":
+          option.setAttribute('value', test_file_name)
+
 def main():
   """Program entry point."""
   try:
@@ -70,6 +83,9 @@
       manifest_doc = minidom.parse(args.manifest)
       overwrite_package_name(doc, manifest_doc, args.package_name)
 
+    if args.test_file_name:
+      overwrite_test_file_name(doc, args.test_file_name)
+
     with open(args.output, 'wb') as f:
       write_xml(f, doc)
 
diff --git a/scripts/test_config_fixer_test.py b/scripts/test_config_fixer_test.py
index b90582e..1272c6b 100644
--- a/scripts/test_config_fixer_test.py
+++ b/scripts/test_config_fixer_test.py
@@ -67,5 +67,32 @@
     self.assertEqual(expected, output.getvalue())
 
 
+class OverwriteTestFileNameTest(unittest.TestCase):
+  """ Unit tests for overwrite_test_file_name function """
+
+  test_config = (
+      '<?xml version="1.0" encoding="utf-8"?>\n'
+      '<configuration description="Runs some tests.">\n'
+      '    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">\n'
+      '        <option name="test-file-name" value="%s"/>\n'
+      '    </target_preparer>\n'
+      '    <test class="com.android.tradefed.testtype.AndroidJUnitTest">\n'
+      '        <option name="package" value="com.android.foo"/>\n'
+      '        <option name="runtime-hint" value="20s"/>\n'
+      '    </test>\n'
+      '</configuration>\n')
+
+  def test_all(self):
+    doc = minidom.parseString(self.test_config % ("foo.apk"))
+
+    test_config_fixer.overwrite_test_file_name(doc, "bar.apk")
+    output = StringIO.StringIO()
+    test_config_fixer.write_xml(output, doc)
+
+    # Only the matching package name in a test node should be updated.
+    expected = self.test_config % ("bar.apk")
+    self.assertEqual(expected, output.getvalue())
+
+
 if __name__ == '__main__':
   unittest.main(verbosity=2)
diff --git a/sdk/bp.go b/sdk/bp.go
index 19fb70d..ae06a09 100644
--- a/sdk/bp.go
+++ b/sdk/bp.go
@@ -51,13 +51,23 @@
 	return s.properties[name]
 }
 
-func (s *bpPropertySet) copy() bpPropertySet {
+func (s *bpPropertySet) deepCopy() *bpPropertySet {
 	propertiesCopy := make(map[string]interface{})
 	for p, v := range s.properties {
-		propertiesCopy[p] = v
+		var valueCopy interface{}
+		if ps, ok := v.(*bpPropertySet); ok {
+			valueCopy = ps.deepCopy()
+		} else if values, ok := v.([]string); ok {
+			valuesCopy := make([]string, len(values))
+			copy(valuesCopy, values)
+			valueCopy = valuesCopy
+		} else {
+			valueCopy = v
+		}
+		propertiesCopy[p] = valueCopy
 	}
 
-	return bpPropertySet{
+	return &bpPropertySet{
 		properties: propertiesCopy,
 		order:      append([]string(nil), s.order...),
 	}
@@ -95,15 +105,15 @@
 }
 
 type bpModule struct {
-	bpPropertySet
+	*bpPropertySet
 	moduleType string
 }
 
 var _ android.BpModule = (*bpModule)(nil)
 
-func (m *bpModule) copy() *bpModule {
+func (m *bpModule) deepCopy() *bpModule {
 	return &bpModule{
-		bpPropertySet: m.bpPropertySet.copy(),
+		bpPropertySet: m.bpPropertySet.deepCopy(),
 		moduleType:    m.moduleType,
 	}
 }
@@ -134,8 +144,9 @@
 
 func (f *bpFile) newModule(moduleType string) *bpModule {
 	module := &bpModule{
-		moduleType: moduleType,
+		moduleType:    moduleType,
+		bpPropertySet: &bpPropertySet{},
 	}
-	(&module.bpPropertySet).init()
+	module.bpPropertySet.init()
 	return module
 }
diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
index 255ac08..9a75610 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -101,6 +101,11 @@
 			srcs: ["libfoo.so"],
 			system_shared_libs: [],
 			stl: "none",
+			// TODO: remove //apex_available:platform
+			apex_available: [
+				"//apex_available:platform",
+				"myapex",
+			],
 		}
 
 		cc_prebuilt_library_shared {
@@ -109,6 +114,11 @@
 			srcs: ["libfoo.so"],
 			system_shared_libs: [],
 			stl: "none",
+			// TODO: remove //apex_available:platform
+			apex_available: [
+				"//apex_available:platform",
+				"myapex2",
+			],
 		}
 
 		cc_library_shared {
@@ -117,6 +127,10 @@
 			shared_libs: ["sdkmember"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [
+				"myapex",
+				"myapex2",
+			],
 		}
 
 		apex {
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index 218a16a..692c205 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -73,6 +73,10 @@
 			sdk_version: "none",
 			compile_dex: true,
 			host_supported: true,
+			apex_available: [
+				"myapex",
+				"myapex2",
+			],
 		}
 
 		apex {
diff --git a/sdk/sdk.go b/sdk/sdk.go
index 44e5cbb..3b0752f 100644
--- a/sdk/sdk.go
+++ b/sdk/sdk.go
@@ -285,12 +285,15 @@
 
 // For dependencies from an in-development version of an SDK member to frozen versions of the same member
 // e.g. libfoo -> libfoo.mysdk.11 and libfoo.mysdk.12
-type sdkMemberVesionedDepTag struct {
+type sdkMemberVersionedDepTag struct {
 	dependencyTag
 	member  string
 	version string
 }
 
+// Mark this tag so dependencies that use it are excluded from visibility enforcement.
+func (t sdkMemberVersionedDepTag) ExcludeFromVisibilityEnforcement() {}
+
 // Step 1: create dependencies from an SDK module to its members.
 func memberMutator(mctx android.BottomUpMutatorContext) {
 	if s, ok := mctx.Module().(*sdk); ok {
@@ -337,7 +340,7 @@
 	if m, ok := mctx.Module().(android.SdkAware); ok && m.IsInAnySdk() {
 		if !m.ContainingSdk().Unversioned() {
 			memberName := m.MemberName()
-			tag := sdkMemberVesionedDepTag{member: memberName, version: m.ContainingSdk().Version}
+			tag := sdkMemberVersionedDepTag{member: memberName, version: m.ContainingSdk().Version}
 			mctx.AddReverseDependency(mctx.Module(), tag, memberName)
 		}
 	}
diff --git a/sdk/testing.go b/sdk/testing.go
index 8097889..c9cc30f 100644
--- a/sdk/testing.go
+++ b/sdk/testing.go
@@ -62,14 +62,12 @@
 	ctx := android.NewTestArchContext()
 
 	// from android package
-	ctx.PreArchMutators(android.RegisterPackageRenamer)
+	android.RegisterPackageBuildComponents(ctx)
 	ctx.PreArchMutators(android.RegisterVisibilityRuleChecker)
 	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
 	ctx.PreArchMutators(android.RegisterVisibilityRuleGatherer)
 	ctx.PostDepsMutators(android.RegisterVisibilityRuleEnforcer)
 
-	ctx.RegisterModuleType("package", android.PackageFactory)
-
 	// from java package
 	java.RegisterJavaBuildComponents(ctx)
 	java.RegisterAppBuildComponents(ctx)
diff --git a/sdk/update.go b/sdk/update.go
index 5bc3b83..2731d50 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -196,7 +196,7 @@
 
 	for _, unversioned := range builder.prebuiltOrder {
 		// Copy the unversioned module so it can be modified to make it versioned.
-		versioned := unversioned.copy()
+		versioned := unversioned.deepCopy()
 		name := versioned.properties["name"].(string)
 		versioned.setProperty("name", builder.versionedSdkMemberName(name))
 		versioned.insertAfter("name", "sdk_member_name", name)
@@ -286,7 +286,7 @@
 	for _, bpModule := range bpFile.order {
 		contents.Printfln("")
 		contents.Printfln("%s {", bpModule.moduleType)
-		outputPropertySet(contents, &bpModule.bpPropertySet)
+		outputPropertySet(contents, bpModule.bpPropertySet)
 		contents.Printfln("}")
 	}
 }
diff --git a/ui/build/build.go b/ui/build/build.go
index 1c2d864..69ef003 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -19,6 +19,8 @@
 	"os"
 	"path/filepath"
 	"text/template"
+
+	"android/soong/ui/metrics"
 )
 
 // Ensures the out directory exists, and has the proper files to prevent kati
@@ -139,6 +141,9 @@
 	ctx.Verboseln("Environment:", config.Environment().Environ())
 	ctx.Verbosef("Total RAM: %dGB", config.TotalRAM()/1024/1024/1024)
 
+	ctx.BeginTrace(metrics.Total, "total")
+	defer ctx.EndTrace()
+
 	if config.SkipMake() {
 		ctx.Verboseln("Skipping Make/Kati as requested")
 		what = what & (BuildSoong | BuildNinja)
diff --git a/ui/build/ninja.go b/ui/build/ninja.go
index 8c6ebb8..0b56b67 100644
--- a/ui/build/ninja.go
+++ b/ui/build/ninja.go
@@ -127,6 +127,7 @@
 			"GOMA_USE_LOCAL",
 
 			// RBE client
+			"FLAG_compare",
 			"FLAG_exec_root",
 			"FLAG_exec_strategy",
 			"FLAG_invocation_id",
diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
index 711a9c7..bfe662d 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -82,14 +82,11 @@
 	"fuser":    Allowed,
 	"getopt":   Allowed,
 	"git":      Allowed,
-	"gzcat":    Allowed,
-	"gzip":     Allowed,
 	"hexdump":  Allowed,
 	"jar":      Allowed,
 	"java":     Allowed,
 	"javap":    Allowed,
 	"lsof":     Allowed,
-	"m4":       Log,
 	"openssl":  Allowed,
 	"patch":    Allowed,
 	"pstree":   Allowed,
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 3388417..afbc073 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -119,6 +119,7 @@
 			"-j", strconv.Itoa(config.Parallel()),
 			"--frontend_file", fifo,
 			"-f", filepath.Join(config.SoongOutDir(), file))
+		cmd.Environment.Set("SOONG_SANDBOX_SOONG_BUILD", "true")
 		cmd.Sandbox = soongSandbox
 		cmd.RunAndStreamOrFatal()
 	}
diff --git a/ui/metrics/metrics.go b/ui/metrics/metrics.go
index 64bbbf3..8254e4a 100644
--- a/ui/metrics/metrics.go
+++ b/ui/metrics/metrics.go
@@ -30,6 +30,7 @@
 	RunSoong     = "soong"
 	PrimaryNinja = "ninja"
 	TestRun      = "test"
+	Total        = "total"
 )
 
 type Metrics struct {
@@ -56,6 +57,8 @@
 	case PrimaryNinja:
 		m.metrics.NinjaRuns = append(m.metrics.NinjaRuns, &perf)
 		break
+	case Total:
+		m.metrics.Total = &perf
 	default:
 		// ignored
 	}
diff --git a/ui/metrics/metrics_proto/metrics.pb.go b/ui/metrics/metrics_proto/metrics.pb.go
index 0fe5a0d..3986d0e 100644
--- a/ui/metrics/metrics_proto/metrics.pb.go
+++ b/ui/metrics/metrics_proto/metrics.pb.go
@@ -195,10 +195,12 @@
 	// The metrics for calling Soong.
 	SoongRuns []*PerfInfo `protobuf:"bytes,19,rep,name=soong_runs,json=soongRuns" json:"soong_runs,omitempty"`
 	// The metrics for calling Ninja.
-	NinjaRuns            []*PerfInfo `protobuf:"bytes,20,rep,name=ninja_runs,json=ninjaRuns" json:"ninja_runs,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}    `json:"-"`
-	XXX_unrecognized     []byte      `json:"-"`
-	XXX_sizecache        int32       `json:"-"`
+	NinjaRuns []*PerfInfo `protobuf:"bytes,20,rep,name=ninja_runs,json=ninjaRuns" json:"ninja_runs,omitempty"`
+	// The metrics for the whole build
+	Total                *PerfInfo `protobuf:"bytes,21,opt,name=total" json:"total,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}  `json:"-"`
+	XXX_unrecognized     []byte    `json:"-"`
+	XXX_sizecache        int32     `json:"-"`
 }
 
 func (m *MetricsBase) Reset()         { *m = MetricsBase{} }
@@ -371,6 +373,13 @@
 	return nil
 }
 
+func (m *MetricsBase) GetTotal() *PerfInfo {
+	if m != nil {
+		return m.Total
+	}
+	return nil
+}
+
 type PerfInfo struct {
 	// The description for the phase/action/part while the tool running.
 	Desc *string `protobuf:"bytes,1,opt,name=desc" json:"desc,omitempty"`
@@ -612,58 +621,58 @@
 func init() { proto.RegisterFile("metrics.proto", fileDescriptor_6039342a2ba47b72) }
 
 var fileDescriptor_6039342a2ba47b72 = []byte{
-	// 834 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0x6f, 0x6b, 0xdb, 0x46,
-	0x18, 0xaf, 0x62, 0x25, 0xb6, 0x1e, 0xc5, 0xae, 0x7a, 0xc9, 0xa8, 0xba, 0x12, 0x66, 0xc4, 0x3a,
-	0xf2, 0x62, 0x75, 0x8b, 0x29, 0xa1, 0x98, 0x32, 0x48, 0x1c, 0x53, 0xba, 0x60, 0xbb, 0x28, 0x71,
-	0x57, 0xb6, 0x17, 0x87, 0x22, 0x9d, 0x1b, 0x75, 0x96, 0x4e, 0xdc, 0x9d, 0xca, 0xfc, 0x21, 0xf6,
-	0x4d, 0xf6, 0xb5, 0xf6, 0x3d, 0xc6, 0x3d, 0x27, 0x39, 0x0a, 0x78, 0x34, 0xf4, 0xdd, 0xe9, 0xf9,
-	0xfd, 0xb9, 0xdf, 0x73, 0xd2, 0x3d, 0x82, 0x6e, 0xc6, 0x94, 0x48, 0x63, 0x39, 0x28, 0x04, 0x57,
-	0x9c, 0x1c, 0x48, 0xce, 0xf3, 0x4f, 0xf4, 0xba, 0x4c, 0x57, 0x09, 0xad, 0xa0, 0xe0, 0x1f, 0x07,
-	0xdc, 0xa9, 0x59, 0x9f, 0x45, 0x92, 0x91, 0x97, 0x70, 0x68, 0x08, 0x49, 0xa4, 0x18, 0x55, 0x69,
-	0xc6, 0xa4, 0x8a, 0xb2, 0xc2, 0xb7, 0xfa, 0xd6, 0x71, 0x2b, 0x24, 0x88, 0x9d, 0x47, 0x8a, 0x5d,
-	0xd5, 0x08, 0x79, 0x02, 0x1d, 0xa3, 0x48, 0x13, 0x7f, 0xa7, 0x6f, 0x1d, 0x3b, 0x61, 0x1b, 0x9f,
-	0xdf, 0x25, 0x64, 0x04, 0x4f, 0x8a, 0x55, 0xa4, 0x96, 0x5c, 0x64, 0xf4, 0x0b, 0x13, 0x32, 0xe5,
-	0x39, 0x8d, 0x79, 0xc2, 0xf2, 0x28, 0x63, 0x7e, 0x0b, 0xb9, 0x8f, 0x6b, 0xc2, 0x07, 0x83, 0x8f,
-	0x2b, 0x98, 0x3c, 0x83, 0x9e, 0x8a, 0xc4, 0x27, 0xa6, 0x68, 0x21, 0x78, 0x52, 0xc6, 0xca, 0xb7,
-	0x51, 0xd0, 0x35, 0xd5, 0xf7, 0xa6, 0x48, 0x12, 0x38, 0xac, 0x68, 0x26, 0xc4, 0x97, 0x48, 0xa4,
-	0x51, 0xae, 0xfc, 0xdd, 0xbe, 0x75, 0xdc, 0x1b, 0x3e, 0x1f, 0x6c, 0xe9, 0x79, 0xd0, 0xe8, 0x77,
-	0x70, 0xa6, 0x91, 0x0f, 0x46, 0x34, 0x6a, 0x4d, 0x66, 0x6f, 0x43, 0x62, 0xfc, 0x9a, 0x00, 0x99,
-	0x83, 0x5b, 0xed, 0x12, 0x89, 0xf8, 0xc6, 0xdf, 0x43, 0xf3, 0x67, 0x5f, 0x35, 0x3f, 0x15, 0xf1,
-	0xcd, 0xa8, 0xbd, 0x98, 0x5d, 0xcc, 0xe6, 0xbf, 0xcd, 0x42, 0x30, 0x16, 0xba, 0x48, 0x06, 0x70,
-	0xd0, 0x30, 0xdc, 0xa4, 0x6e, 0x63, 0x8b, 0x8f, 0x6e, 0x89, 0x75, 0x80, 0x9f, 0xa1, 0x8a, 0x45,
-	0xe3, 0xa2, 0xdc, 0xd0, 0x3b, 0x48, 0xf7, 0x0c, 0x32, 0x2e, 0xca, 0x9a, 0x7d, 0x01, 0xce, 0x0d,
-	0x97, 0x55, 0x58, 0xe7, 0x9b, 0xc2, 0x76, 0xb4, 0x01, 0x46, 0x0d, 0xa1, 0x8b, 0x66, 0xc3, 0x3c,
-	0x31, 0x86, 0xf0, 0x4d, 0x86, 0xae, 0x36, 0x19, 0xe6, 0x09, 0x7a, 0x3e, 0x86, 0x36, 0x7a, 0x72,
-	0xe9, 0xbb, 0xd8, 0xc3, 0x9e, 0x7e, 0x9c, 0x4b, 0x12, 0x54, 0x9b, 0x71, 0x49, 0xd9, 0x5f, 0x4a,
-	0x44, 0xfe, 0x3e, 0xc2, 0xae, 0x81, 0x27, 0xba, 0xb4, 0xe1, 0xc4, 0x82, 0x4b, 0xa9, 0x2d, 0xba,
-	0xb7, 0x9c, 0xb1, 0xae, 0xcd, 0x25, 0xf9, 0x09, 0x1e, 0x36, 0x38, 0x18, 0xbb, 0x67, 0x3e, 0x9f,
-	0x0d, 0x0b, 0x83, 0x3c, 0x87, 0x83, 0x06, 0x6f, 0xd3, 0xe2, 0x43, 0x73, 0xb0, 0x1b, 0x6e, 0x23,
-	0x37, 0x2f, 0x15, 0x4d, 0x52, 0xe1, 0x7b, 0x26, 0x37, 0x2f, 0xd5, 0x79, 0x2a, 0xc8, 0x2f, 0xe0,
-	0x4a, 0xa6, 0xca, 0x82, 0x2a, 0xce, 0x57, 0xd2, 0x7f, 0xd4, 0x6f, 0x1d, 0xbb, 0xc3, 0xa3, 0xad,
-	0x47, 0xf4, 0x9e, 0x89, 0xe5, 0xbb, 0x7c, 0xc9, 0x43, 0x40, 0xc5, 0x95, 0x16, 0x90, 0x11, 0x38,
-	0x7f, 0x46, 0x2a, 0xa5, 0xa2, 0xcc, 0xa5, 0x4f, 0xee, 0xa3, 0xee, 0x68, 0x7e, 0x58, 0xe6, 0x92,
-	0xbc, 0x01, 0x30, 0x4c, 0x14, 0x1f, 0xdc, 0x47, 0xec, 0x20, 0x5a, 0xab, 0xf3, 0x34, 0xff, 0x1c,
-	0x19, 0xf5, 0xe1, 0xbd, 0xd4, 0x28, 0xd0, 0xea, 0xe0, 0x25, 0xec, 0xdf, 0xb9, 0x28, 0x1d, 0xb0,
-	0x17, 0x97, 0x93, 0xd0, 0x7b, 0x40, 0xba, 0xe0, 0xe8, 0xd5, 0xf9, 0xe4, 0x6c, 0xf1, 0xd6, 0xb3,
-	0x48, 0x1b, 0xf4, 0xe5, 0xf2, 0x76, 0x82, 0x37, 0x60, 0xe3, 0x51, 0xba, 0x50, 0x7f, 0x1a, 0xde,
-	0x03, 0x8d, 0x9e, 0x86, 0x53, 0xcf, 0x22, 0x0e, 0xec, 0x9e, 0x86, 0xd3, 0x93, 0x57, 0xde, 0x8e,
-	0xae, 0x7d, 0x7c, 0x7d, 0xe2, 0xb5, 0x08, 0xc0, 0xde, 0xc7, 0xd7, 0x27, 0xf4, 0xe4, 0x95, 0x67,
-	0x07, 0x7f, 0x5b, 0xd0, 0xa9, 0x73, 0x10, 0x02, 0x76, 0xc2, 0x64, 0x8c, 0xb3, 0xc9, 0x09, 0x71,
-	0xad, 0x6b, 0x38, 0x5d, 0xcc, 0x24, 0xc2, 0x35, 0x39, 0x02, 0x90, 0x2a, 0x12, 0x0a, 0xc7, 0x19,
-	0xce, 0x1d, 0x3b, 0x74, 0xb0, 0xa2, 0xa7, 0x18, 0x79, 0x0a, 0x8e, 0x60, 0xd1, 0xca, 0xa0, 0x36,
-	0xa2, 0x1d, 0x5d, 0x40, 0xf0, 0x08, 0x20, 0x63, 0x19, 0x17, 0x6b, 0x5a, 0x4a, 0x86, 0x53, 0xc5,
-	0x0e, 0x1d, 0x53, 0x59, 0x48, 0x16, 0xfc, 0x6b, 0x41, 0x6f, 0xca, 0x93, 0x72, 0xc5, 0xae, 0xd6,
-	0x05, 0xc3, 0x54, 0x7f, 0xc0, 0xbe, 0x39, 0x37, 0xb9, 0x96, 0x8a, 0x65, 0x98, 0xae, 0x37, 0x7c,
-	0xb1, 0xfd, 0xba, 0xdc, 0x91, 0x9a, 0x61, 0x74, 0x89, 0xb2, 0xc6, 0xc5, 0xb9, 0xbe, 0xad, 0x92,
-	0x1f, 0xc0, 0xcd, 0x50, 0x43, 0xd5, 0xba, 0xa8, 0xbb, 0x84, 0x6c, 0x63, 0x43, 0x7e, 0x84, 0x5e,
-	0x5e, 0x66, 0x94, 0x2f, 0xa9, 0x29, 0x4a, 0xec, 0xb7, 0x1b, 0xee, 0xe7, 0x65, 0x36, 0x5f, 0x9a,
-	0xfd, 0x64, 0xf0, 0x02, 0xdc, 0xc6, 0x5e, 0x77, 0xdf, 0x85, 0x03, 0xbb, 0x97, 0xf3, 0xf9, 0x4c,
-	0xbf, 0xb4, 0x0e, 0xd8, 0xd3, 0xd3, 0x8b, 0x89, 0xb7, 0x13, 0xac, 0xe0, 0xfb, 0xb1, 0x48, 0x55,
-	0x1a, 0x47, 0xab, 0x85, 0x64, 0xe2, 0x57, 0x5e, 0x8a, 0x9c, 0xad, 0xab, 0xdb, 0xbe, 0x39, 0x74,
-	0xab, 0x71, 0xe8, 0x23, 0x68, 0x57, 0x5d, 0x62, 0x4a, 0x77, 0xd8, 0xff, 0xda, 0xc0, 0x08, 0x6b,
-	0x41, 0x70, 0x0d, 0x4f, 0xb7, 0xec, 0x26, 0xeb, 0xed, 0xc6, 0x60, 0xc7, 0xe5, 0x67, 0xe9, 0x5b,
-	0xf8, 0xb1, 0x6e, 0x3f, 0xd9, 0xff, 0x4f, 0x1b, 0xa2, 0xf8, 0xec, 0xbb, 0xdf, 0xab, 0xff, 0x61,
-	0xa5, 0xa0, 0xf8, 0x93, 0xfc, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x20, 0x07, 0xbc, 0xf0, 0x34, 0x07,
-	0x00, 0x00,
+	// 847 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0xdd, 0x6e, 0xdb, 0x36,
+	0x14, 0xae, 0x12, 0x25, 0xb6, 0x8e, 0x62, 0x57, 0x65, 0x52, 0x54, 0x5d, 0x11, 0xcc, 0x10, 0xd6,
+	0x21, 0x17, 0xab, 0x5b, 0x78, 0x45, 0x50, 0x18, 0xc5, 0x80, 0xc4, 0x31, 0x8a, 0x2e, 0xb0, 0x5d,
+	0x28, 0x71, 0x57, 0x6c, 0x17, 0x02, 0x23, 0xd1, 0x8d, 0x3a, 0x4b, 0x14, 0x48, 0xaa, 0x98, 0x1f,
+	0x62, 0x0f, 0xb9, 0x8b, 0xbd, 0xc7, 0xc0, 0x43, 0xc9, 0x51, 0x00, 0x0f, 0x09, 0x7a, 0x47, 0x9d,
+	0xef, 0x87, 0xdf, 0xa1, 0xc4, 0x23, 0xe8, 0x64, 0x4c, 0x89, 0x34, 0x96, 0xfd, 0x42, 0x70, 0xc5,
+	0xc9, 0xbe, 0xe4, 0x3c, 0xff, 0x1c, 0x5d, 0x95, 0xe9, 0x32, 0x89, 0x2a, 0x28, 0xf8, 0xc7, 0x01,
+	0x77, 0x62, 0xd6, 0xa7, 0x54, 0x32, 0xf2, 0x0a, 0x0e, 0x0c, 0x21, 0xa1, 0x8a, 0x45, 0x2a, 0xcd,
+	0x98, 0x54, 0x34, 0x2b, 0x7c, 0xab, 0x67, 0x1d, 0x6d, 0x87, 0x04, 0xb1, 0x33, 0xaa, 0xd8, 0x65,
+	0x8d, 0x90, 0xa7, 0xd0, 0x36, 0x8a, 0x34, 0xf1, 0xb7, 0x7a, 0xd6, 0x91, 0x13, 0xb6, 0xf0, 0xf9,
+	0x7d, 0x42, 0x86, 0xf0, 0xb4, 0x58, 0x52, 0xb5, 0xe0, 0x22, 0x8b, 0xbe, 0x32, 0x21, 0x53, 0x9e,
+	0x47, 0x31, 0x4f, 0x58, 0x4e, 0x33, 0xe6, 0x6f, 0x23, 0xf7, 0x49, 0x4d, 0xf8, 0x68, 0xf0, 0x51,
+	0x05, 0x93, 0xe7, 0xd0, 0x55, 0x54, 0x7c, 0x66, 0x2a, 0x2a, 0x04, 0x4f, 0xca, 0x58, 0xf9, 0x36,
+	0x0a, 0x3a, 0xa6, 0xfa, 0xc1, 0x14, 0x49, 0x02, 0x07, 0x15, 0xcd, 0x84, 0xf8, 0x4a, 0x45, 0x4a,
+	0x73, 0xe5, 0xef, 0xf4, 0xac, 0xa3, 0xee, 0xe0, 0x45, 0x7f, 0x43, 0xcf, 0xfd, 0x46, 0xbf, 0xfd,
+	0x53, 0x8d, 0x7c, 0x34, 0xa2, 0xe1, 0xf6, 0x78, 0xfa, 0x2e, 0x24, 0xc6, 0xaf, 0x09, 0x90, 0x19,
+	0xb8, 0xd5, 0x2e, 0x54, 0xc4, 0xd7, 0xfe, 0x2e, 0x9a, 0x3f, 0xbf, 0xd3, 0xfc, 0x44, 0xc4, 0xd7,
+	0xc3, 0xd6, 0x7c, 0x7a, 0x3e, 0x9d, 0xfd, 0x36, 0x0d, 0xc1, 0x58, 0xe8, 0x22, 0xe9, 0xc3, 0x7e,
+	0xc3, 0x70, 0x9d, 0xba, 0x85, 0x2d, 0x3e, 0xba, 0x21, 0xd6, 0x01, 0x7e, 0x82, 0x2a, 0x56, 0x14,
+	0x17, 0xe5, 0x9a, 0xde, 0x46, 0xba, 0x67, 0x90, 0x51, 0x51, 0xd6, 0xec, 0x73, 0x70, 0xae, 0xb9,
+	0xac, 0xc2, 0x3a, 0xdf, 0x14, 0xb6, 0xad, 0x0d, 0x30, 0x6a, 0x08, 0x1d, 0x34, 0x1b, 0xe4, 0x89,
+	0x31, 0x84, 0x6f, 0x32, 0x74, 0xb5, 0xc9, 0x20, 0x4f, 0xd0, 0xf3, 0x09, 0xb4, 0xd0, 0x93, 0x4b,
+	0xdf, 0xc5, 0x1e, 0x76, 0xf5, 0xe3, 0x4c, 0x92, 0xa0, 0xda, 0x8c, 0xcb, 0x88, 0xfd, 0xa5, 0x04,
+	0xf5, 0xf7, 0x10, 0x76, 0x0d, 0x3c, 0xd6, 0xa5, 0x35, 0x27, 0x16, 0x5c, 0x4a, 0x6d, 0xd1, 0xb9,
+	0xe1, 0x8c, 0x74, 0x6d, 0x26, 0xc9, 0x8f, 0xf0, 0xb0, 0xc1, 0xc1, 0xd8, 0x5d, 0xf3, 0xf9, 0xac,
+	0x59, 0x18, 0xe4, 0x05, 0xec, 0x37, 0x78, 0xeb, 0x16, 0x1f, 0x9a, 0x83, 0x5d, 0x73, 0x1b, 0xb9,
+	0x79, 0xa9, 0xa2, 0x24, 0x15, 0xbe, 0x67, 0x72, 0xf3, 0x52, 0x9d, 0xa5, 0x82, 0xfc, 0x02, 0xae,
+	0x64, 0xaa, 0x2c, 0x22, 0xc5, 0xf9, 0x52, 0xfa, 0x8f, 0x7a, 0xdb, 0x47, 0xee, 0xe0, 0x70, 0xe3,
+	0x11, 0x7d, 0x60, 0x62, 0xf1, 0x3e, 0x5f, 0xf0, 0x10, 0x50, 0x71, 0xa9, 0x05, 0x64, 0x08, 0xce,
+	0x9f, 0x54, 0xa5, 0x91, 0x28, 0x73, 0xe9, 0x93, 0xfb, 0xa8, 0xdb, 0x9a, 0x1f, 0x96, 0xb9, 0x24,
+	0x6f, 0x01, 0x0c, 0x13, 0xc5, 0xfb, 0xf7, 0x11, 0x3b, 0x88, 0xd6, 0xea, 0x3c, 0xcd, 0xbf, 0x50,
+	0xa3, 0x3e, 0xb8, 0x97, 0x1a, 0x05, 0xa8, 0xfe, 0x19, 0x76, 0x14, 0x57, 0x74, 0xe9, 0x3f, 0xee,
+	0x59, 0x77, 0x0b, 0x0d, 0x37, 0x78, 0x05, 0x7b, 0xb7, 0x6e, 0x57, 0x1b, 0xec, 0xf9, 0xc5, 0x38,
+	0xf4, 0x1e, 0x90, 0x0e, 0x38, 0x7a, 0x75, 0x36, 0x3e, 0x9d, 0xbf, 0xf3, 0x2c, 0xd2, 0x02, 0x7d,
+	0x23, 0xbd, 0xad, 0xe0, 0x2d, 0xd8, 0x78, 0xfe, 0x2e, 0xd4, 0xdf, 0x93, 0xf7, 0x40, 0xa3, 0x27,
+	0xe1, 0xc4, 0xb3, 0x88, 0x03, 0x3b, 0x27, 0xe1, 0xe4, 0xf8, 0xb5, 0xb7, 0xa5, 0x6b, 0x9f, 0xde,
+	0x1c, 0x7b, 0xdb, 0x04, 0x60, 0xf7, 0xd3, 0x9b, 0xe3, 0xe8, 0xf8, 0xb5, 0x67, 0x07, 0x7f, 0x5b,
+	0xd0, 0xae, 0x33, 0x10, 0x02, 0x76, 0xc2, 0x64, 0x8c, 0x03, 0xcd, 0x09, 0x71, 0xad, 0x6b, 0x38,
+	0x92, 0xcc, 0xf8, 0xc2, 0x35, 0x39, 0x04, 0x90, 0x8a, 0x0a, 0x85, 0x33, 0x10, 0x87, 0x95, 0x1d,
+	0x3a, 0x58, 0xd1, 0xa3, 0x8f, 0x3c, 0x03, 0x47, 0x30, 0xba, 0x34, 0xa8, 0x8d, 0x68, 0x5b, 0x17,
+	0x10, 0x3c, 0x04, 0xc8, 0x58, 0xc6, 0xc5, 0x2a, 0x2a, 0x25, 0xc3, 0x51, 0x64, 0x87, 0x8e, 0xa9,
+	0xcc, 0x25, 0x0b, 0xfe, 0xb5, 0xa0, 0x3b, 0xe1, 0x49, 0xb9, 0x64, 0x97, 0xab, 0x82, 0x61, 0xaa,
+	0x3f, 0x60, 0xcf, 0x9c, 0x99, 0x5c, 0x49, 0xc5, 0x32, 0x4c, 0xd7, 0x1d, 0xbc, 0xdc, 0x7c, 0xc7,
+	0x6e, 0x49, 0xcd, 0x04, 0xbb, 0x40, 0x59, 0xe3, 0xb6, 0x5d, 0xdd, 0x54, 0xc9, 0xf7, 0xe0, 0x66,
+	0xa8, 0x89, 0xd4, 0xaa, 0xa8, 0xbb, 0x84, 0x6c, 0x6d, 0x43, 0x7e, 0x80, 0x6e, 0x5e, 0x66, 0x11,
+	0x5f, 0x44, 0xa6, 0x28, 0xb1, 0xdf, 0x4e, 0xb8, 0x97, 0x97, 0xd9, 0x6c, 0x61, 0xf6, 0x93, 0xc1,
+	0x4b, 0x70, 0x1b, 0x7b, 0xdd, 0x7e, 0x17, 0x0e, 0xec, 0x5c, 0xcc, 0x66, 0x53, 0xfd, 0xd2, 0xda,
+	0x60, 0x4f, 0x4e, 0xce, 0xc7, 0xde, 0x56, 0xb0, 0x84, 0xef, 0x46, 0x22, 0x55, 0x69, 0x4c, 0x97,
+	0x73, 0xc9, 0xc4, 0xaf, 0xbc, 0x14, 0x39, 0x5b, 0x55, 0x23, 0x62, 0x7d, 0xe8, 0x56, 0xe3, 0xd0,
+	0x87, 0xd0, 0xaa, 0xba, 0xc4, 0x94, 0xee, 0xa0, 0x77, 0xd7, 0x94, 0x09, 0x6b, 0x41, 0x70, 0x05,
+	0xcf, 0x36, 0xec, 0x26, 0xeb, 0xed, 0x46, 0x60, 0xc7, 0xe5, 0x17, 0xe9, 0x5b, 0xf8, 0x85, 0x6f,
+	0x3e, 0xd9, 0xff, 0x4f, 0x1b, 0xa2, 0xf8, 0xf4, 0xf1, 0xef, 0xd5, 0x4f, 0xb4, 0x52, 0x44, 0xf8,
+	0x67, 0xfd, 0x2f, 0x00, 0x00, 0xff, 0xff, 0xc4, 0xbd, 0xe2, 0xb1, 0x69, 0x07, 0x00, 0x00,
 }
diff --git a/ui/metrics/metrics_proto/metrics.proto b/ui/metrics/metrics_proto/metrics.proto
index 1ea24bf..194aa6b 100644
--- a/ui/metrics/metrics_proto/metrics.proto
+++ b/ui/metrics/metrics_proto/metrics.proto
@@ -89,6 +89,9 @@
 
   // The metrics for calling Ninja.
   repeated PerfInfo ninja_runs = 20;
+
+  // The metrics for the whole build
+  optional PerfInfo total = 21;
 }
 
 message PerfInfo {