Merge "Make 'file_contexts' prop as `android:"path"`"
diff --git a/android/makevars.go b/android/makevars.go
index c011ea6..38a028c 100644
--- a/android/makevars.go
+++ b/android/makevars.go
@@ -80,6 +80,12 @@
 	// Eval().
 	StrictRaw(name, value string)
 	CheckRaw(name, value string)
+
+	// GlobWithDeps returns a list of files that match the specified pattern but do not match any
+	// of the patterns in excludes.  It also adds efficient dependencies to rerun the primary
+	// 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)
 }
 
 var _ PathContext = MakeVarsContext(nil)
diff --git a/android/module.go b/android/module.go
index fa6388c..891babc 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1771,7 +1771,7 @@
 }
 
 // A module that implements OutputFileProducer can be referenced from any property that is tagged with `android:"path"`
-// using the ":module" syntax or ":module{.tag}" syntax and provides a list of otuput files to be used as if they were
+// using the ":module" syntax or ":module{.tag}" syntax and provides a list of output files to be used as if they were
 // listed in the property.
 type OutputFileProducer interface {
 	OutputFiles(tag string) (Paths, error)
diff --git a/android/sh_binary.go b/android/sh_binary.go
index 6db9892..2b649c4 100644
--- a/android/sh_binary.go
+++ b/android/sh_binary.go
@@ -196,6 +196,9 @@
 // executable binary to <partition>/bin.
 func ShBinaryFactory() Module {
 	module := &ShBinary{}
+	module.Prefer32(func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool {
+		return class == Device && ctx.Config().DevicePrefer32BitExecutables()
+	})
 	InitShBinaryModule(module)
 	InitAndroidArchModule(module, HostAndDeviceSupported, MultilibFirst)
 	return module
diff --git a/apex/apex.go b/apex/apex.go
index c19c9eb..b35b73e 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -592,10 +592,6 @@
 				a.properties.Multilib.First.Tests,
 				target,
 				a.getImageVariation(config))
-
-			// When multilib.* is omitted for prebuilts, it implies multilib.first.
-			ctx.AddFarVariationDependencies(target.Variations(),
-				prebuiltTag, a.properties.Prebuilts...)
 		}
 
 		switch target.Arch.ArchType.Multilib {
@@ -646,6 +642,22 @@
 
 	}
 
+	// For prebuilt_etc, use the first variant (64 on 64/32bit device,
+	// 32 on 32bit device) regardless of the TARGET_PREFER_* setting.
+	// b/144532908
+	archForPrebuiltEtc := config.Arches()[0]
+	for _, arch := range config.Arches() {
+		// Prefer 64-bit arch if there is any
+		if arch.ArchType.Multilib == "lib64" {
+			archForPrebuiltEtc = arch
+			break
+		}
+	}
+	ctx.AddFarVariationDependencies([]blueprint.Variation{
+		{Mutator: "os", Variation: ctx.Os().String()},
+		{Mutator: "arch", Variation: archForPrebuiltEtc.String()},
+	}, prebuiltTag, a.properties.Prebuilts...)
+
 	ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(),
 		javaLibTag, a.properties.Java_libs...)
 
diff --git a/cc/cc.go b/cc/cc.go
index 06617ad..aa656da 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -562,6 +562,10 @@
 	return false
 }
 
