Merge "Increase per-process file limits for multiproduct_kati"
diff --git a/android/config.go b/android/config.go
index f806b49..0eebb5f 100644
--- a/android/config.go
+++ b/android/config.go
@@ -295,10 +295,7 @@
 func (c *config) fromEnv() error {
 	switch c.Getenv("EXPERIMENTAL_USE_OPENJDK9") {
 	case "":
-		if c.Getenv("RUN_ERROR_PRONE") != "true" {
-			// Use OpenJDK9, but target 1.8
-			c.useOpenJDK9 = true
-		}
+		// Use OpenJDK8
 	case "false":
 		// Use OpenJDK8
 	case "1.8":
@@ -309,7 +306,7 @@
 		c.useOpenJDK9 = true
 		c.targetOpenJDK9 = true
 	default:
-		return fmt.Errorf(`Invalid value for EXPERIMENTAL_USE_OPENJDK9, should be "", "false", "1.8", or "true"`)
+		return fmt.Errorf(`Invalid value for EXPERIMENTAL_USE_OPENJDK9, should be "", "1.8", or "true"`)
 	}
 
 	return nil
diff --git a/cc/config/global.go b/cc/config/global.go
index 4057317..5d1f7c4 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -132,15 +132,12 @@
 
 	// Some Android.mk files still have warnings.
 	WarningAllowedOldProjects = []string{
-		"cts/hostsidetests/security/securityPatch/",
-		"cts/tests/tests/permission/jni/",
 		"frameworks/av/drm/mediacas/plugins/",
 		"frameworks/av/services/mediaextractor/",
 		"frameworks/webview/chromium/",
 		"hardware/libhardware/modules/",
 		"hardware/qcom/",
 		"sdk/emulator/mksdcard/",
-		"system/vold/tests/",
 		"tools/adt/idea/android/ultimate/get_modification_time/jni/",
 	}
 )
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 651ec15..4f3ba93 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -131,6 +131,7 @@
 
 func (g *Module) DepsMutator(ctx android.BottomUpMutatorContext) {
 	android.ExtractSourcesDeps(ctx, g.properties.Srcs)
+	android.ExtractSourcesDeps(ctx, g.properties.Tool_files)
 	if g, ok := ctx.Module().(*Module); ok {
 		if len(g.properties.Tools) > 0 {
 			ctx.AddFarVariationDependencies([]blueprint.Variation{
@@ -141,11 +142,6 @@
 }
 
 func (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	if len(g.properties.Tools) == 0 && len(g.properties.Tool_files) == 0 {
-		ctx.ModuleErrorf("at least one `tools` or `tool_files` is required")
-		return
-	}
-
 	if len(g.properties.Export_include_dirs) > 0 {
 		for _, dir := range g.properties.Export_include_dirs {
 			g.exportedIncludeDirs = append(g.exportedIncludeDirs,
@@ -208,13 +204,13 @@
 		return
 	}
 
-	for _, tool := range g.properties.Tool_files {
-		toolPath := android.PathForModuleSrc(ctx, tool)
-		g.deps = append(g.deps, toolPath)
-		if _, exists := tools[tool]; !exists {
-			tools[tool] = toolPath
+	toolFiles := ctx.ExpandSources(g.properties.Tool_files, nil)
+	for _, tool := range toolFiles {
+		g.deps = append(g.deps, tool)
+		if _, exists := tools[tool.Rel()]; !exists {
+			tools[tool.Rel()] = tool
 		} else {
-			ctx.ModuleErrorf("multiple tools for %q, %q and %q", tool, tools[tool], toolPath.String())
+			ctx.ModuleErrorf("multiple tools for %q, %q and %q", tool, tools[tool.Rel()], tool.Rel())
 		}
 	}
 
@@ -226,10 +222,14 @@
 	rawCommand, err := android.Expand(task.cmd, func(name string) (string, error) {
 		switch name {
 		case "location":
+			if len(g.properties.Tools) == 0 && len(toolFiles) == 0 {
+				return "", fmt.Errorf("at least one `tools` or `tool_files` is required if $(location) is used")
+			}
+
 			if len(g.properties.Tools) > 0 {
 				return tools[g.properties.Tools[0]].String(), nil
 			} else {
-				return tools[g.properties.Tool_files[0]].String(), nil
+				return tools[toolFiles[0].Rel()].String(), nil
 			}
 		case "in":
 			return "${in}", nil
@@ -277,7 +277,10 @@
 	}
 
 	genDir := android.PathForModuleGen(ctx)
-	sandboxCommand := fmt.Sprintf("$sboxCmd --sandbox-path %s --output-root %s -c %q %s $allouts", sandboxPath, genDir, rawCommand, depfilePlaceholder)
+	// Escape the command for the shell
+	rawCommand = "'" + strings.Replace(rawCommand, "'", `'\''`, -1) + "'"
+	sandboxCommand := fmt.Sprintf("$sboxCmd --sandbox-path %s --output-root %s -c %s %s $allouts",
+		sandboxPath, genDir, rawCommand, depfilePlaceholder)
 
 	ruleParams := blueprint.RuleParams{
 		Command:     sandboxCommand,
diff --git a/java/builder.go b/java/builder.go
index be40103..10dfe06 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -161,6 +161,20 @@
 		},
 		"outDir", "dxFlags")
 
+	d8 = pctx.AndroidStaticRule("d8",
+		blueprint.RuleParams{
+			Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
+				`${config.D8Cmd} --output $outDir $dxFlags $in && ` +
+				`${config.SoongZipCmd} -o $outDir/classes.dex.jar -C $outDir -D $outDir && ` +
+				`${config.MergeZipsCmd} -D -stripFile "*.class" $out $outDir/classes.dex.jar $in`,
+			CommandDeps: []string{
+				"${config.DxCmd}",
+				"${config.SoongZipCmd}",
+				"${config.MergeZipsCmd}",
+			},
+		},
+		"outDir", "dxFlags")
+
 	jarjar = pctx.AndroidStaticRule("jarjar",
 		blueprint.RuleParams{
 			Command:     "${config.JavaCmd} -jar ${config.JarjarCmd} process $rulesFile $in $out",
@@ -420,9 +434,15 @@
 
 	outDir := android.PathForModuleOut(ctx, "dex")
 
+	rule := dx
+	desc := "dx"
+	if ctx.AConfig().IsEnvTrue("USE_D8_DESUGAR") {
+		rule = d8
+		desc = "d8"
+	}
 	ctx.Build(pctx, android.BuildParams{
-		Rule:        dx,
-		Description: "dx",
+		Rule:        rule,
+		Description: desc,
 		Output:      outputFile,
 		Input:       classesJar,
 		Args: map[string]string{
diff --git a/java/config/config.go b/java/config/config.go
index ad2f0ae..c43f9a3 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -106,6 +106,13 @@
 			return path.String(), nil
 		}
 	})
+	pctx.VariableFunc("D8Cmd", func(config android.Config) (string, error) {
+		path, err := pctx.HostBinToolPath(config, "d8")
+		if err != nil {
+			return "", err
+		}
+		return path.String(), nil
+	})
 	pctx.VariableFunc("TurbineJar", func(config android.Config) (string, error) {
 		turbine := "turbine.jar"
 		if config.UnbundledBuild() {
diff --git a/java/config/makevars.go b/java/config/makevars.go
index dc9a91b..5c8589e 100644
--- a/java/config/makevars.go
+++ b/java/config/makevars.go
@@ -45,8 +45,15 @@
 	ctx.Strict("JAR_ARGS", "${JarArgsCmd}")
 	ctx.Strict("JAVADOC", "${JavadocCmd}")
 	ctx.Strict("COMMON_JDK_FLAGS", "${CommonJdkFlags}")
-	ctx.Strict("DX", "${DxCmd}")
-	ctx.Strict("DX_COMMAND", "${DxCmd} -JXms16M -JXmx2048M")
+
+	if ctx.Config().IsEnvTrue("USE_D8_DESUGAR") {
+		ctx.Strict("DX", "${D8Cmd}")
+		ctx.Strict("DX_COMMAND", "${D8Cmd} -JXms16M -JXmx2048M")
+	} else {
+		ctx.Strict("DX", "${DxCmd}")
+		ctx.Strict("DX_COMMAND", "${DxCmd} -JXms16M -JXmx2048M")
+	}
+
 	ctx.Strict("TURBINE", "${TurbineJar}")
 
 	if ctx.Config().IsEnvTrue("RUN_ERROR_PRONE") {
diff --git a/java/java.go b/java/java.go
index 3663253..e9f8331 100644
--- a/java/java.go
+++ b/java/java.go
@@ -671,6 +671,7 @@
 	// Store the list of .java files that was passed to javac
 	j.compiledJavaSrcs = uniqueSrcFiles
 	j.compiledSrcJars = srcJars
+	fullD8 := ctx.AConfig().IsEnvTrue("USE_D8_DESUGAR")
 
 	enable_sharding := false
 	if ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") {
@@ -793,7 +794,7 @@
 		j.headerJarFile = j.implementationJarFile
 	}
 
-	if ctx.Device() && j.installable() {
+	if !fullD8 && ctx.Device() && j.installable() {
 		outputFile = j.desugar(ctx, flags, outputFile, jarName)
 	}
 
@@ -808,7 +809,11 @@
 	}
 
 	if ctx.Device() && j.installable() {
-		outputFile = j.compileDex(ctx, flags, outputFile, jarName)
+		if fullD8 {
+			outputFile = j.compileDexFullD8(ctx, flags, outputFile, jarName)
+		} else {
+			outputFile = j.compileDex(ctx, flags, outputFile, jarName)
+		}
 		if ctx.Failed() {
 			return
 		}
@@ -896,15 +901,6 @@
 	classesJar android.Path, jarName string) android.Path {
 
 	dxFlags := j.deviceProperties.Dxflags
-	if false /* emma enabled */ {
-		// If you instrument class files that have local variable debug information in
-		// them emma does not correctly maintain the local variable table.
-		// This will cause an error when you try to convert the class files for Android.
-		// The workaround here is to build different dex file here based on emma switch
-		// then later copy into classes.dex. When emma is on, dx is run with --no-locals
-		// option to remove local variable information
-		dxFlags = append(dxFlags, "--no-locals")
-	}
 
 	if ctx.Config().Getenv("NO_OPTIMIZE_DX") != "" {
 		dxFlags = append(dxFlags, "--no-optimize")
@@ -930,6 +926,51 @@
 	return javalibJar
 }
 
+func (j *Module) compileDexFullD8(ctx android.ModuleContext, flags javaBuilderFlags,
+	classesJar android.Path, jarName string) android.Path {
+
+	// Translate all the DX flags to D8 ones until all the build files have been migrated
+	// to D8 flags. See: b/69377755
+	var dxFlags []string
+	for _, x := range j.deviceProperties.Dxflags {
+		if x == "--core-library" {
+			continue
+		}
+		if x == "--dex" {
+			continue
+		}
+		if x == "--multi-dex" {
+			continue
+		}
+		if x == "--no-locals" {
+			dxFlags = append(dxFlags, "--release")
+			continue
+		}
+		dxFlags = append(dxFlags, x)
+	}
+
+	if ctx.AConfig().Getenv("NO_OPTIMIZE_DX") != "" {
+		dxFlags = append(dxFlags, "--debug")
+	}
+
+	if ctx.AConfig().Getenv("GENERATE_DEX_DEBUG") != "" {
+		dxFlags = append(dxFlags,
+			"--debug",
+			"--verbose")
+	}
+
+	dxFlags = append(dxFlags, "--min-api "+j.minSdkVersionNumber(ctx))
+
+	flags.dxFlags = strings.Join(dxFlags, " ")
+
+	// Compile classes.jar into classes.dex and then javalib.jar
+	javalibJar := android.PathForModuleOut(ctx, "dex", jarName)
+	TransformClassesJarToDexJar(ctx, javalibJar, classesJar, flags)
+
+	j.dexJarFile = javalibJar
+	return javalibJar
+}
+
 // Returns a sdk version as a string that is guaranteed to be a parseable as a number.  For
 // modules targeting an unreleased SDK (meaning it does not yet have a number) it returns "10000".
 func (j *Module) minSdkVersionNumber(ctx android.ModuleContext) string {
@@ -1031,7 +1072,7 @@
 
 	isWrapperVariant bool
 
-	wrapperFile android.SourcePath
+	wrapperFile android.Path
 	binaryFile  android.OutputPath
 }
 
@@ -1048,7 +1089,13 @@
 		j.isWrapperVariant = true
 
 		if String(j.binaryProperties.Wrapper) != "" {
-			j.wrapperFile = android.PathForModuleSrc(ctx, String(j.binaryProperties.Wrapper)).SourcePath
+			wrapperSrcs := ctx.ExpandSources([]string{String(j.binaryProperties.Wrapper)}, nil)
+			if len(wrapperSrcs) == 1 {
+				j.wrapperFile = wrapperSrcs[0]
+			} else {
+				ctx.PropertyErrorf("wrapper", "module providing wrapper must produce exactly one file")
+				return
+			}
 		} else {
 			j.wrapperFile = android.PathForSource(ctx, "build/soong/scripts/jar-wrapper.sh")
 		}
@@ -1065,6 +1112,8 @@
 func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) {
 	if ctx.Arch().ArchType == android.Common {
 		j.deps(ctx)
+	} else {
+		android.ExtractSourcesDeps(ctx, []string{String(j.binaryProperties.Wrapper)})
 	}
 }
 
diff --git a/ui/build/config.go b/ui/build/config.go
index b608d38..df97d80 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -150,16 +150,7 @@
 		if override, ok := ret.environ.Get("OVERRIDE_ANDROID_JAVA_HOME"); ok {
 			return override
 		}
-		v, ok := ret.environ.Get("EXPERIMENTAL_USE_OPENJDK9")
-		if !ok {
-			v2, ok2 := ret.environ.Get("RUN_ERROR_PRONE")
-			if ok2 && (v2 == "true") {
-				v = "false"
-			} else {
-				v = "1.8"
-			}
-		}
-		if v != "false" {
+		if v, ok := ret.environ.Get("EXPERIMENTAL_USE_OPENJDK9"); ok && v != "" && v != "false" {
 			return filepath.Join("prebuilts/jdk/jdk9", ret.HostPrebuiltTag())
 		}
 		return filepath.Join("prebuilts/jdk/jdk8", ret.HostPrebuiltTag())