Merge changes I6f80b7b3,Ida8f046c

* changes:
  Don't dexpreopt when compile_dex but not installable
  Don't dexpreopt or strip java_test modules
diff --git a/androidmk/cmd/androidmk/android.go b/androidmk/cmd/androidmk/android.go
index 99b3523..d16ac93 100644
--- a/androidmk/cmd/androidmk/android.go
+++ b/androidmk/cmd/androidmk/android.go
@@ -144,6 +144,7 @@
 			"LOCAL_AAPT_FLAGS":            "aaptflags",
 			"LOCAL_PACKAGE_SPLITS":        "package_splits",
 			"LOCAL_COMPATIBILITY_SUITE":   "test_suites",
+			"LOCAL_OVERRIDES_PACKAGES":    "overrides",
 
 			"LOCAL_ANNOTATION_PROCESSORS":        "annotation_processors",
 			"LOCAL_ANNOTATION_PROCESSOR_CLASSES": "annotation_processor_classes",
@@ -738,27 +739,31 @@
 		true: "product_variables.pdk"},
 }
 
-func mydir(args []string) string {
-	return "."
+func mydir(args []string) []string {
+	return []string{"."}
 }
 
-func allFilesUnder(wildcard string) func(args []string) string {
-	return func(args []string) string {
-		dir := ""
+func allFilesUnder(wildcard string) func(args []string) []string {
+	return func(args []string) []string {
+		dirs := []string{""}
 		if len(args) > 0 {
-			dir = strings.TrimSpace(args[0])
+			dirs = strings.Fields(args[0])
 		}
 
-		return fmt.Sprintf("%s/**/"+wildcard, dir)
+		paths := make([]string, len(dirs))
+		for i := range paths {
+			paths[i] = fmt.Sprintf("%s/**/"+wildcard, dirs[i])
+		}
+		return paths
 	}
 }
 
-func allSubdirJavaFiles(args []string) string {
-	return "**/*.java"
+func allSubdirJavaFiles(args []string) []string {
+	return []string{"**/*.java"}
 }
 
-func includeIgnored(args []string) string {
-	return include_ignored
+func includeIgnored(args []string) []string {
+	return []string{include_ignored}
 }
 
 var moduleTypes = map[string]string{
diff --git a/androidmk/cmd/androidmk/androidmk_test.go b/androidmk/cmd/androidmk/androidmk_test.go
index 0f6c5ac..40fc9f3 100644
--- a/androidmk/cmd/androidmk/androidmk_test.go
+++ b/androidmk/cmd/androidmk/androidmk_test.go
@@ -554,6 +554,10 @@
 			LOCAL_SRC_FILES := d.java
 			LOCAL_UNINSTALLABLE_MODULE := false
 			include $(BUILD_JAVA_LIBRARY)
+
+			include $(CLEAR_VARS)
+			LOCAL_SRC_FILES := $(call all-java-files-under, src gen)
+			include $(BUILD_STATIC_JAVA_LIBRARY)
 		`,
 		expected: `
 			java_library {
@@ -574,6 +578,13 @@
 				installable: true,
 				srcs: ["d.java"],
 			}
+
+			java_library {
+				srcs: [
+					"src/**/*.java",
+					"gen/**/*.java",
+				],
+			}
 		`,
 	},
 	{
diff --git a/androidmk/cmd/androidmk/values.go b/androidmk/cmd/androidmk/values.go
index d240a01..90f2e74 100644
--- a/androidmk/cmd/androidmk/values.go
+++ b/androidmk/cmd/androidmk/values.go
@@ -29,6 +29,14 @@
 	}
 }
 
+func stringListToStringValueList(list []string) []bpparser.Expression {
+	valList := make([]bpparser.Expression, len(list))
+	for i, l := range list {
+		valList[i] = stringToStringValue(l)
+	}
+	return valList
+}
+
 func addValues(val1, val2 bpparser.Expression) (bpparser.Expression, error) {
 	if val1 == nil {
 		return val2, nil
@@ -63,7 +71,10 @@
 
 	for i, s := range ms.Strings[1:] {
 		if ret, ok := ms.Variables[i].EvalFunction(scope); ok {
-			val, err = addValues(val, stringToStringValue(ret))
+			if len(ret) > 1 {
+				return nil, fmt.Errorf("Unexpected list value %s", ms.Dump())
+			}
+			val, err = addValues(val, stringToStringValue(ret[0]))
 		} else {
 			name := ms.Variables[i].Name
 			if !name.Const() {
@@ -125,9 +136,7 @@
 	for _, f := range fields {
 		if len(f.Variables) == 1 && f.Strings[0] == "" && f.Strings[1] == "" {
 			if ret, ok := f.Variables[0].EvalFunction(scope); ok {
-				listValue.Values = append(listValue.Values, &bpparser.String{
-					Value: ret,
-				})
+				listValue.Values = append(listValue.Values, stringListToStringValueList(ret)...)
 			} else {
 				// Variable by itself, variable is probably a list
 				if !f.Variables[0].Name.Const() {
diff --git a/androidmk/parser/scope.go b/androidmk/parser/scope.go
index 167e470..8111c89 100644
--- a/androidmk/parser/scope.go
+++ b/androidmk/parser/scope.go
@@ -21,13 +21,13 @@
 type Scope interface {
 	Get(name string) string
 	Set(name, value string)
-	Call(name string, args []string) string
-	SetFunc(name string, f func([]string) string)
+	Call(name string, args []string) []string
+	SetFunc(name string, f func([]string) []string)
 }
 
 type scope struct {
 	variables map[string]string
-	functions map[string]func([]string) string
+	functions map[string]func([]string) []string
 	parent    Scope
 }
 
@@ -47,22 +47,22 @@
 	s.variables[name] = value
 }
 
-func (s *scope) Call(name string, args []string) string {
+func (s *scope) Call(name string, args []string) []string {
 	if f, ok := s.functions[name]; ok {
 		return f(args)
 	}
 
-	return "<func:'" + name + "' unset>"
+	return []string{"<func:'" + name + "' unset>"}
 }
 
-func (s *scope) SetFunc(name string, f func([]string) string) {
+func (s *scope) SetFunc(name string, f func([]string) []string) {
 	s.functions[name] = f
 }
 
 func NewScope(parent Scope) Scope {
 	return &scope{
 		variables: make(map[string]string),
-		functions: make(map[string]func([]string) string),
+		functions: make(map[string]func([]string) []string),
 		parent:    parent,
 	}
 }
@@ -74,7 +74,7 @@
 	builtinScope[builtinDollar] = "$"
 }
 
-func (v Variable) EvalFunction(scope Scope) (string, bool) {
+func (v Variable) EvalFunction(scope Scope) ([]string, bool) {
 	f := v.Name.SplitN(" \t", 2)
 	if len(f) > 1 && f[0].Const() {
 		fname := f[0].Value(nil)
@@ -88,17 +88,20 @@
 			if fname == "call" {
 				return scope.Call(argVals[0], argVals[1:]), true
 			} else {
-				return "__builtin_func:" + fname + " " + strings.Join(argVals, " "), true
+				return []string{"__builtin_func:" + fname + " " + strings.Join(argVals, " ")}, true
 			}
 		}
 	}
 
-	return "", false
+	return []string{""}, false
 }
 
 func (v Variable) Value(scope Scope) string {
 	if ret, ok := v.EvalFunction(scope); ok {
-		return ret
+		if len(ret) > 1 {
+			panic("Expected a single value, but instead got a list")
+		}
+		return ret[0]
 	}
 	if scope == nil {
 		panic("Cannot take the value of a variable in a nil scope")
diff --git a/apex/apex.go b/apex/apex.go
index 79b79e8..c6d2e8e 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -40,7 +40,7 @@
 		Command: `echo '/ 1000 1000 0755' > ${out} && ` +
 			`echo '/apex_manifest.json 1000 1000 0644' >> ${out} && ` +
 			`echo ${ro_paths} | tr ' ' '\n' | awk '{print "/"$$1 " 1000 1000 0644"}' >> ${out} && ` +
-			`echo ${exec_paths} | tr ' ' '\n' | awk '{print "/"$$1 " 1000 1000 0755"}' >> ${out}`,
+			`echo ${exec_paths} | tr ' ' '\n' | awk '{print "/"$$1 " 0 2000 0755"}' >> ${out}`,
 		Description: "fs_config ${out}",
 	}, "ro_paths", "exec_paths")
 
@@ -374,6 +374,7 @@
 
 func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
 	targets := ctx.MultiTargets()
+	config := ctx.DeviceConfig()
 	has32BitTarget := false
 	for _, target := range targets {
 		if target.Arch.ArchType.Multilib == "lib32" {
@@ -385,7 +386,7 @@
 		// multilib.both.
 		ctx.AddFarVariationDependencies([]blueprint.Variation{
 			{Mutator: "arch", Variation: target.String()},
-			{Mutator: "image", Variation: a.getImageVariation()},
+			{Mutator: "image", Variation: a.getImageVariation(config)},
 			{Mutator: "link", Variation: "shared"},
 		}, sharedLibTag, a.properties.Native_shared_libs...)
 
@@ -393,21 +394,21 @@
 		addDependenciesForNativeModules(ctx,
 			a.properties.Multilib.Both.Native_shared_libs,
 			a.properties.Multilib.Both.Binaries, target.String(),
-			a.getImageVariation())
+			a.getImageVariation(config))
 
 		if i == 0 {
 			// When multilib.* is omitted for binaries, it implies
 			// multilib.first.
 			ctx.AddFarVariationDependencies([]blueprint.Variation{
 				{Mutator: "arch", Variation: target.String()},
-				{Mutator: "image", Variation: a.getImageVariation()},
+				{Mutator: "image", Variation: a.getImageVariation(config)},
 			}, executableTag, a.properties.Binaries...)
 
 			// Add native modules targetting the first ABI
 			addDependenciesForNativeModules(ctx,
 				a.properties.Multilib.First.Native_shared_libs,
 				a.properties.Multilib.First.Binaries, target.String(),
-				a.getImageVariation())
+				a.getImageVariation(config))
 		}
 
 		switch target.Arch.ArchType.Multilib {
@@ -416,24 +417,24 @@
 			addDependenciesForNativeModules(ctx,
 				a.properties.Multilib.Lib32.Native_shared_libs,
 				a.properties.Multilib.Lib32.Binaries, target.String(),
-				a.getImageVariation())
+				a.getImageVariation(config))
 
 			addDependenciesForNativeModules(ctx,
 				a.properties.Multilib.Prefer32.Native_shared_libs,
 				a.properties.Multilib.Prefer32.Binaries, target.String(),
-				a.getImageVariation())
+				a.getImageVariation(config))
 		case "lib64":
 			// Add native modules targetting 64-bit ABI
 			addDependenciesForNativeModules(ctx,
 				a.properties.Multilib.Lib64.Native_shared_libs,
 				a.properties.Multilib.Lib64.Binaries, target.String(),
-				a.getImageVariation())
+				a.getImageVariation(config))
 
 			if !has32BitTarget {
 				addDependenciesForNativeModules(ctx,
 					a.properties.Multilib.Prefer32.Native_shared_libs,
 					a.properties.Multilib.Prefer32.Binaries, target.String(),
-					a.getImageVariation())
+					a.getImageVariation(config))
 			}
 		}
 
@@ -471,8 +472,8 @@
 	return a.properties.Installable == nil || proptools.Bool(a.properties.Installable)
 }
 
-func (a *apexBundle) getImageVariation() string {
-	if proptools.Bool(a.properties.Use_vendor) {
+func (a *apexBundle) getImageVariation(config android.DeviceConfig) string {
+	if config.VndkVersion() != "" && proptools.Bool(a.properties.Use_vendor) {
 		return "vendor"
 	} else {
 		return "core"
diff --git a/bpfix/bpfix/bpfix.go b/bpfix/bpfix/bpfix.go
index 24a38c9..a4723fb 100644
--- a/bpfix/bpfix/bpfix.go
+++ b/bpfix/bpfix/bpfix.go
@@ -205,6 +205,11 @@
 		if mod.Type != "java_import" {
 			continue
 		}
+		host, _ := getLiteralBoolPropertyValue(mod, "host")
+		if host {
+			mod.Type = "java_import_host"
+			removeProperty(mod, "host")
+		}
 		srcs, ok := getLiteralListProperty(mod, "srcs")
 		if !ok {
 			continue
@@ -705,6 +710,24 @@
 	return stringValue.Value, true
 }
 
+func getLiteralBoolProperty(mod *parser.Module, name string) (b *parser.Bool, found bool) {
+	prop, ok := mod.GetProperty(name)
+	if !ok {
+		return nil, false
+	}
+	b, ok = prop.Value.(*parser.Bool)
+	return b, ok
+}
+
+func getLiteralBoolPropertyValue(mod *parser.Module, name string) (s bool, found bool) {
+	boolValue, ok := getLiteralBoolProperty(mod, name)
+	if !ok {
+		return false, false
+	}
+
+	return boolValue.Value, true
+}
+
 func propertyIndex(props []*parser.Property, propertyName string) int {
 	for i, prop := range props {
 		if prop.Name == propertyName {
diff --git a/bpfix/bpfix/bpfix_test.go b/bpfix/bpfix/bpfix_test.go
index 16dfce0..0469faf 100644
--- a/bpfix/bpfix/bpfix_test.go
+++ b/bpfix/bpfix/bpfix_test.go
@@ -555,3 +555,69 @@
 		})
 	}
 }
+
+func TestRewritePrebuilts(t *testing.T) {
+	tests := []struct {
+		name string
+		in   string
+		out  string
+	}{
+		{
+			name: "jar srcs",
+			in: `
+				java_import {
+					name: "foo",
+					srcs: ["foo.jar"],
+				}
+			`,
+			out: `
+				java_import {
+					name: "foo",
+					jars: ["foo.jar"],
+				}
+			`,
+		},
+		{
+			name: "aar srcs",
+			in: `
+				java_import {
+					name: "foo",
+					srcs: ["foo.aar"],
+					installable: true,
+				}
+			`,
+			out: `
+				android_library_import {
+					name: "foo",
+					aars: ["foo.aar"],
+
+				}
+			`,
+		},
+		{
+			name: "host prebuilt",
+			in: `
+				java_import {
+					name: "foo",
+					srcs: ["foo.jar"],
+					host: true,
+				}
+			`,
+			out: `
+				java_import_host {
+					name: "foo",
+					jars: ["foo.jar"],
+
+				}
+			`,
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			runPass(t, test.in, test.out, func(fixer *Fixer) error {
+				return rewriteIncorrectAndroidmkPrebuilts(fixer)
+			})
+		})
+	}
+}
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index 2bd0cf4..0380368 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -104,9 +104,6 @@
 
 	build.SetupOutDir(buildCtx, config)
 
-	metricsPath := filepath.Join(config.OutDir(), "build_metrics")
-	defer met.Dump(metricsPath)
-
 	logsDir := config.OutDir()
 	if config.Dist() {
 		logsDir = filepath.Join(config.DistDir(), "logs")
@@ -118,6 +115,8 @@
 	stat.AddOutput(status.NewVerboseLog(log, filepath.Join(logsDir, "verbose.log")))
 	stat.AddOutput(status.NewErrorLog(log, filepath.Join(logsDir, "error.log")))
 
+	defer met.Dump(filepath.Join(logsDir, "build_metrics"))
+
 	if start, ok := os.LookupEnv("TRACE_BEGIN_SOONG"); ok {
 		if !strings.HasSuffix(start, "N") {
 			if start_time, err := strconv.ParseUint(start, 10, 64); err == nil {
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 0ea32b8..3b21106 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -201,6 +201,8 @@
 	vdexPath := pathtools.ReplaceExtension(odexPath, "vdex")
 	vdexInstallPath := pathtools.ReplaceExtension(odexInstallPath, "vdex")
 
+	invocationPath := pathtools.ReplaceExtension(odexPath, "invocation")
+
 	// bootImageLocation is $OUT/dex_bootjars/system/framework/boot.art, but dex2oat actually reads
 	// $OUT/dex_bootjars/system/framework/arm64/boot.art
 	var bootImagePath string
@@ -265,11 +267,11 @@
 		const hidlManager = "android.hidl.manager-V1.0-java"
 
 		conditionalClassLoaderContextHost29 = append(conditionalClassLoaderContextHost29,
-      pathForLibrary(module, hidlManager))
+			pathForLibrary(module, hidlManager))
 		conditionalClassLoaderContextTarget29 = append(conditionalClassLoaderContextTarget29,
 			filepath.Join("/system/framework", hidlManager+".jar"))
 		conditionalClassLoaderContextHost29 = append(conditionalClassLoaderContextHost29,
-      pathForLibrary(module, hidlBase))
+			pathForLibrary(module, hidlBase))
 		conditionalClassLoaderContextTarget29 = append(conditionalClassLoaderContextTarget29,
 			filepath.Join("/system/framework", hidlBase+".jar"))
 	} else {
@@ -291,7 +293,7 @@
 		rule.Command().Textf(`uses_library_names="%s"`, strings.Join(verifyUsesLibs, " "))
 		rule.Command().Textf(`optional_uses_library_names="%s"`, strings.Join(verifyOptionalUsesLibs, " "))
 		rule.Command().Textf(`aapt_binary="%s"`, global.Tools.Aapt)
-		rule.Command().Textf(`dex_preopt_host_libraries="%s"`, strings.Join(classLoaderContextHost, " " ))
+		rule.Command().Textf(`dex_preopt_host_libraries="%s"`, strings.Join(classLoaderContextHost, " "))
 		rule.Command().Textf(`dex_preopt_target_libraries="%s"`, strings.Join(classLoaderContextTarget, " "))
 		rule.Command().Textf(`conditional_host_libs_28="%s"`, strings.Join(conditionalClassLoaderContextHost28, " "))
 		rule.Command().Textf(`conditional_target_libs_28="%s"`, strings.Join(conditionalClassLoaderContextTarget28, " "))
@@ -305,6 +307,7 @@
 		Text(`ANDROID_LOG_TAGS="*:e"`).
 		Tool(global.Tools.Dex2oat).
 		Flag("--avoid-storing-invocation").
+		FlagWithOutput("--write-invocation-to=", invocationPath).ImplicitOutput(invocationPath).
 		Flag("--runtime-arg").FlagWithArg("-Xms", global.Dex2oatXms).
 		Flag("--runtime-arg").FlagWithArg("-Xmx", global.Dex2oatXmx).
 		Flag("${class_loader_context_arg}").
diff --git a/python/scripts/stub_template_host.txt b/python/scripts/stub_template_host.txt
index 213401d..a48a86f 100644
--- a/python/scripts/stub_template_host.txt
+++ b/python/scripts/stub_template_host.txt
@@ -12,6 +12,9 @@
 MAIN_FILE = '%main%'
 PYTHON_PATH = 'PYTHONPATH'
 
+# Don't imply 'import site' on initialization
+PYTHON_ARG = '-S'
+
 def SearchPathEnv(name):
   search_path = os.getenv('PATH', os.defpath).split(os.pathsep)
   for directory in search_path:
@@ -73,7 +76,7 @@
     python_program = FindPythonBinary()
     if python_program is None:
       raise AssertionError('Could not find python binary: ' + PYTHON_BINARY)
-    args = [python_program, main_filepath] + args
+    args = [python_program, PYTHON_ARG, main_filepath] + args
 
     os.environ.update(new_env)
 
diff --git a/soong_ui.bash b/soong_ui.bash
index a39aa9c..c1c236b 100755
--- a/soong_ui.bash
+++ b/soong_ui.bash
@@ -23,7 +23,7 @@
 function gettop
 {
     local TOPFILE=build/soong/root.bp
-    if [ -z "${TOP-}" -a -f "${TOP-}/${TOPFILE}" ] ; then
+    if [ -n "${TOP-}" -a -f "${TOP-}/${TOPFILE}" ] ; then
         # The following circumlocution ensures we remove symlinks from TOP.
         (cd $TOP; PWD= /bin/pwd)
     else
diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
index e2e4368..1bcbec1 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -78,7 +78,6 @@
 	"bash":      Allowed,
 	"bc":        Allowed,
 	"bzip2":     Allowed,
-	"chmod":     Allowed,
 	"cp":        Allowed,
 	"date":      Allowed,
 	"dd":        Allowed,
@@ -154,6 +153,7 @@
 	// On linux we'll use the toybox version of these instead
 	"basename": Toybox,
 	"cat":      Toybox,
+	"chmod":    Toybox,
 	"cmp":      Toybox,
 	"comm":     Toybox,
 	"cut":      Toybox,