+func (c *Module) NonCcVariants() bool {
+	return false
+}
+
 func (c *Module) SetBuildStubs() {
 	if c.linker != nil {
 		if library, ok := c.linker.(*libraryDecorator); ok {
@@ -890,7 +894,7 @@
 
 func isBionic(name string) bool {
 	switch name {
-	case "libc", "libm", "libdl", "linker":
+	case "libc", "libm", "libdl", "libdl_android", "linker":
 		return true
 	}
 	return false
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 476d805..bb89bb4 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -117,45 +117,46 @@
 // incorrectly use the core libraries (sanitizer runtimes, libc, libdl, etc.)
 // from a dependency. This may cause issues when dependencies have explicit
 // sanitizer tags, as we may get a dependency on an unsanitized libc, etc.
-func collectAllSharedDependencies(
-	module android.Module,
-	sharedDeps map[string]android.Path,
-	ctx android.SingletonContext) {
+func collectAllSharedDependencies(ctx android.SingletonContext, module android.Module) android.Paths {
 	var fringe []android.Module
 
+	seen := make(map[android.Module]bool)
+
 	// Enumerate the first level of dependencies, as we discard all non-library
 	// modules in the BFS loop below.
 	ctx.VisitDirectDeps(module, func(dep android.Module) {
-		if isValidSharedDependency(dep, sharedDeps) {
+		if isValidSharedDependency(dep) {
 			fringe = append(fringe, dep)
 		}
 	})
 
+	var sharedLibraries android.Paths
+
 	for i := 0; i < len(fringe); i++ {
 		module := fringe[i]
-		if _, exists := sharedDeps[module.Name()]; exists {
+		if seen[module] {
 			continue
 		}
+		seen[module] = true
 
 		ccModule := module.(*Module)
-		sharedDeps[ccModule.Name()] = ccModule.UnstrippedOutputFile()
+		sharedLibraries = append(sharedLibraries, ccModule.UnstrippedOutputFile())
 		ctx.VisitDirectDeps(module, func(dep android.Module) {
-			if isValidSharedDependency(dep, sharedDeps) {
+			if isValidSharedDependency(dep) && !seen[dep] {
 				fringe = append(fringe, dep)
 			}
 		})
 	}
+
+	return sharedLibraries
 }
 
 // This function takes a module and determines if it is a unique shared library
 // that should be installed in the fuzz target output directories. This function
 // returns true, unless:
-//  - The module already exists in `sharedDeps`, or
 //  - The module is not a shared library, or
 //  - The module is a header, stub, or vendor-linked library.
-func isValidSharedDependency(
-	dependency android.Module,
-	sharedDeps map[string]android.Path) bool {
+func isValidSharedDependency(dependency android.Module) bool {
 	// TODO(b/144090547): We should be parsing these modules using
 	// ModuleDependencyTag instead of the current brute-force checking.
 
@@ -177,10 +178,6 @@
 		}
 	}
 
-	// If this library has already been traversed, we don't need to do any more work.
-	if _, exists := sharedDeps[dependency.Name()]; exists {
-		return false
-	}
 	return true
 }
 
@@ -236,10 +233,16 @@
 	}
 
 	// Grab the list of required shared libraries.
-	sharedLibraries := make(map[string]android.Path)
+	seen := make(map[android.Module]bool)
+	var sharedLibraries android.Paths
 	ctx.WalkDeps(func(child, parent android.Module) bool {
-		if isValidSharedDependency(child, sharedLibraries) {
-			sharedLibraries[child.Name()] = child.(*Module).UnstrippedOutputFile()
+		if seen[child] {
+			return false
+		}
+		seen[child] = true
+
+		if isValidSharedDependency(child) {
+			sharedLibraries = append(sharedLibraries, child.(*Module).UnstrippedOutputFile())
 			return true
 		}
 		return false
@@ -250,8 +253,6 @@
 			sharedLibraryInstallLocation(
 				lib, ctx.Host(), ctx.Arch().ArchType.String()))
 	}
-
-	sort.Strings(fuzz.installedSharedDeps)
 }
 
 func NewFuzz(hod android.HostOrDeviceSupported) *Module {
@@ -305,19 +306,21 @@
 	DestinationPathPrefix string
 }
 
-type archAndLibraryKey struct {
-	ArchDir android.OutputPath
-	Library android.Path
+type archOs struct {
+	hostOrTarget string
+	arch         string
+	dir          string
 }
 
 func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
 	// Map between each architecture + host/device combination, and the files that
 	// need to be packaged (in the tuple of {source file, destination folder in
 	// archive}).
-	archDirs := make(map[android.OutputPath][]fileToZip)
+	archDirs := make(map[archOs][]fileToZip)
 
-	// List of shared library dependencies for each architecture + host/device combo.
-	archSharedLibraryDeps := make(map[archAndLibraryKey]bool)
+	// Map tracking whether each shared library has an install rule to avoid duplicate install rules from
+	// multiple fuzzers that depend on the same shared library.
+	sharedLibraryInstalled := make(map[string]bool)
 
 	// List of individual fuzz targets, so that 'make fuzz' also installs the targets
 	// to the correct output directories as well.
@@ -351,10 +354,10 @@
 
 		archString := ccModule.Arch().ArchType.String()
 		archDir := android.PathForIntermediates(ctx, "fuzz", hostOrTargetString, archString)
+		archOs := archOs{hostOrTarget: hostOrTargetString, arch: archString, dir: archDir.String()}
 
 		// Grab the list of required shared libraries.
-		sharedLibraries := make(map[string]android.Path)
-		collectAllSharedDependencies(module, sharedLibraries, ctx)
+		sharedLibraries := collectAllSharedDependencies(ctx, module)
 
 		var files []fileToZip
 		builder := android.NewRuleBuilder()
@@ -374,16 +377,15 @@
 		for _, library := range sharedLibraries {
 			files = append(files, fileToZip{library, "lib"})
 
-			if _, exists := archSharedLibraryDeps[archAndLibraryKey{archDir, library}]; exists {
-				continue
-			}
-
 			// For each architecture-specific shared library dependency, we need to
 			// install it to the output directory. Setup the install destination here,
 			// which will be used by $(copy-many-files) in the Make backend.
-			archSharedLibraryDeps[archAndLibraryKey{archDir, library}] = true
 			installDestination := sharedLibraryInstallLocation(
 				library, ccModule.Host(), archString)
+			if sharedLibraryInstalled[installDestination] {
+				continue
+			}
+			sharedLibraryInstalled[installDestination] = true
 			// Escape all the variables, as the install destination here will be called
 			// via. $(eval) in Make.
 			installDestination = strings.ReplaceAll(
@@ -421,12 +423,19 @@
 		builder.Build(pctx, ctx, "create-"+fuzzZip.String(),
 			"Package "+module.Name()+" for "+archString+"-"+hostOrTargetString)
 
-		archDirs[archDir] = append(archDirs[archDir], fileToZip{fuzzZip, ""})
+		archDirs[archOs] = append(archDirs[archOs], fileToZip{fuzzZip, ""})
 	})
 
-	for archDir, filesToZip := range archDirs {
-		arch := archDir.Base()
-		hostOrTarget := filepath.Base(filepath.Dir(archDir.String()))
+	var archOsList []archOs
+	for archOs := range archDirs {
+		archOsList = append(archOsList, archOs)
+	}
+	sort.Slice(archOsList, func(i, j int) bool { return archOsList[i].dir < archOsList[j].dir })
+
+	for _, archOs := range archOsList {
+		filesToZip := archDirs[archOs]
+		arch := archOs.arch
+		hostOrTarget := archOs.hostOrTarget
 		builder := android.NewRuleBuilder()
 		outputFile := android.PathForOutput(ctx, "fuzz-"+hostOrTarget+"-"+arch+".zip")
 		s.packages = append(s.packages, outputFile)
diff --git a/cc/library.go b/cc/library.go
index dde067c..b8c4b51 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -1262,13 +1262,15 @@
 			shared.linker.(prebuiltLibraryInterface).disablePrebuilt()
 		}
 	} else if library, ok := mctx.Module().(LinkableInterface); ok && library.CcLibraryInterface() {
-		if library.BuildStaticVariant() && library.BuildSharedVariant() {
-			variations := []string{"static", "shared"}
 
-			// Non-cc.Modules need an empty variant for their mutators.
-			if _, ok := mctx.Module().(*Module); !ok {
-				variations = append(variations, "")
-			}
+		// Non-cc.Modules may need an empty variant for their mutators.
+		variations := []string{}
+		if library.NonCcVariants() {
+			variations = append(variations, "")
+		}
+
+		if library.BuildStaticVariant() && library.BuildSharedVariant() {
+			variations := append([]string{"static", "shared"}, variations...)
 
 			modules := mctx.CreateLocalVariations(variations...)
 			static := modules[0].(LinkableInterface)
@@ -1281,16 +1283,18 @@
 				reuseStaticLibrary(mctx, static.(*Module), shared.(*Module))
 			}
 		} else if library.BuildStaticVariant() {
-			modules := mctx.CreateLocalVariations("static")
+			variations := append([]string{"static"}, variations...)
+
+			modules := mctx.CreateLocalVariations(variations...)
 			modules[0].(LinkableInterface).SetStatic()
 		} else if library.BuildSharedVariant() {
-			modules := mctx.CreateLocalVariations("shared")
-			modules[0].(LinkableInterface).SetShared()
-		} else if _, ok := mctx.Module().(*Module); !ok {
-			// Non-cc.Modules need an empty variant for their mutators.
-			mctx.CreateLocalVariations("")
-		}
+			variations := append([]string{"shared"}, variations...)
 
+			modules := mctx.CreateLocalVariations(variations...)
+			modules[0].(LinkableInterface).SetShared()
+		} else if len(variations) > 0 {
+			mctx.CreateLocalVariations(variations...)
+		}
 	}
 }
 
diff --git a/cc/linkable.go b/cc/linkable.go
index 2efefea..815d405 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -20,6 +20,8 @@
 	HasStaticVariant() bool
 	GetStaticVariant() LinkableInterface
 
+	NonCcVariants() bool
+
 	StubsVersions() []string
 	BuildStubs() bool
 	SetBuildStubs()
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index b75c4c8..c47cbf0 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -269,6 +269,10 @@
 		// (avoids the need to link an unwinder into a fake library).
 		"-fno-unwind-tables",
 	)
+	// All symbols in the stubs library should be visible.
+	if inList("-fvisibility=hidden", flags.Local.CFlags) {
+		flags.Local.CFlags = append(flags.Local.CFlags, "-fvisibility=default")
+	}
 	return flags
 }
 
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index 9215eff..f38d892 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -44,9 +44,10 @@
 	ProductUpdatableBootModules   []string
 	ProductUpdatableBootLocations []string
 
-	SystemServerJars []string // jars that form the system server
-	SystemServerApps []string // apps that are loaded into system server
-	SpeedApps        []string // apps that should be speed optimized
+	SystemServerJars          []string // jars that form the system server
+	SystemServerApps          []string // apps that are loaded into system server
+	UpdatableSystemServerJars []string // jars within apex that are loaded into system server
+	SpeedApps                 []string // apps that should be speed optimized
 
 	PreoptFlags []string // global dex2oat flags that should be used if no module-specific dex2oat flags are specified
 
@@ -285,6 +286,7 @@
 		ProductUpdatableBootLocations:      nil,
 		SystemServerJars:                   nil,
 		SystemServerApps:                   nil,
+		UpdatableSystemServerJars:          nil,
 		SpeedApps:                          nil,
 		PreoptFlags:                        nil,
 		DefaultCompilerFilter:              "",
diff --git a/java/app.go b/java/app.go
index e1128c9..c635703 100644
--- a/java/app.go
+++ b/java/app.go
@@ -448,7 +448,7 @@
 	} else if a.Privileged() {
 		a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName)
 	} else if ctx.InstallInTestcases() {
-		a.installDir = android.PathForModuleInstall(ctx, a.installApkName)
+		a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch())
 	} else {
 		a.installDir = android.PathForModuleInstall(ctx, "app", a.installApkName)
 	}
