Merge changes from topic "hostdex"

* changes:
  Allow exclude_java_resources to affect java_resource_dirs
  Allow '$' in some paths
diff --git a/android/module.go b/android/module.go
index 77765f1..4d9ddd4 100644
--- a/android/module.go
+++ b/android/module.go
@@ -23,6 +23,7 @@
 
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/pathtools"
+	"github.com/google/blueprint/proptools"
 )
 
 var (
@@ -844,6 +845,13 @@
 		bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
 	}
 
+	bparams.Outputs = proptools.NinjaEscape(bparams.Outputs)
+	bparams.ImplicitOutputs = proptools.NinjaEscape(bparams.ImplicitOutputs)
+	bparams.Inputs = proptools.NinjaEscape(bparams.Inputs)
+	bparams.Implicits = proptools.NinjaEscape(bparams.Implicits)
+	bparams.OrderOnly = proptools.NinjaEscape(bparams.OrderOnly)
+	bparams.Depfile = proptools.NinjaEscape([]string{bparams.Depfile})[0]
+
 	return bparams
 }
 
diff --git a/android/package_ctx.go b/android/package_ctx.go
index e228bba..00b99ff 100644
--- a/android/package_ctx.go
+++ b/android/package_ctx.go
@@ -124,7 +124,11 @@
 // package-scoped variable's initialization.
 func (p PackageContext) SourcePathVariable(name, path string) blueprint.Variable {
 	return p.VariableFunc(name, func(ctx PackageVarContext) string {
-		return safePathForSource(ctx, path).String()
+		p, err := safePathForSource(ctx, path)
+		if err != nil {
+			ctx.Errorf("%s", err.Error())
+		}
+		return p.String()
 	})
 }
 
@@ -136,7 +140,10 @@
 	return p.VariableFunc(name, func(ctx PackageVarContext) string {
 		var ret []string
 		for _, path := range paths {
-			p := safePathForSource(ctx, path)
+			p, err := safePathForSource(ctx, path)
+			if err != nil {
+				ctx.Errorf("%s", err.Error())
+			}
 			ret = append(ret, p.String())
 		}
 		return strings.Join(ret, separator)
@@ -150,7 +157,10 @@
 // as part of a package-scoped variable's initialization.
 func (p PackageContext) SourcePathVariableWithEnvOverride(name, path, env string) blueprint.Variable {
 	return p.VariableFunc(name, func(ctx PackageVarContext) string {
-		p := safePathForSource(ctx, path)
+		p, err := safePathForSource(ctx, path)
+		if err != nil {
+			ctx.Errorf("%s", err.Error())
+		}
 		return ctx.Config().GetenvWithDefault(env, p.String())
 	})
 }
diff --git a/android/paths.go b/android/paths.go
index 57ebae2..91abeba 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -230,6 +230,8 @@
 // pathsForModuleSrcFromFullPath returns Paths rooted from the module's local
 // source directory, but strip the local source directory from the beginning of
 // each string. If incDirs is false, strip paths with a trailing '/' from the list.
+// It intended for use in globs that only list files that exist, so it allows '$' in
+// filenames.
 func pathsForModuleSrcFromFullPath(ctx ModuleContext, paths []string, incDirs bool) Paths {
 	prefix := filepath.Join(ctx.Config().srcDir, ctx.ModuleDir()) + "/"
 	if prefix == "./" {
@@ -246,7 +248,7 @@
 			continue
 		}
 
-		srcPath, err := pathForSource(ctx, ctx.ModuleDir(), path[len(prefix):])
+		srcPath, err := safePathForSource(ctx, ctx.ModuleDir(), path[len(prefix):])
 		if err != nil {
 			reportPathError(ctx, err)
 			continue
@@ -494,29 +496,26 @@
 
 // safePathForSource is for paths that we expect are safe -- only for use by go
 // code that is embedding ninja variables in paths
-func safePathForSource(ctx PathContext, path string) SourcePath {
-	p, err := validateSafePath(path)
-	if err != nil {
-		reportPathError(ctx, err)
-	}
+func safePathForSource(ctx PathContext, pathComponents ...string) (SourcePath, error) {
+	p, err := validateSafePath(pathComponents...)
 	ret := SourcePath{basePath{p, ctx.Config(), ""}}
+	if err != nil {
+		return ret, err
+	}
 
 	abs, err := filepath.Abs(ret.String())
 	if err != nil {
-		reportPathError(ctx, err)
-		return ret
+		return ret, err
 	}
 	buildroot, err := filepath.Abs(ctx.Config().buildDir)
 	if err != nil {
-		reportPathError(ctx, err)
-		return ret
+		return ret, err
 	}
 	if strings.HasPrefix(abs, buildroot) {
-		reportPathErrorf(ctx, "source path %s is in output", abs)
-		return ret
+		return ret, fmt.Errorf("source path %s is in output", abs)
 	}
 
-	return ret
+	return ret, err
 }
 
 // pathForSource creates a SourcePath from pathComponents, but does not check that it exists.
diff --git a/java/builder.go b/java/builder.go
index bb1590a..48b5a7b 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -24,6 +24,7 @@
 	"strings"
 
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/proptools"
 
 	"android/soong/android"
 )
@@ -320,7 +321,7 @@
 		Output:      outputFile,
 		Implicits:   deps,
 		Args: map[string]string{
-			"jarArgs": strings.Join(jarArgs, " "),
+			"jarArgs": strings.Join(proptools.NinjaEscape(jarArgs), " "),
 		},
 	})
 }
diff --git a/java/java.go b/java/java.go
index b60f9c7..4bf5880 100644
--- a/java/java.go
+++ b/java/java.go
@@ -75,7 +75,7 @@
 	// list of files to use as Java resources
 	Java_resources []string `android:"arch_variant"`
 
-	// list of files that should be excluded from java_resources
+	// list of files that should be excluded from java_resources and java_resource_dirs
 	Exclude_java_resources []string `android:"arch_variant"`
 
 	// don't build against the default libraries (bootclasspath, legacy-test, core-junit,
@@ -1119,7 +1119,8 @@
 		}
 	}
 