@@ -697,6 +697,10 @@
 	appTestHelperAppProperties appTestHelperAppProperties
 }
 
+func (a *AndroidTestHelperApp) InstallInTestcases() bool {
+	return true
+}
+
 // android_test_helper_app compiles sources and Android resources into an Android application package `.apk` file that
 // will be used by tests, but does not produce an `AndroidTest.xml` file so the module will not be run directly as a
 // test.
diff --git a/java/app_test.go b/java/app_test.go
index 2a4c4ec..7e461bc 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -1159,7 +1159,7 @@
 	}{
 		{
 			variantName:       "android_common",
-			apkPath:           "/target/product/test_device/testcases/foo_test/foo_test.apk",
+			apkPath:           "/target/product/test_device/testcases/foo_test/arm64/foo_test.apk",
 			overrides:         nil,
 			targetVariant:     "android_common",
 			packageFlag:       "",
@@ -1167,7 +1167,7 @@
 		},
 		{
 			variantName:       "android_common_bar_test",
-			apkPath:           "/target/product/test_device/testcases/bar_test/bar_test.apk",
+			apkPath:           "/target/product/test_device/testcases/bar_test/arm64/bar_test.apk",
 			overrides:         []string{"foo_test"},
 			targetVariant:     "android_common_bar",
 			packageFlag:       "com.android.bar.test",
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index a6661b3..15f11e1 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -15,6 +15,7 @@
 package java
 
 import (
+	"fmt"
 	"path/filepath"
 	"strings"
 
@@ -65,6 +66,16 @@
 var dexpreoptGlobalConfigKey = android.NewOnceKey("DexpreoptGlobalConfig")
 var dexpreoptTestGlobalConfigKey = android.NewOnceKey("TestDexpreoptGlobalConfig")
 
+// Expected format for apexJarValue = <apex name>:<jar name>
+func splitApexJarPair(apexJarValue string) (string, string)  {
+	var apexJarPair []string = strings.SplitN(apexJarValue, ":", 2)
+	if apexJarPair == nil || len(apexJarPair) != 2 {
+		panic(fmt.Errorf("malformed apexJarValue: %q, expected format: <apex>:<jar>",
+			apexJarValue))
+	}
+	return apexJarPair[0], apexJarPair[1]
+}
+
 // systemServerClasspath returns the on-device locations of the modules in the system server classpath.  It is computed
 // once the first time it is called for any ctx.Config(), and returns the same slice for all future calls with the same
 // ctx.Config().
@@ -77,6 +88,11 @@
 			systemServerClasspathLocations = append(systemServerClasspathLocations,
 				filepath.Join("/system/framework", m+".jar"))
 		}
+		for _, m := range global.UpdatableSystemServerJars {
+			apex, jar := splitApexJarPair(m)
+			systemServerClasspathLocations = append(systemServerClasspathLocations,
+				filepath.Join("/apex", apex, "javalib", jar + ".jar"))
+		}
 		return systemServerClasspathLocations
 	})
 }
diff --git a/rust/builder.go b/rust/builder.go
index 9109651..27eeec2 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -44,6 +44,8 @@
 
 func TransformSrcToBinary(ctx android.ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
 	outputFile android.WritablePath, includeDirs []string) {
+	flags.RustFlags = append(flags.RustFlags, "-C lto")
+
 	transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "bin", includeDirs)
 }
 
@@ -59,11 +61,13 @@
 
 func TransformSrctoStatic(ctx android.ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
 	outputFile android.WritablePath, includeDirs []string) {
+	flags.RustFlags = append(flags.RustFlags, "-C lto")
 	transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "staticlib", includeDirs)
 }
 
 func TransformSrctoShared(ctx android.ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
 	outputFile android.WritablePath, includeDirs []string) {
+	flags.RustFlags = append(flags.RustFlags, "-C lto")
 	transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "cdylib", includeDirs)
 }
 
diff --git a/rust/config/global.go b/rust/config/global.go
index 7846d21..4d87780 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -37,6 +37,9 @@
 
 	GlobalRustFlags = []string{
 		"--remap-path-prefix $$(pwd)=",
+		"-C codegen-units=1",
+		"-C opt-level=3",
+		"-C relocation-model=pic",
 	}
 
 	deviceGlobalRustFlags = []string{}