-	dirArgs, dirDeps := ResourceDirsToJarArgs(ctx, j.properties.Java_resource_dirs, j.properties.Exclude_java_resource_dirs)
+	dirArgs, dirDeps := ResourceDirsToJarArgs(ctx, j.properties.Java_resource_dirs,
+		j.properties.Exclude_java_resource_dirs, j.properties.Exclude_java_resources)
 	fileArgs, fileDeps := ResourceFilesToJarArgs(ctx, j.properties.Java_resources, j.properties.Exclude_java_resources)
 
 	var resArgs []string
diff --git a/java/java_resources.go b/java/java_resources.go
index e02709d..fdc1590 100644
--- a/java/java_resources.go
+++ b/java/java_resources.go
@@ -32,7 +32,7 @@
 }
 
 func ResourceDirsToJarArgs(ctx android.ModuleContext,
-	resourceDirs, excludeResourceDirs []string) (args []string, deps android.Paths) {
+	resourceDirs, excludeResourceDirs, excludeResourceFiles []string) (args []string, deps android.Paths) {
 	var excludeDirs []string
 	var excludeFiles []string
 
@@ -44,6 +44,8 @@
 		}
 	}
 
+	excludeFiles = append(excludeFiles, ctx.ExpandSources(excludeResourceFiles, nil).Strings()...)
+
 	excludeFiles = append(excludeFiles, resourceExcludes...)
 
 	for _, resourceDir := range resourceDirs {
diff --git a/java/java_test.go b/java/java_test.go
index 3ace528..82accd5 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -702,6 +702,30 @@
 			prop: `java_resource_dirs: ["java-res/*"], exclude_java_resource_dirs: ["java-res/b"]`,
 			args: "-C java-res/a -f java-res/a/a",
 		},
+		{
+			// Test wildcards in java_resources
+			name: "wildcard files",
+			prop: `java_resources: ["java-res/**/*"]`,
+			args: "-C . -f java-res/a/a -f java-res/b/b",
+		},
+		{
+			// Test exclude_java_resources with java_resources
+			name: "wildcard files with exclude",
+			prop: `java_resources: ["java-res/**/*"], exclude_java_resources: ["java-res/b/*"]`,
+			args: "-C . -f java-res/a/a",
+		},
+		{
+			// Test exclude_java_resources with java_resource_dirs
+			name: "resource dirs with exclude files",
+			prop: `java_resource_dirs: ["java-res"], exclude_java_resources: ["java-res/b/b"]`,
+			args: "-C java-res -f java-res/a/a",
+		},
+		{
+			// Test exclude_java_resource_dirs with java_resource_dirs
+			name: "resource dirs with exclude files",
+			prop: `java_resource_dirs: ["java-res", "java-res2"], exclude_java_resource_dirs: ["java-res2"]`,
+			args: "-C java-res -f java-res/a/a -f java-res/b/b",
+		},
 	}
 
 	for _, test := range table {
@@ -734,42 +758,6 @@
 	}
 }
 
-func TestExcludeResources(t *testing.T) {
-	ctx := testJava(t, `
-		java_library {
-			name: "foo",
-			srcs: ["a.java"],
-			java_resource_dirs: ["java-res", "java-res2"],
-			exclude_java_resource_dirs: ["java-res2"],
-		}
-
-		java_library {
-			name: "bar",
-			srcs: ["a.java"],
-			java_resources: ["java-res/*/*"],
-			exclude_java_resources: ["java-res/b/*"],
-		}
-	`)
-
-	fooRes := ctx.ModuleForTests("foo", "android_common").Output("res/foo.jar")
-
-	expected := "-C java-res -f java-res/a/a -f java-res/b/b"
-	if fooRes.Args["jarArgs"] != expected {
-		t.Errorf("foo resource jar args %q is not %q",
-			fooRes.Args["jarArgs"], expected)
-
-	}
-
-	barRes := ctx.ModuleForTests("bar", "android_common").Output("res/bar.jar")
-
-	expected = "-C . -f java-res/a/a"
-	if barRes.Args["jarArgs"] != expected {
-		t.Errorf("bar resource jar args %q is not %q",
-			barRes.Args["jarArgs"], expected)
-
-	}
-}
-
 func TestGeneratedSources(t *testing.T) {
 	ctx := testJava(t, `
 		java_library {