diff --git a/rust/library.go b/rust/library.go
index 386ea47..ba47541 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -19,6 +19,7 @@
 	"strings"
 
 	"android/soong/android"
+	"android/soong/rust/config"
 )
 
 func init() {
@@ -304,6 +305,15 @@
 }
 
 func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
+
+	// TODO(b/144861059) Remove if C libraries support dylib linkage in the future.
+	if !ctx.Host() && (library.static() || library.shared()) {
+		library.setNoStdlibs()
+		for _, stdlib := range config.Stdlibs {
+			deps.Rlibs = append(deps.Rlibs, stdlib+".static")
+		}
+	}
+
 	deps = library.baseCompiler.compilerDeps(ctx, deps)
 
 	if ctx.toolchain().Bionic() && (library.dylib() || library.shared()) {
diff --git a/rust/rust.go b/rust/rust.go
index 8782f8e..096f7b6 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -89,6 +89,19 @@
 	return ""
 }
 
+func (mod *Module) NonCcVariants() bool {
+	if mod.compiler != nil {
+		if library, ok := mod.compiler.(libraryInterface); ok {
+			if library.buildRlib() || library.buildDylib() {
+				return true
+			} else {
+				return false
+			}
+		}
+	}
+	panic(fmt.Errorf("NonCcVariants called on non-library module: %q", mod.BaseModuleName()))
+}
+
 func (mod *Module) ApiLevel() string {
 	panic(fmt.Errorf("Called ApiLevel on Rust module %q; stubs libraries are not yet supported.", mod.BaseModuleName()))
 }