Merge "Turn on string-plus-int warning"
diff --git a/android/config.go b/android/config.go
index 92879de..1520739 100644
--- a/android/config.go
+++ b/android/config.go
@@ -581,7 +581,7 @@
 	if defaultCert == "" || filepath.Dir(defaultCert) == "build/target/product/security" {
 		// When defaultCert is unset or is set to the testkeys path, use the APEX keys
 		// that is under the module dir
-		return PathForModuleSrc(ctx).SourcePath
+		return pathForModuleSrc(ctx)
 	} else {
 		// If not, APEX keys are under the specified directory
 		return PathForSource(ctx, filepath.Dir(defaultCert))
diff --git a/android/filegroup.go b/android/filegroup.go
index c2be22a..ec522fc 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -60,7 +60,11 @@
 }
 
 func (fg *fileGroup) GenerateAndroidBuildActions(ctx ModuleContext) {
-	fg.srcs = ctx.ExpandSourcesSubDir(fg.properties.Srcs, fg.properties.Exclude_srcs, String(fg.properties.Path))
+	fg.srcs = PathsForModuleSrcExcludes(ctx, fg.properties.Srcs, fg.properties.Exclude_srcs)
+
+	if fg.properties.Path != nil {
+		fg.srcs = PathsWithModuleSrcSubDir(ctx, fg.srcs, String(fg.properties.Path))
+	}
 }
 
 func (fg *fileGroup) Srcs() Paths {
diff --git a/android/module.go b/android/module.go
index 9a69a26..afd2b71 100644
--- a/android/module.go
+++ b/android/module.go
@@ -117,7 +117,6 @@
 	ExpandSources(srcFiles, excludes []string) Paths
 	ExpandSource(srcFile, prop string) Path
 	ExpandOptionalSource(srcFile *string, prop string) OptionalPath
-	ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths
 	Glob(globPattern string, excludes []string) Paths
 	GlobFiles(globPattern string, excludes []string) Paths
 
@@ -855,7 +854,7 @@
 
 		if a.commonProperties.Notice != nil {
 			// For filegroup-based notice file references.
-			a.noticeFile = ctx.ExpandSource(*a.commonProperties.Notice, "notice")
+			a.noticeFile = PathForModuleSrc(ctx, *a.commonProperties.Notice)
 		}
 	}
 
@@ -1420,27 +1419,18 @@
 
 // Returns a list of paths expanded from globs and modules referenced using ":module" syntax.  The property must
 // be tagged with `android:"path" to support automatic source module dependency resolution.
+//
+// Deprecated: use PathsForModuleSrc or PathsForModuleSrcExcludes instead.
 func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
-	return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
+	return PathsForModuleSrcExcludes(ctx, srcFiles, excludes)
 }
 
 // Returns a single path expanded from globs and modules referenced using ":module" syntax.  The property must
 // be tagged with `android:"path" to support automatic source module dependency resolution.
+//
+// Deprecated: use PathForModuleSrc instead.
 func (ctx *androidModuleContext) ExpandSource(srcFile, prop string) Path {
-	srcFiles := ctx.ExpandSourcesSubDir([]string{srcFile}, nil, "")
-	if len(srcFiles) == 1 {
-		return srcFiles[0]
-	} else if len(srcFiles) == 0 {
-		if ctx.Config().AllowMissingDependencies() {
-			ctx.AddMissingDependencies([]string{srcFile})
-		} else {
-			ctx.PropertyErrorf(prop, "%s path %s does not exist", prop, srcFile)
-		}
-		return nil
-	} else {
-		ctx.PropertyErrorf(prop, "module providing %s must produce exactly one file", prop)
-		return nil
-	}
+	return PathForModuleSrc(ctx, srcFile)
 }
 
 // Returns an optional single path expanded from globs and modules referenced using ":module" syntax if
@@ -1448,82 +1438,11 @@
 // dependency resolution.
 func (ctx *androidModuleContext) ExpandOptionalSource(srcFile *string, prop string) OptionalPath {
 	if srcFile != nil {
-		return OptionalPathForPath(ctx.ExpandSource(*srcFile, prop))
+		return OptionalPathForPath(PathForModuleSrc(ctx, *srcFile))
 	}
 	return OptionalPath{}
 }
 
-func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
-	prefix := PathForModuleSrc(ctx).String()
-
-	var expandedExcludes []string
-	if excludes != nil {
-		expandedExcludes = make([]string, 0, len(excludes))
-	}
-
-	for _, e := range excludes {
-		if m := SrcIsModule(e); m != "" {
-			module := ctx.GetDirectDepWithTag(m, SourceDepTag)
-			if module == nil {
-				if ctx.Config().AllowMissingDependencies() {
-					ctx.AddMissingDependencies([]string{m})
-				} else {
-					ctx.ModuleErrorf(`missing dependency on %q, is the property annotated with android:"path"?`, m)
-				}
-				continue
-			}
-			if srcProducer, ok := module.(SourceFileProducer); ok {
-				expandedExcludes = append(expandedExcludes, srcProducer.Srcs().Strings()...)
-			} else {
-				ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
-			}
-		} else {
-			expandedExcludes = append(expandedExcludes, filepath.Join(prefix, e))
-		}
-	}
-	expandedSrcFiles := make(Paths, 0, len(srcFiles))
-	for _, s := range srcFiles {
-		if m := SrcIsModule(s); m != "" {
-			module := ctx.GetDirectDepWithTag(m, SourceDepTag)
-			if module == nil {
-				if ctx.Config().AllowMissingDependencies() {
-					ctx.AddMissingDependencies([]string{m})
-				} else {
-					ctx.ModuleErrorf(`missing dependency on %q, is the property annotated with android:"path"?`, m)
-				}
-				continue
-			}
-			if srcProducer, ok := module.(SourceFileProducer); ok {
-				moduleSrcs := srcProducer.Srcs()
-				for _, e := range expandedExcludes {
-					for j, ms := range moduleSrcs {
-						if ms.String() == e {
-							moduleSrcs = append(moduleSrcs[:j], moduleSrcs[j+1:]...)
-						}
-					}
-				}
-				expandedSrcFiles = append(expandedSrcFiles, moduleSrcs...)
-			} else {
-				ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
-			}
-		} else if pathtools.IsGlob(s) {
-			globbedSrcFiles := ctx.GlobFiles(filepath.Join(prefix, s), expandedExcludes)
-			for i, s := range globbedSrcFiles {
-				globbedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
-			}
-			expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
-		} else {
-			p := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
-			j := findStringInSlice(p.String(), expandedExcludes)
-			if j == -1 {
-				expandedSrcFiles = append(expandedSrcFiles, p)
-			}
-
-		}
-	}
-	return expandedSrcFiles
-}
-
 func (ctx *androidModuleContext) RequiredModuleNames() []string {
 	return ctx.module.base().commonProperties.Required
 }
diff --git a/android/paths.go b/android/paths.go
index afde55e..cdcb719 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -220,11 +220,104 @@
 // PathsForModuleSrc returns Paths rooted from the module's local source
 // directory
 func PathsForModuleSrc(ctx ModuleContext, paths []string) Paths {
-	ret := make(Paths, len(paths))
-	for i, path := range paths {
-		ret[i] = PathForModuleSrc(ctx, path)
+	return PathsForModuleSrcExcludes(ctx, paths, nil)
+}
+
+func PathsForModuleSrcExcludes(ctx ModuleContext, paths, excludes []string) Paths {
+	prefix := pathForModuleSrc(ctx).String()
+
+	var expandedExcludes []string
+	if excludes != nil {
+		expandedExcludes = make([]string, 0, len(excludes))
 	}
-	return ret
+
+	for _, e := range excludes {
+		if m := SrcIsModule(e); m != "" {
+			module := ctx.GetDirectDepWithTag(m, SourceDepTag)
+			if module == nil {
+				if ctx.Config().AllowMissingDependencies() {
+					ctx.AddMissingDependencies([]string{m})
+				} else {
+					ctx.ModuleErrorf(`missing dependency on %q, is the property annotated with android:"path"?`, m)
+				}
+				continue
+			}
+			if srcProducer, ok := module.(SourceFileProducer); ok {
+				expandedExcludes = append(expandedExcludes, srcProducer.Srcs().Strings()...)
+			} else {
+				ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
+			}
+		} else {
+			expandedExcludes = append(expandedExcludes, filepath.Join(prefix, e))
+		}
+	}
+
+	if paths == nil {
+		return nil
+	}
+
+	expandedSrcFiles := make(Paths, 0, len(paths))
+	for _, s := range paths {
+		srcFiles, err := expandOneSrcPath(ctx, s, expandedExcludes)
+		if depErr, ok := err.(missingDependencyError); ok {
+			if ctx.Config().AllowMissingDependencies() {
+				ctx.AddMissingDependencies(depErr.missingDeps)
+			} else {
+				ctx.ModuleErrorf(`%s, is the property annotated with android:"path"?`, depErr.Error())
+			}
+		} else if err != nil {
+			reportPathError(ctx, err)
+		}
+		expandedSrcFiles = append(expandedSrcFiles, srcFiles...)
+	}
+	return expandedSrcFiles
+}
+
+type missingDependencyError struct {
+	missingDeps []string
+}
+
+func (e missingDependencyError) Error() string {
+	return "missing dependencies: " + strings.Join(e.missingDeps, ", ")
+}
+
+func expandOneSrcPath(ctx ModuleContext, s string, expandedExcludes []string) (Paths, error) {
+	if m := SrcIsModule(s); m != "" {
+		module := ctx.GetDirectDepWithTag(m, SourceDepTag)
+		if module == nil {
+			return nil, missingDependencyError{[]string{m}}
+		}
+		if srcProducer, ok := module.(SourceFileProducer); ok {
+			moduleSrcs := srcProducer.Srcs()
+			for _, e := range expandedExcludes {
+				for j := 0; j < len(moduleSrcs); j++ {
+					if moduleSrcs[j].String() == e {
+						moduleSrcs = append(moduleSrcs[:j], moduleSrcs[j+1:]...)
+						j--
+					}
+				}
+			}
+			return moduleSrcs, nil
+		} else {
+			return nil, fmt.Errorf("path dependency %q is not a source file producing module", m)
+		}
+	} else if pathtools.IsGlob(s) {
+		paths := ctx.GlobFiles(pathForModuleSrc(ctx, s).String(), expandedExcludes)
+		return PathsWithModuleSrcSubDir(ctx, paths, ""), nil
+	} else {
+		p := pathForModuleSrc(ctx, s)
+		if exists, _, err := ctx.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)
+		}
+
+		j := findStringInSlice(p.String(), expandedExcludes)
+		if j >= 0 {
+			return nil, nil
+		}
+		return Paths{p}, nil
+	}
 }
 
 // pathsForModuleSrcFromFullPath returns Paths rooted from the module's local
@@ -254,10 +347,9 @@
 			continue
 		}
 
-		moduleSrcPath := ModuleSrcPath{srcPath}
-		moduleSrcPath.basePath.rel = srcPath.path
+		srcPath.basePath.rel = srcPath.path
 
-		ret = append(ret, moduleSrcPath)
+		ret = append(ret, srcPath)
 	}
 	return ret
 }
@@ -620,13 +712,20 @@
 	return p.withRel(path)
 }
 
+// join is like Join but does less path validation.
+func (p SourcePath) join(ctx PathContext, paths ...string) SourcePath {
+	path, err := validateSafePath(paths...)
+	if err != nil {
+		reportPathError(ctx, err)
+	}
+	return p.withRel(path)
+}
+
 // OverlayPath returns the overlay for `path' if it exists. This assumes that the
 // SourcePath is the path to a resource overlay directory.
 func (p SourcePath) OverlayPath(ctx ModuleContext, path Path) OptionalPath {
 	var relDir string
-	if moduleSrcPath, ok := path.(ModuleSrcPath); ok {
-		relDir = moduleSrcPath.path
-	} else if srcPath, ok := path.(SourcePath); ok {
+	if srcPath, ok := path.(SourcePath); ok {
 		relDir = srcPath.path
 	} else {
 		reportPathErrorf(ctx, "Cannot find relative path for %s(%s)", reflect.TypeOf(path).Name(), path)
@@ -738,45 +837,75 @@
 	return PathForOutput(ctx, ".intermediates", path)
 }
 
-// ModuleSrcPath is a Path representing a file rooted from a module's local source dir
-type ModuleSrcPath struct {
-	SourcePath
+var _ genPathProvider = SourcePath{}
+var _ objPathProvider = SourcePath{}
+var _ resPathProvider = SourcePath{}
+
+// PathForModuleSrc returns a Path representing the paths... under the
+// module's local source directory.
+func PathForModuleSrc(ctx ModuleContext, pathComponents ...string) Path {
+	p, err := validatePath(pathComponents...)
+	if err != nil {
+		reportPathError(ctx, err)
+	}
+	paths, err := expandOneSrcPath(ctx, p, nil)
+	if err != nil {
+		if depErr, ok := err.(missingDependencyError); ok {
+			if ctx.Config().AllowMissingDependencies() {
+				ctx.AddMissingDependencies(depErr.missingDeps)
+			} else {
+				ctx.ModuleErrorf(`%s, is the property annotated with android:"path"?`, depErr.Error())
+			}
+		} else {
+			reportPathError(ctx, err)
+		}
+		return nil
+	} else if len(paths) == 0 {
+		reportPathErrorf(ctx, "%q produced no files, expected exactly one", p)
+		return nil
+	} else if len(paths) > 1 {
+		reportPathErrorf(ctx, "%q produced %d files, expected exactly one", p, len(paths))
+	}
+	return paths[0]
 }
 
-var _ Path = ModuleSrcPath{}
-var _ genPathProvider = ModuleSrcPath{}
-var _ objPathProvider = ModuleSrcPath{}
-var _ resPathProvider = ModuleSrcPath{}
-
-// PathForModuleSrc returns a ModuleSrcPath representing the paths... under the
-// module's local source directory.
-func PathForModuleSrc(ctx ModuleContext, paths ...string) ModuleSrcPath {
+func pathForModuleSrc(ctx ModuleContext, paths ...string) SourcePath {
 	p, err := validatePath(paths...)
 	if err != nil {
 		reportPathError(ctx, err)
 	}
 
-	srcPath, err := pathForSource(ctx, ctx.ModuleDir(), p)
+	path, err := pathForSource(ctx, ctx.ModuleDir(), p)
 	if err != nil {
 		reportPathError(ctx, err)
 	}
 
-	if pathtools.IsGlob(srcPath.String()) {
-		reportPathErrorf(ctx, "path may not contain a glob: %s", srcPath.String())
-	}
-
-	path := ModuleSrcPath{srcPath}
 	path.basePath.rel = p
 
-	if exists, _, err := ctx.Fs().Exists(path.String()); err != nil {
-		reportPathErrorf(ctx, "%s: %s", path, err.Error())
-	} else if !exists {
-		reportPathErrorf(ctx, "module source path %q does not exist", path)
-	}
-
 	return path
 }
 
+// PathsWithModuleSrcSubDir takes a list of Paths and returns a new list of Paths where Rel() on each path
+// will return the path relative to subDir in the module's source directory.  If any input paths are not located
+// inside subDir then a path error will be reported.
+func PathsWithModuleSrcSubDir(ctx ModuleContext, paths Paths, subDir string) Paths {
+	paths = append(Paths(nil), paths...)
+	subDirFullPath := pathForModuleSrc(ctx, subDir)
+	for i, path := range paths {
+		rel := Rel(ctx, subDirFullPath.String(), path.String())
+		paths[i] = subDirFullPath.join(ctx, rel)
+	}
+	return paths
+}
+
+// PathWithModuleSrcSubDir takes a Path and returns a Path where Rel() will return the path relative to subDir in the
+// module's source directory.  If the input path is not located inside subDir then a path error will be reported.
+func PathWithModuleSrcSubDir(ctx ModuleContext, path Path, subDir string) Path {
+	subDirFullPath := pathForModuleSrc(ctx, subDir)
+	rel := Rel(ctx, subDirFullPath.String(), path.String())
+	return subDirFullPath.Join(ctx, rel)
+}
+
 // OptionalPathForModuleSrc returns an OptionalPath. The OptionalPath contains a
 // valid path if p is non-nil.
 func OptionalPathForModuleSrc(ctx ModuleContext, p *string) OptionalPath {
@@ -786,25 +915,19 @@
 	return OptionalPathForPath(PathForModuleSrc(ctx, *p))
 }
 
-func (p ModuleSrcPath) genPathWithExt(ctx ModuleContext, subdir, ext string) ModuleGenPath {
+func (p SourcePath) genPathWithExt(ctx ModuleContext, subdir, ext string) ModuleGenPath {
 	return PathForModuleGen(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
 }
 
-func (p ModuleSrcPath) objPathWithExt(ctx ModuleContext, subdir, ext string) ModuleObjPath {
+func (p SourcePath) objPathWithExt(ctx ModuleContext, subdir, ext string) ModuleObjPath {
 	return PathForModuleObj(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
 }
 
-func (p ModuleSrcPath) resPathWithName(ctx ModuleContext, name string) ModuleResPath {
+func (p SourcePath) resPathWithName(ctx ModuleContext, name string) ModuleResPath {
 	// TODO: Use full directory if the new ctx is not the current ctx?
 	return PathForModuleRes(ctx, p.path, name)
 }
 
-func (p ModuleSrcPath) WithSubDir(ctx ModuleContext, subdir string) ModuleSrcPath {
-	subdir = PathForModuleSrc(ctx, subdir).String()
-	p.rel = Rel(ctx, subdir, p.path)
-	return p
-}
-
 // ModuleOutPath is a Path representing a module's output directory.
 type ModuleOutPath struct {
 	OutputPath
diff --git a/android/paths_test.go b/android/paths_test.go
index cadf371..2e0e0e8 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -24,6 +24,7 @@
 	"testing"
 
 	"github.com/google/blueprint/pathtools"
+	"github.com/google/blueprint/proptools"
 )
 
 type strsTestCase struct {
@@ -508,15 +509,27 @@
 }
 
 func TestDirectorySortedPaths(t *testing.T) {
+	config := TestConfig("out", nil)
+
+	ctx := PathContextForTesting(config, map[string][]byte{
+		"a.txt":   nil,
+		"a/txt":   nil,
+		"a/b/c":   nil,
+		"a/b/d":   nil,
+		"b":       nil,
+		"b/b.txt": nil,
+		"a/a.txt": nil,
+	})
+
 	makePaths := func() Paths {
 		return Paths{
-			PathForTesting("a.txt"),
-			PathForTesting("a/txt"),
-			PathForTesting("a/b/c"),
-			PathForTesting("a/b/d"),
-			PathForTesting("b"),
-			PathForTesting("b/b.txt"),
-			PathForTesting("a/a.txt"),
+			PathForSource(ctx, "a.txt"),
+			PathForSource(ctx, "a/txt"),
+			PathForSource(ctx, "a/b/c"),
+			PathForSource(ctx, "a/b/d"),
+			PathForSource(ctx, "b"),
+			PathForSource(ctx, "b/b.txt"),
+			PathForSource(ctx, "a/a.txt"),
 		}
 	}
 
@@ -694,39 +707,117 @@
 	}
 }
 
-type expandSourcesTestModule struct {
+type pathForModuleSrcTestModule struct {
 	ModuleBase
 	props struct {
 		Srcs         []string `android:"path"`
 		Exclude_srcs []string `android:"path"`
+
+		Src *string `android:"path"`
 	}
 
-	srcs Paths
+	src string
+	rel string
+
+	srcs []string
 	rels []string
+
+	missingDeps []string
 }
 
-func expandSourcesTestModuleFactory() Module {
-	module := &expandSourcesTestModule{}
+func pathForModuleSrcTestModuleFactory() Module {
+	module := &pathForModuleSrcTestModule{}
 	module.AddProperties(&module.props)
 	InitAndroidModule(module)
 	return module
 }
 
-func (p *expandSourcesTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
-	p.srcs = ctx.ExpandSources(p.props.Srcs, p.props.Exclude_srcs)
+func (p *pathForModuleSrcTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+	srcs := PathsForModuleSrcExcludes(ctx, p.props.Srcs, p.props.Exclude_srcs)
+	p.srcs = srcs.Strings()
 
-	for _, src := range p.srcs {
+	for _, src := range srcs {
 		p.rels = append(p.rels, src.Rel())
 	}
+
+	if p.props.Src != nil {
+		src := PathForModuleSrc(ctx, *p.props.Src)
+		if src != nil {
+			p.src = src.String()
+			p.rel = src.Rel()
+		}
+	}
+
+	p.missingDeps = ctx.GetMissingDependencies()
+}
+
+type pathForModuleSrcTestCase struct {
+	name string
+	bp   string
+	srcs []string
+	rels []string
+	src  string
+	rel  string
+}
+
+func testPathForModuleSrc(t *testing.T, buildDir string, tests []pathForModuleSrcTestCase) {
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			config := TestConfig(buildDir, nil)
+			ctx := NewTestContext()
+
+			ctx.RegisterModuleType("test", ModuleFactoryAdaptor(pathForModuleSrcTestModuleFactory))
+			ctx.RegisterModuleType("filegroup", ModuleFactoryAdaptor(FileGroupFactory))
+
+			fgBp := `
+				filegroup {
+					name: "a",
+					srcs: ["src/a"],
+				}
+			`
+
+			mockFS := map[string][]byte{
+				"fg/Android.bp":     []byte(fgBp),
+				"foo/Android.bp":    []byte(test.bp),
+				"fg/src/a":          nil,
+				"foo/src/b":         nil,
+				"foo/src/c":         nil,
+				"foo/src/d":         nil,
+				"foo/src/e/e":       nil,
+				"foo/src_special/$": nil,
+			}
+
+			ctx.MockFileSystem(mockFS)
+
+			ctx.Register()
+			_, errs := ctx.ParseFileList(".", []string{"fg/Android.bp", "foo/Android.bp"})
+			FailIfErrored(t, errs)
+			_, errs = ctx.PrepareBuildActions(config)
+			FailIfErrored(t, errs)
+
+			m := ctx.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)
+
+			if g, w := m.srcs, test.srcs; !reflect.DeepEqual(g, w) {
+				t.Errorf("want srcs %q, got %q", w, g)
+			}
+
+			if g, w := m.rels, test.rels; !reflect.DeepEqual(g, w) {
+				t.Errorf("want rels %q, got %q", w, g)
+			}
+
+			if g, w := m.src, test.src; g != w {
+				t.Errorf("want src %q, got %q", w, g)
+			}
+
+			if g, w := m.rel, test.rel; g != w {
+				t.Errorf("want rel %q, got %q", w, g)
+			}
+		})
+	}
 }
 
-func TestExpandSources(t *testing.T) {
-	tests := []struct {
-		name string
-		bp   string
-		srcs []string
-		rels []string
-	}{
+func TestPathsForModuleSrc(t *testing.T) {
+	tests := []pathForModuleSrcTestCase{
 		{
 			name: "path",
 			bp: `
@@ -782,57 +873,118 @@
 		},
 	}
 
+	buildDir, err := ioutil.TempDir("", "soong_paths_for_module_src_test")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(buildDir)
+
+	testPathForModuleSrc(t, buildDir, tests)
+}
+
+func TestPathForModuleSrc(t *testing.T) {
+	tests := []pathForModuleSrcTestCase{
+		{
+			name: "path",
+			bp: `
+			test {
+				name: "foo",
+				src: "src/b",
+			}`,
+			src: "foo/src/b",
+			rel: "src/b",
+		},
+		{
+			name: "glob",
+			bp: `
+			test {
+				name: "foo",
+				src: "src/e/*",
+			}`,
+			src: "foo/src/e/e",
+			rel: "src/e/e",
+		},
+		{
+			name: "filegroup",
+			bp: `
+			test {
+				name: "foo",
+				src: ":a",
+			}`,
+			src: "fg/src/a",
+			rel: "src/a",
+		},
+		{
+			name: "special characters glob",
+			bp: `
+			test {
+				name: "foo",
+				src: "src_special/*",
+			}`,
+			src: "foo/src_special/$",
+			rel: "src_special/$",
+		},
+	}
+
 	buildDir, err := ioutil.TempDir("", "soong_path_for_module_src_test")
 	if err != nil {
 		t.Fatal(err)
 	}
 	defer os.RemoveAll(buildDir)
 
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			config := TestConfig(buildDir, nil)
-			ctx := NewTestContext()
+	testPathForModuleSrc(t, buildDir, tests)
+}
 
-			ctx.RegisterModuleType("test", ModuleFactoryAdaptor(expandSourcesTestModuleFactory))
-			ctx.RegisterModuleType("filegroup", ModuleFactoryAdaptor(FileGroupFactory))
-
-			fgBp := `
-				filegroup {
-					name: "a",
-					srcs: ["src/a"],
-				}
-			`
-
-			mockFS := map[string][]byte{
-				"fg/Android.bp":     []byte(fgBp),
-				"foo/Android.bp":    []byte(test.bp),
-				"fg/src/a":          nil,
-				"foo/src/b":         nil,
-				"foo/src/c":         nil,
-				"foo/src/d":         nil,
-				"foo/src/e/e":       nil,
-				"foo/src_special/$": nil,
-			}
-
-			ctx.MockFileSystem(mockFS)
-
-			ctx.Register()
-			_, errs := ctx.ParseFileList(".", []string{"fg/Android.bp", "foo/Android.bp"})
-			FailIfErrored(t, errs)
-			_, errs = ctx.PrepareBuildActions(config)
-			FailIfErrored(t, errs)
-
-			m := ctx.ModuleForTests("foo", "").Module().(*expandSourcesTestModule)
-
-			if g, w := m.srcs.Strings(), test.srcs; !reflect.DeepEqual(g, w) {
-				t.Errorf("want srcs %q, got %q", w, g)
-			}
-
-			if g, w := m.rels, test.rels; !reflect.DeepEqual(g, w) {
-				t.Errorf("want rels %q, got %q", w, g)
-			}
-		})
+func TestPathsForModuleSrc_AllowMissingDependencies(t *testing.T) {
+	buildDir, err := ioutil.TempDir("", "soong_paths_for_module_src_allow_missing_dependencies_test")
+	if err != nil {
+		t.Fatal(err)
 	}
+	defer os.RemoveAll(buildDir)
+
+	config := TestConfig(buildDir, nil)
+	config.TestProductVariables.Allow_missing_dependencies = proptools.BoolPtr(true)
+
+	ctx := NewTestContext()
+	ctx.SetAllowMissingDependencies(true)
+
+	ctx.RegisterModuleType("test", ModuleFactoryAdaptor(pathForModuleSrcTestModuleFactory))
+
+	bp := `
+		test {
+			name: "foo",
+			srcs: [":a"],
+			exclude_srcs: [":b"],
+			src: ":c",
+		}
+	`
+
+	mockFS := map[string][]byte{
+		"Android.bp": []byte(bp),
+	}
+
+	ctx.MockFileSystem(mockFS)
+
+	ctx.Register()
+	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
+	FailIfErrored(t, errs)
+	_, errs = ctx.PrepareBuildActions(config)
+	FailIfErrored(t, errs)
+
+	foo := ctx.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)
+
+	if g, w := foo.missingDeps, []string{"a", "b", "c"}; !reflect.DeepEqual(g, w) {
+		t.Errorf("want missing deps %q, got %q", w, g)
+	}
+
+	if g, w := foo.srcs, []string{}; !reflect.DeepEqual(g, w) {
+		t.Errorf("want srcs %q, got %q", w, g)
+	}
+
+	if g, w := foo.src, ""; g != w {
+		t.Errorf("want src %q, got %q", w, g)
+	}
+
 }
 
 func ExampleOutputPath_ReplaceExtension() {
diff --git a/android/prebuilt.go b/android/prebuilt.go
index ea4870d..5bd0e2d 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -61,7 +61,7 @@
 
 	// Return the singleton source after expanding any filegroup in the
 	// sources.
-	return ctx.ExpandSource((*p.srcs)[0], "")
+	return PathForModuleSrc(ctx, (*p.srcs)[0])
 }
 
 func InitPrebuiltModule(module PrebuiltInterface, srcs *[]string) {
diff --git a/android/prebuilt_etc.go b/android/prebuilt_etc.go
index 0c68b0c..2a3e07e 100644
--- a/android/prebuilt_etc.go
+++ b/android/prebuilt_etc.go
@@ -88,7 +88,7 @@
 }
 
 func (p *PrebuiltEtc) SourceFilePath(ctx ModuleContext) Path {
-	return ctx.ExpandSource(String(p.properties.Src), "src")
+	return PathForModuleSrc(ctx, String(p.properties.Src))
 }
 
 // This allows other derivative modules (e.g. prebuilt_etc_xml) to perform
@@ -110,7 +110,7 @@
 }
 
 func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx ModuleContext) {
-	p.sourceFilePath = ctx.ExpandSource(String(p.properties.Src), "src")
+	p.sourceFilePath = PathForModuleSrc(ctx, String(p.properties.Src))
 	filename := String(p.properties.Filename)
 	filename_from_src := Bool(p.properties.Filename_from_src)
 	if filename == "" {
diff --git a/android/sh_binary.go b/android/sh_binary.go
index 8bb3517..bee61ef 100644
--- a/android/sh_binary.go
+++ b/android/sh_binary.go
@@ -82,7 +82,7 @@
 }
 
 func (s *ShBinary) SourceFilePath(ctx ModuleContext) Path {
-	return ctx.ExpandSource(String(s.properties.Src), "src")
+	return PathForModuleSrc(ctx, String(s.properties.Src))
 }
 
 func (s *ShBinary) OutputFile() OutputPath {
@@ -98,7 +98,7 @@
 }
 
 func (s *ShBinary) GenerateAndroidBuildActions(ctx ModuleContext) {
-	s.sourceFilePath = ctx.ExpandSource(String(s.properties.Src), "src")
+	s.sourceFilePath = PathForModuleSrc(ctx, String(s.properties.Src))
 	filename := String(s.properties.Filename)
 	filename_from_src := Bool(s.properties.Filename_from_src)
 	if filename == "" {
diff --git a/apex/apex.go b/apex/apex.go
index 04b70d4..ad1ef74 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -839,7 +839,7 @@
 		a.container_private_key_file = key
 	}
 
-	manifest := ctx.ExpandSource(proptools.StringDefault(a.properties.Manifest, "apex_manifest.json"), "manifest")
+	manifest := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json"))
 
 	var abis []string
 	for _, target := range ctx.MultiTargets() {
@@ -936,7 +936,7 @@
 		}
 
 		if a.properties.AndroidManifest != nil {
-			androidManifestFile := ctx.ExpandSource(proptools.String(a.properties.AndroidManifest), "androidManifest")
+			androidManifestFile := android.PathForModuleSrc(ctx, proptools.String(a.properties.AndroidManifest))
 			implicitInputs = append(implicitInputs, androidManifestFile)
 			optFlags = append(optFlags, "--android_manifest "+androidManifestFile.String())
 		}
@@ -1015,7 +1015,7 @@
 	if a.installable() {
 		// For flattened APEX, do nothing but make sure that apex_manifest.json file is also copied along
 		// with other ordinary files.
-		manifest := ctx.ExpandSource(proptools.StringDefault(a.properties.Manifest, "apex_manifest.json"), "manifest")
+		manifest := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json"))
 
 		// rename to apex_manifest.json
 		copiedManifest := android.PathForModuleOut(ctx, "apex_manifest.json")
diff --git a/bpf/bpf.go b/bpf/bpf.go
index 01e98f1..073f62d 100644
--- a/bpf/bpf.go
+++ b/bpf/bpf.go
@@ -76,7 +76,7 @@
 
 	cflags = append(cflags, bpf.properties.Cflags...)
 
-	srcs := ctx.ExpandSources(bpf.properties.Srcs, nil)
+	srcs := android.PathsForModuleSrc(ctx, bpf.properties.Srcs)
 
 	for _, src := range srcs {
 		obj := android.ObjPathWithExt(ctx, "", src, "o")
diff --git a/cc/binary.go b/cc/binary.go
index cae1739..7f7c600 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -384,7 +384,7 @@
 
 	TransformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs, deps.StaticLibs,
 		deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
-		builderFlags, outputFile)
+		builderFlags, outputFile, nil)
 
 	objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...)
 	objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)
diff --git a/cc/builder.go b/cc/builder.go
index 97ae806..dab887c 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -26,6 +26,7 @@
 	"strings"
 
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/pathtools"
 
 	"android/soong/android"
 	"android/soong/cc/config"
@@ -597,7 +598,7 @@
 // and shared libraries, to a shared library (.so) or dynamic executable
 func TransformObjToDynamicBinary(ctx android.ModuleContext,
 	objFiles, sharedLibs, staticLibs, lateStaticLibs, wholeStaticLibs, deps android.Paths,
-	crtBegin, crtEnd android.OptionalPath, groupLate bool, flags builderFlags, outputFile android.WritablePath) {
+	crtBegin, crtEnd android.OptionalPath, groupLate bool, flags builderFlags, outputFile android.WritablePath, implicitOutputs android.WritablePaths) {
 
 	ldCmd := "${config.ClangBin}/clang++"
 
@@ -634,7 +635,11 @@
 	}
 
 	for _, lib := range sharedLibs {
-		libFlagsList = append(libFlagsList, lib.String())
+		libFile := lib.String()
+		if ctx.Windows() {
+			libFile = pathtools.ReplaceExtension(libFile, "a")
+		}
+		libFlagsList = append(libFlagsList, libFile)
 	}
 
 	deps = append(deps, staticLibs...)
@@ -645,11 +650,12 @@
 	}
 
 	ctx.Build(pctx, android.BuildParams{
-		Rule:        ld,
-		Description: "link " + outputFile.Base(),
-		Output:      outputFile,
-		Inputs:      objFiles,
-		Implicits:   deps,
+		Rule:            ld,
+		Description:     "link " + outputFile.Base(),
+		Output:          outputFile,
+		ImplicitOutputs: implicitOutputs,
+		Inputs:          objFiles,
+		Implicits:       deps,
 		Args: map[string]string{
 			"ldCmd":    ldCmd,
 			"crtBegin": crtBegin.String(),
diff --git a/cc/compiler.go b/cc/compiler.go
index df396e8..0ab1f01 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -256,7 +256,7 @@
 func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
 	tc := ctx.toolchain()
 
-	compiler.srcsBeforeGen = ctx.ExpandSources(compiler.Properties.Srcs, compiler.Properties.Exclude_srcs)
+	compiler.srcsBeforeGen = android.PathsForModuleSrcExcludes(ctx, compiler.Properties.Srcs, compiler.Properties.Exclude_srcs)
 	compiler.srcsBeforeGen = append(compiler.srcsBeforeGen, deps.GeneratedSources...)
 
 	CheckBadCompilerFlags(ctx, "cflags", compiler.Properties.Cflags)
diff --git a/cc/library.go b/cc/library.go
index 5df5112..7216832 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -347,9 +347,10 @@
 				)
 			}
 		} else {
-			f = append(f,
-				"-shared",
-				"-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix())
+			f = append(f, "-shared")
+			if !ctx.Windows() {
+				f = append(f, "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix())
+			}
 		}
 
 		flags.LdFlags = append(f, flags.LdFlags...)
@@ -450,11 +451,11 @@
 	buildFlags := flagsToBuilderFlags(flags)
 
 	if library.static() {
-		srcs := ctx.ExpandSources(library.Properties.Static.Srcs, nil)
+		srcs := android.PathsForModuleSrc(ctx, library.Properties.Static.Srcs)
 		objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceStaticLibrary,
 			srcs, library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps))
 	} else if library.shared() {
-		srcs := ctx.ExpandSources(library.Properties.Shared.Srcs, nil)
+		srcs := android.PathsForModuleSrc(ctx, library.Properties.Shared.Srcs)
 		objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceSharedLibrary,
 			srcs, library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps))
 	}
@@ -673,6 +674,14 @@
 	outputFile := android.PathForModuleOut(ctx, fileName)
 	ret := outputFile
 
+	var implicitOutputs android.WritablePaths
+	if ctx.Windows() {
+		importLibraryPath := android.PathForModuleOut(ctx, pathtools.ReplaceExtension(fileName, "a"))
+
+		flags.LdFlags = append(flags.LdFlags, "-Wl,--out-implib="+importLibraryPath.String())
+		implicitOutputs = append(implicitOutputs, importLibraryPath)
+	}
+
 	builderFlags := flagsToBuilderFlags(flags)
 
 	// Optimize out relinking against shared libraries whose interface hasn't changed by
@@ -724,7 +733,7 @@
 
 	TransformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs,
 		deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
-		linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile)
+		linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile, implicitOutputs)
 
 	objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...)
 	objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)
diff --git a/cc/linker.go b/cc/linker.go
index fd958ba..179a998 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -290,10 +290,6 @@
 	if ctx.Darwin() {
 		return false
 	}
-	// http://b/110800681 - lld cannot link Android's Windows modules yet.
-	if ctx.Windows() {
-		return false
-	}
 	if linker.Properties.Use_clang_lld != nil {
 		return Bool(linker.Properties.Use_clang_lld)
 	}
@@ -347,7 +343,7 @@
 			// darwin defaults to treating undefined symbols as errors
 			flags.LdFlags = append(flags.LdFlags, "-Wl,-undefined,dynamic_lookup")
 		}
-	} else if !ctx.Darwin() {
+	} else if !ctx.Darwin() && !ctx.Windows() {
 		flags.LdFlags = append(flags.LdFlags, "-Wl,--no-undefined")
 	}
 
@@ -384,7 +380,7 @@
 
 	flags.LdFlags = append(flags.LdFlags, proptools.NinjaAndShellEscapeList(linker.Properties.Ldflags)...)
 
-	if ctx.Host() {
+	if ctx.Host() && !ctx.Windows() {
 		rpath_prefix := `\$$ORIGIN/`
 		if ctx.Darwin() {
 			rpath_prefix = "@loader_path/"
diff --git a/cc/ndk_headers.go b/cc/ndk_headers.go
index 2024180..5e45c1a 100644
--- a/cc/ndk_headers.go
+++ b/cc/ndk_headers.go
@@ -90,7 +90,7 @@
 	properties headerProperties
 
 	installPaths android.Paths
-	licensePath  android.ModuleSrcPath
+	licensePath  android.Path
 }
 
 func getHeaderInstallDir(ctx android.ModuleContext, header android.Path, from string,
@@ -140,7 +140,7 @@
 		return
 	}
 
-	srcFiles := ctx.ExpandSources(m.properties.Srcs, m.properties.Exclude_srcs)
+	srcFiles := android.PathsForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs)
 	for _, header := range srcFiles {
 		installDir := getHeaderInstallDir(ctx, header, String(m.properties.From),
 			String(m.properties.To))
@@ -204,7 +204,7 @@
 	properties versionedHeaderProperties
 
 	installPaths android.Paths
-	licensePath  android.ModuleSrcPath
+	licensePath  android.Path
 }
 
 func (m *versionedHeaderModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -232,7 +232,8 @@
 	processHeadersWithVersioner(ctx, fromSrcPath, toOutputPath, srcFiles, installPaths)
 }
 
-func processHeadersWithVersioner(ctx android.ModuleContext, srcDir, outDir android.Path, srcFiles android.Paths, installPaths []android.WritablePath) android.Path {
+func processHeadersWithVersioner(ctx android.ModuleContext, srcDir, outDir android.Path,
+	srcFiles android.Paths, installPaths []android.WritablePath) android.Path {
 	// The versioner depends on a dependencies directory to simplify determining include paths
 	// when parsing headers. This directory contains architecture specific directories as well
 	// as a common directory, each of which contains symlinks to the actually directories to
@@ -326,7 +327,7 @@
 	properties preprocessedHeadersProperties
 
 	installPaths android.Paths
-	licensePath  android.ModuleSrcPath
+	licensePath  android.Path
 }
 
 func (m *preprocessedHeadersModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -337,7 +338,7 @@
 	preprocessor := android.PathForModuleSrc(ctx, String(m.properties.Preprocessor))
 	m.licensePath = android.PathForModuleSrc(ctx, String(m.properties.License))
 
-	srcFiles := ctx.ExpandSources(m.properties.Srcs, m.properties.Exclude_srcs)
+	srcFiles := android.PathsForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs)
 	installDir := getCurrentIncludePath(ctx).Join(ctx, String(m.properties.To))
 	for _, src := range srcFiles {
 		installPath := installDir.Join(ctx, src.Base())
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 7297718..26418ad 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -35,7 +35,11 @@
 	asanLdflags = []string{"-Wl,-u,__asan_preinit"}
 	asanLibs    = []string{"libasan"}
 
-	hwasanCflags = []string{"-fno-omit-frame-pointer", "-Wno-frame-larger-than=", "-mllvm", "-hwasan-create-frame-descriptions=0"}
+	// TODO(pcc): Stop passing -hwasan-allow-ifunc here once it has been made
+	// the default.
+	hwasanCflags = []string{"-fno-omit-frame-pointer", "-Wno-frame-larger-than=",
+		"-mllvm", "-hwasan-create-frame-descriptions=0",
+		"-mllvm", "-hwasan-allow-ifunc"}
 
 	cfiCflags = []string{"-flto", "-fsanitize-cfi-cross-dso",
 		"-fsanitize-blacklist=external/compiler-rt/lib/cfi/cfi_blacklist.txt"}
@@ -50,12 +54,7 @@
 
 	intOverflowCflags = []string{"-fsanitize-blacklist=build/soong/cc/config/integer_overflow_blacklist.txt"}
 
-	// Pass -Xclang before -fsanitize-minimal-runtime to work around a driver
-	// check which rejects -fsanitize-minimal-runtime together with
-	// -fsanitize=shadow-call-stack even though this combination of flags
-	// is valid.
-	// TODO(pcc): Remove the -Xclang once LLVM r346526 is rolled into the compiler.
-	minimalRuntimeFlags = []string{"-Xclang", "-fsanitize-minimal-runtime", "-fno-sanitize-trap=integer,undefined",
+	minimalRuntimeFlags = []string{"-fsanitize-minimal-runtime", "-fno-sanitize-trap=integer,undefined",
 		"-fno-sanitize-recover=integer,undefined"}
 	hwasanGlobalOptions = []string{"heap_history_size=1023,stack_history_size=512"}
 )
@@ -312,10 +311,7 @@
 	}
 
 	// SCS is only implemented on AArch64.
-	// We also disable SCS if ASAN, TSAN or HWASAN are enabled because Clang considers
-	// them to be incompatible, although they are in fact compatible.
-	// TODO(pcc): Remove these checks once r347282 is rolled into the compiler.
-	if ctx.Arch().ArchType != android.Arm64 || Bool(s.Address) || Bool(s.Thread) || Bool(s.Hwaddress) {
+	if ctx.Arch().ArchType != android.Arm64 {
 		s.Scs = nil
 	}
 
diff --git a/cc/test.go b/cc/test.go
index f0274e9..c3fadbd 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -253,7 +253,7 @@
 }
 
 func (test *testBinary) install(ctx ModuleContext, file android.Path) {
-	test.data = ctx.ExpandSources(test.Properties.Data, nil)
+	test.data = android.PathsForModuleSrc(ctx, test.Properties.Data)
 	optionsMap := map[string]string{}
 	if Bool(test.testDecorator.Properties.Isolated) {
 		optionsMap["not-shardable"] = "true"
@@ -378,7 +378,7 @@
 }
 
 func (benchmark *benchmarkDecorator) install(ctx ModuleContext, file android.Path) {
-	benchmark.data = ctx.ExpandSources(benchmark.Properties.Data, nil)
+	benchmark.data = android.PathsForModuleSrc(ctx, benchmark.Properties.Data)
 	benchmark.testConfig = tradefed.AutoGenNativeBenchmarkTestConfig(ctx, benchmark.Properties.Test_config,
 		benchmark.Properties.Test_config_template, benchmark.Properties.Test_suites)
 
diff --git a/cc/test_data_test.go b/cc/test_data_test.go
index 7ba244e..21ea765 100644
--- a/cc/test_data_test.go
+++ b/cc/test_data_test.go
@@ -178,5 +178,5 @@
 }
 
 func (test *testDataTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	test.data = ctx.ExpandSources(test.Properties.Data, nil)
+	test.data = android.PathsForModuleSrc(ctx, test.Properties.Data)
 }
diff --git a/genrule/genrule.go b/genrule/genrule.go
index f265eb6..c8be61a 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -225,14 +225,14 @@
 	}
 
 	for _, toolFile := range g.properties.Tool_files {
-		paths := ctx.ExpandSources([]string{toolFile}, nil)
+		paths := android.PathsForModuleSrc(ctx, []string{toolFile})
 		g.deps = append(g.deps, paths...)
 		addLocationLabel(toolFile, paths.Strings())
 	}
 
 	var srcFiles android.Paths
 	for _, in := range g.properties.Srcs {
-		paths := ctx.ExpandSources([]string{in}, g.properties.Exclude_srcs)
+		paths := android.PathsForModuleSrcExcludes(ctx, []string{in}, g.properties.Exclude_srcs)
 		srcFiles = append(srcFiles, paths...)
 		addLocationLabel(in, paths.Strings())
 	}
diff --git a/java/aapt2.go b/java/aapt2.go
index d217b9f..bcc8e97 100644
--- a/java/aapt2.go
+++ b/java/aapt2.go
@@ -161,7 +161,7 @@
 func aapt2Link(ctx android.ModuleContext,
 	packageRes, genJar, proguardOptions, rTxt, extraPackages android.WritablePath,
 	flags []string, deps android.Paths,
-	compiledRes, compiledOverlay android.Paths) {
+	compiledRes, compiledOverlay android.Paths, splitPackages android.WritablePaths) {
 
 	genDir := android.PathForModuleGen(ctx, "aapt2", "R")
 
@@ -196,12 +196,14 @@
 		inFlags = append(inFlags, "-R", "@"+overlayFileList.String())
 	}
 
+	implicitOutputs := append(splitPackages, proguardOptions, genJar, rTxt, extraPackages)
+
 	ctx.Build(pctx, android.BuildParams{
 		Rule:            aapt2LinkRule,
 		Description:     "aapt2 link",
 		Implicits:       deps,
 		Output:          packageRes,
-		ImplicitOutputs: android.WritablePaths{proguardOptions, genJar, rTxt, extraPackages},
+		ImplicitOutputs: implicitOutputs,
 		Args: map[string]string{
 			"flags":           strings.Join(flags, " "),
 			"inFlags":         strings.Join(inFlags, " "),
diff --git a/java/aar.go b/java/aar.go
index 3f13e59..1a5ea4d 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -83,9 +83,18 @@
 	useEmbeddedDex        bool
 	usesNonSdkApis        bool
 
+	splitNames []string
+	splits     []split
+
 	aaptProperties aaptProperties
 }
 
+type split struct {
+	name   string
+	suffix string
+	path   android.Path
+}
+
 func (a *aapt) ExportPackage() android.Path {
 	return a.exportPackage
 }
@@ -121,7 +130,7 @@
 	// Find implicit or explicit asset and resource dirs
 	assetDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Asset_dirs, "assets")
 	resourceDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res")
-	resourceZips := ctx.ExpandSources(a.aaptProperties.Resource_zips, nil)
+	resourceZips := android.PathsForModuleSrc(ctx, a.aaptProperties.Resource_zips)
 
 	var linkDeps android.Paths
 
@@ -248,8 +257,23 @@
 		compiledOverlay = append(compiledOverlay, aapt2Compile(ctx, dir.dir, dir.files).Paths()...)
 	}
 
+	var splitPackages android.WritablePaths
+	var splits []split
+
+	for _, s := range a.splitNames {
+		suffix := strings.Replace(s, ",", "_", -1)
+		path := android.PathForModuleOut(ctx, "package_"+suffix+".apk")
+		linkFlags = append(linkFlags, "--split", path.String()+":"+s)
+		splitPackages = append(splitPackages, path)
+		splits = append(splits, split{
+			name:   s,
+			suffix: suffix,
+			path:   path,
+		})
+	}
+
 	aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt, extraPackages,
-		linkFlags, linkDeps, compiledRes, compiledOverlay)
+		linkFlags, linkDeps, compiledRes, compiledOverlay, splitPackages)
 
 	a.aaptSrcJar = srcJar
 	a.exportPackage = packageRes
@@ -258,6 +282,7 @@
 	a.rroDirs = rroDirs
 	a.extraAaptPackagesFile = extraPackages
 	a.rTxt = rTxt
+	a.splits = splits
 }
 
 // aaptLibs collects libraries from dependencies and sdk_version and converts them into paths
@@ -564,7 +589,7 @@
 	overlayRes := append(android.Paths{flata}, transitiveStaticLibs...)
 
 	aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, rTxt, a.extraAaptPackagesFile,
-		linkFlags, linkDeps, nil, overlayRes)
+		linkFlags, linkDeps, nil, overlayRes, nil)
 }
 
 var _ Dependency = (*AARImport)(nil)
diff --git a/java/androidmk.go b/java/androidmk.go
index 04b328d..0c3b1c7 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -131,6 +131,28 @@
 	}
 }
 
+func (prebuilt *DexImport) AndroidMk() android.AndroidMkData {
+	return android.AndroidMkData{
+		Class:      "JAVA_LIBRARIES",
+		OutputFile: android.OptionalPathForPath(prebuilt.maybeStrippedDexJarFile),
+		Include:    "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
+		Extra: []android.AndroidMkExtraFunc{
+			func(w io.Writer, outputFile android.Path) {
+				if prebuilt.dexJarFile != nil {
+					fmt.Fprintln(w, "LOCAL_SOONG_DEX_JAR :=", prebuilt.dexJarFile.String())
+					// TODO(b/125517186): export the dex jar as a classes jar to match some mis-uses in Make until
+					// boot_jars_package_check.mk can check dex jars.
+					fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", prebuilt.dexJarFile.String())
+					fmt.Fprintln(w, "LOCAL_SOONG_CLASSES_JAR :=", prebuilt.dexJarFile.String())
+				}
+				if len(prebuilt.dexpreopter.builtInstalled) > 0 {
+					fmt.Fprintln(w, "LOCAL_SOONG_BUILT_INSTALLED :=", prebuilt.dexpreopter.builtInstalled)
+				}
+			},
+		},
+	}
+}
+
 func (prebuilt *AARImport) AndroidMk() android.AndroidMkData {
 	return android.AndroidMkData{
 		Class:      "JAVA_LIBRARIES",
@@ -262,6 +284,10 @@
 				if len(app.dexpreopter.builtInstalled) > 0 {
 					fmt.Fprintln(w, "LOCAL_SOONG_BUILT_INSTALLED :=", app.dexpreopter.builtInstalled)
 				}
+				for _, split := range app.aapt.splits {
+					install := "$(LOCAL_MODULE_PATH)/" + strings.TrimSuffix(app.installApkName, ".apk") + split.suffix + ".apk"
+					fmt.Fprintln(w, "LOCAL_SOONG_BUILT_INSTALLED +=", split.path.String()+":"+install)
+				}
 			},
 		},
 	}
diff --git a/java/app.go b/java/app.go
index 8a422fc..8f5d010 100644
--- a/java/app.go
+++ b/java/app.go
@@ -226,6 +226,8 @@
 
 	aaptLinkFlags = append(aaptLinkFlags, a.additionalAaptFlags...)
 
+	a.aapt.splitNames = a.appProperties.Package_splits
+
 	a.aapt.buildActions(ctx, sdkContext(a), aaptLinkFlags...)
 
 	// apps manifests are handled by aapt, don't let Module see them
@@ -341,19 +343,32 @@
 	CreateAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates)
 	a.outputFile = packageFile
 
+	for _, split := range a.aapt.splits {
+		// Sign the split APKs
+		packageFile := android.PathForModuleOut(ctx, ctx.ModuleName()+"_"+split.suffix+".apk")
+		CreateAppPackage(ctx, packageFile, split.path, nil, nil, certificates)
+		a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
+	}
+
 	// Build an app bundle.
 	bundleFile := android.PathForModuleOut(ctx, "base.zip")
 	BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile)
 	a.bundleFile = bundleFile
 
 	// Install the app package.
+	var installDir android.OutputPath
 	if ctx.ModuleName() == "framework-res" {
 		// framework-res.apk is installed as system/framework/framework-res.apk
-		ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), ctx.ModuleName()+".apk", a.outputFile)
+		installDir = android.PathForModuleInstall(ctx, "framework")
 	} else if Bool(a.appProperties.Privileged) {
-		ctx.InstallFile(android.PathForModuleInstall(ctx, "priv-app", a.installApkName), a.installApkName+".apk", a.outputFile)
+		installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName)
 	} else {
-		ctx.InstallFile(android.PathForModuleInstall(ctx, "app", a.installApkName), a.installApkName+".apk", a.outputFile)
+		installDir = android.PathForModuleInstall(ctx, "app", a.installApkName)
+	}
+
+	ctx.InstallFile(installDir, a.installApkName+".apk", a.outputFile)
+	for _, split := range a.aapt.splits {
+		ctx.InstallFile(installDir, a.installApkName+"_"+split.suffix+".apk", split.path)
 	}
 }
 
@@ -455,7 +470,7 @@
 	a.generateAndroidBuildActions(ctx)
 
 	a.testConfig = tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config, a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites)
-	a.data = ctx.ExpandSources(a.testProperties.Data, nil)
+	a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
 }
 
 func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) {
diff --git a/java/app_builder.go b/java/app_builder.go
index bc91d55..e5ccbbc 100644
--- a/java/app_builder.go
+++ b/java/app_builder.go
@@ -65,7 +65,8 @@
 func CreateAppPackage(ctx android.ModuleContext, outputFile android.WritablePath,
 	packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate) {
 
-	unsignedApk := android.PathForModuleOut(ctx, "unsigned.apk")
+	unsignedApkName := strings.TrimSuffix(outputFile.Base(), ".apk") + "-unsigned.apk"
+	unsignedApk := android.PathForModuleOut(ctx, unsignedApkName)
 
 	var inputs android.Paths
 	if dexJarFile != nil {
diff --git a/java/app_test.go b/java/app_test.go
index 1784fc3..3942ecd 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -106,6 +106,30 @@
 	}
 }
 
+func TestAppSplits(t *testing.T) {
+	ctx := testApp(t, `
+				android_app {
+					name: "foo",
+					srcs: ["a.java"],
+					package_splits: ["v4", "v7,hdpi"],
+				}`)
+
+	foo := ctx.ModuleForTests("foo", "android_common")
+
+	expectedOutputs := []string{
+		filepath.Join(buildDir, ".intermediates/foo/android_common/foo.apk"),
+		filepath.Join(buildDir, ".intermediates/foo/android_common/foo_v4.apk"),
+		filepath.Join(buildDir, ".intermediates/foo/android_common/foo_v7_hdpi.apk"),
+	}
+	for _, expectedOutput := range expectedOutputs {
+		foo.Output(expectedOutput)
+	}
+
+	if g, w := foo.Module().(*AndroidApp).Srcs().Strings(), expectedOutputs; !reflect.DeepEqual(g, w) {
+		t.Errorf("want Srcs() = %q, got %q", w, g)
+	}
+}
+
 func TestResourceDirs(t *testing.T) {
 	testCases := []struct {
 		name      string
diff --git a/java/config/config.go b/java/config/config.go
index 2762a4d..3452a1d 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -41,6 +41,7 @@
 		"services",
 		"android.car",
 		"android.car7",
+		"conscrypt",
 		"core-oj",
 		"core-libart",
 	}
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 64de21a..a23b477 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -152,7 +152,7 @@
 
 	ctx.VisitAllModules(func(module android.Module) {
 		// Collect dex jar paths for the modules listed above.
-		if j, ok := module.(Dependency); ok {
+		if j, ok := module.(interface{ DexJar() android.Path }); ok {
 			name := ctx.ModuleName(module)
 			if i := android.IndexList(name, image.modules); i != -1 {
 				bootDexJars[i] = j.DexJar()
diff --git a/java/dexpreopt_bootjars_test.go b/java/dexpreopt_bootjars_test.go
index c99540d..141f7ba 100644
--- a/java/dexpreopt_bootjars_test.go
+++ b/java/dexpreopt_bootjars_test.go
@@ -37,13 +37,18 @@
 			srcs: ["b.java"],
 			installable: true,
 		}
+
+		dex_import {
+			name: "baz",
+			jars: ["a.jar"],
+		}
 	`
 
 	config := testConfig(nil)
 
 	pathCtx := android.PathContextForTesting(config, nil)
 	dexpreoptConfig := dexpreopt.GlobalConfigForTests(pathCtx)
-	dexpreoptConfig.RuntimeApexJars = []string{"foo", "bar"}
+	dexpreoptConfig.RuntimeApexJars = []string{"foo", "bar", "baz"}
 	setDexpreoptTestGlobalConfig(config, dexpreoptConfig)
 
 	ctx := testContext(config, bp, nil)
@@ -59,6 +64,7 @@
 	expectedInputs := []string{
 		"dex_bootjars_input/foo.jar",
 		"dex_bootjars_input/bar.jar",
+		"dex_bootjars_input/baz.jar",
 	}
 
 	for i := range expectedInputs {
@@ -78,15 +84,19 @@
 
 		"dex_bootjars/system/framework/arm64/boot.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-bar.oat",
+		"dex_bootjars/system/framework/arm64/boot-baz.oat",
 
 		"dex_bootjars/system/framework/arm64/boot.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-bar.oat",
+		"dex_bootjars_unstripped/system/framework/arm64/boot-baz.oat",
 	}
 
 	for i := range expectedOutputs {
diff --git a/java/dexpreopt_test.go b/java/dexpreopt_test.go
index 6838bd2..4af2f5c 100644
--- a/java/dexpreopt_test.go
+++ b/java/dexpreopt_test.go
@@ -119,6 +119,15 @@
 				}`,
 			enabled: false,
 		},
+		{
+			name: "dex_import",
+			bp: `
+				dex_import {
+					name: "foo",
+					jars: ["a.jar"],
+				}`,
+			enabled: true,
+		},
 	}
 
 	for _, test := range tests {
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 777cd9c..e163617 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -696,7 +696,7 @@
 	})
 	// do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
 	// may contain filegroup or genrule.
-	srcFiles := ctx.ExpandSources(j.properties.Srcs, j.properties.Exclude_srcs)
+	srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
 	flags := j.collectAidlFlags(ctx, deps)
 	srcFiles = j.genSources(ctx, srcFiles, flags)
 
@@ -715,12 +715,12 @@
 	}
 	j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
 
-	j.argFiles = ctx.ExpandSources(j.properties.Arg_files, nil)
+	j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
 	argFilesMap := map[string]string{}
 	argFileLabels := []string{}
 
 	for _, label := range j.properties.Arg_files {
-		var paths = ctx.ExpandSources([]string{label}, nil)
+		var paths = android.PathsForModuleSrc(ctx, []string{label})
 		if _, exists := argFilesMap[label]; !exists {
 			argFilesMap[label] = strings.Join(paths.Strings(), " ")
 			argFileLabels = append(argFileLabels, label)
@@ -935,22 +935,22 @@
 	})
 
 	if len(d.properties.Html_dirs) > 0 {
-		htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
-		*implicits = append(*implicits, ctx.Glob(htmlDir.Join(ctx, "**/*").String(), nil)...)
-		args = args + " -htmldir " + htmlDir.String()
+		htmlDir := d.properties.Html_dirs[0]
+		*implicits = append(*implicits, android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")})...)
+		args = args + " -htmldir " + htmlDir
 	}
 
 	if len(d.properties.Html_dirs) > 1 {
-		htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
-		*implicits = append(*implicits, ctx.Glob(htmlDir2.Join(ctx, "**/*").String(), nil)...)
-		args = args + " -htmldir2 " + htmlDir2.String()
+		htmlDir2 := d.properties.Html_dirs[1]
+		*implicits = append(*implicits, android.PathsForModuleSrc(ctx, []string{filepath.Join(htmlDir2, "**/*")})...)
+		args = args + " -htmldir2 " + htmlDir2
 	}
 
 	if len(d.properties.Html_dirs) > 2 {
 		ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
 	}
 
-	knownTags := ctx.ExpandSources(d.properties.Knowntags, nil)
+	knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
 	*implicits = append(*implicits, knownTags...)
 
 	for _, kt := range knownTags {
@@ -1415,12 +1415,12 @@
 				"has to be non-empty if annotations was enabled (unless validating nullability)")
 		}
 		if migratingNullability {
-			previousApi := ctx.ExpandSource(String(d.properties.Previous_api), "previous_api")
+			previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
 			*implicits = append(*implicits, previousApi)
 			flags += " --migrate-nullness " + previousApi.String()
 		}
 		if s := String(d.properties.Validate_nullability_from_list); s != "" {
-			flags += " --validate-nullability-from-list " + ctx.ExpandSource(s, "validate_nullability_from_list").String()
+			flags += " --validate-nullability-from-list " + android.PathForModuleSrc(ctx, s).String()
 		}
 		if validatingNullability {
 			d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
@@ -1791,9 +1791,9 @@
 func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
 
 func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	path := android.PathForModuleSrc(ctx, String(d.properties.Path))
-	d.dir = path
-	d.deps = ctx.Glob(path.Join(ctx, "**/*").String(), nil)
+	path := String(d.properties.Path)
+	d.dir = android.PathForModuleSrc(ctx, path)
+	d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
 }
 
 //
diff --git a/java/java.go b/java/java.go
index dcd6dbe..e0da006 100644
--- a/java/java.go
+++ b/java/java.go
@@ -46,6 +46,7 @@
 	android.RegisterModuleType("java_import_host", ImportFactoryHost)
 	android.RegisterModuleType("java_device_for_host", DeviceForHostFactory)
 	android.RegisterModuleType("java_host_for_device", HostForDeviceFactory)
+	android.RegisterModuleType("dex_import", DexImportFactory)
 
 	android.RegisterSingletonType("logtags", LogtagsSingleton)
 }
@@ -288,7 +289,8 @@
 	proguardDictionary android.Path
 
 	// output file of the module, which may be a classes jar or a dex jar
-	outputFile android.Path
+	outputFile       android.Path
+	extraOutputFiles android.Paths
 
 	exportAidlIncludeDirs android.Paths
 
@@ -322,7 +324,7 @@
 }
 
 func (j *Module) Srcs() android.Paths {
-	return android.Paths{j.outputFile}
+	return append(android.Paths{j.outputFile}, j.extraOutputFiles...)
 }
 
 func (j *Module) DexJarFile() android.Path {
@@ -940,7 +942,7 @@
 	if flags.javaVersion == "1.9" {
 		j.properties.Srcs = append(j.properties.Srcs, j.properties.Openjdk9.Srcs...)
 	}
-	srcFiles := ctx.ExpandSources(j.properties.Srcs, j.properties.Exclude_srcs)
+	srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
 	if hasSrcExt(srcFiles.Strings(), ".proto") {
 		flags = protoFlags(ctx, &j.properties, &j.protoProperties, flags)
 	}
@@ -956,7 +958,7 @@
 	j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, srcFiles.Strings()...)
 
 	if j.properties.Jarjar_rules != nil {
-		j.expandJarjarRules = ctx.ExpandSource(*j.properties.Jarjar_rules, "jarjar_rules")
+		j.expandJarjarRules = android.PathForModuleSrc(ctx, *j.properties.Jarjar_rules)
 	}
 
 	jarName := ctx.ModuleName() + ".jar"
@@ -1131,10 +1133,10 @@
 
 	manifest := j.overrideManifest
 	if !manifest.Valid() && j.properties.Manifest != nil {
-		manifest = android.OptionalPathForPath(ctx.ExpandSource(*j.properties.Manifest, "manifest"))
+		manifest = android.OptionalPathForPath(android.PathForModuleSrc(ctx, *j.properties.Manifest))
 	}
 
-	services := ctx.ExpandSources(j.properties.Services, nil)
+	services := android.PathsForModuleSrc(ctx, j.properties.Services)
 	if len(services) > 0 {
 		servicesJar := android.PathForModuleOut(ctx, "services", jarName)
 		var zipargs []string
@@ -1430,14 +1432,14 @@
 	Module
 }
 
-func (j *Library) shouldUncompressDex(ctx android.ModuleContext) bool {
+func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bool {
 	// Store uncompressed (and do not strip) dex files from boot class path jars.
 	if inList(ctx.ModuleName(), ctx.Config().BootJars()) {
 		return true
 	}
 
 	// Store uncompressed dex files that are preopted on /system.
-	if !j.dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !odexOnSystemOther(ctx, j.dexpreopter.installPath)) {
+	if !dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !odexOnSystemOther(ctx, dexpreopter.installPath)) {
 		return true
 	}
 	if ctx.Config().UncompressPrivAppDex() &&
@@ -1452,7 +1454,7 @@
 	j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", ctx.ModuleName()+".jar")
 	j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
 	j.dexpreopter.isInstallable = Bool(j.properties.Installable)
-	j.dexpreopter.uncompressedDex = j.shouldUncompressDex(ctx)
+	j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter)
 	j.deviceProperties.UncompressDex = j.dexpreopter.uncompressedDex
 	j.compile(ctx)
 
@@ -1545,7 +1547,7 @@
 
 func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template, j.testProperties.Test_suites)
-	j.data = ctx.ExpandSources(j.testProperties.Data, nil)
+	j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data)
 
 	j.Library.GenerateAndroidBuildActions(ctx)
 }
@@ -1639,7 +1641,7 @@
 		j.isWrapperVariant = true
 
 		if j.binaryProperties.Wrapper != nil {
-			j.wrapperFile = ctx.ExpandSource(*j.binaryProperties.Wrapper, "wrapper")
+			j.wrapperFile = android.PathForModuleSrc(ctx, *j.binaryProperties.Wrapper)
 		} else {
 			j.wrapperFile = android.PathForSource(ctx, "build/soong/scripts/jar-wrapper.sh")
 		}
@@ -1763,7 +1765,7 @@
 }
 
 func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	jars := ctx.ExpandSources(j.properties.Jars, nil)
+	jars := android.PathsForModuleSrc(ctx, j.properties.Jars)
 
 	jarName := ctx.ModuleName() + ".jar"
 	outputFile := android.PathForModuleOut(ctx, "combined", jarName)
@@ -1900,6 +1902,113 @@
 	return module
 }
 
+// dex_import module
+
+type DexImportProperties struct {
+	Jars []string
+}
+
+type DexImport struct {
+	android.ModuleBase
+	android.DefaultableModuleBase
+	prebuilt android.Prebuilt
+
+	properties DexImportProperties
+
+	dexJarFile              android.Path
+	maybeStrippedDexJarFile android.Path
+
+	dexpreopter
+}
+
+func (j *DexImport) Prebuilt() *android.Prebuilt {
+	return &j.prebuilt
+}
+
+func (j *DexImport) PrebuiltSrcs() []string {
+	return j.properties.Jars
+}
+
+func (j *DexImport) Name() string {
+	return j.prebuilt.Name(j.ModuleBase.Name())
+}
+
+func (j *DexImport) DepsMutator(ctx android.BottomUpMutatorContext) {
+	android.ExtractSourcesDeps(ctx, j.properties.Jars)
+}
+
+func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	if len(j.properties.Jars) != 1 {
+		ctx.PropertyErrorf("jars", "exactly one jar must be provided")
+	}
+
+	j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", ctx.ModuleName()+".jar")
+	j.dexpreopter.isInstallable = true
+	j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter)
+
+	inputJar := ctx.ExpandSource(j.properties.Jars[0], "jars")
+	dexOutputFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar")
+
+	if j.dexpreopter.uncompressedDex {
+		rule := android.NewRuleBuilder()
+
+		temporary := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar.unaligned")
+		rule.Temporary(temporary)
+
+		// use zip2zip to uncompress classes*.dex files
+		rule.Command().
+			Tool(ctx.Config().HostToolPath(ctx, "zip2zip")).
+			FlagWithInput("-i ", inputJar).
+			FlagWithOutput("-o ", temporary).
+			FlagWithArg("-0 ", "'classes*.dex'")
+
+		// use zipalign to align uncompressed classes*.dex files
+		rule.Command().
+			Tool(ctx.Config().HostToolPath(ctx, "zipalign")).
+			Flag("-f").
+			Text("4").
+			Input(temporary).
+			Output(dexOutputFile)
+
+		rule.DeleteTemporaryFiles()
+
+		rule.Build(pctx, ctx, "uncompress_dex", "uncompress dex")
+	} else {
+		ctx.Build(pctx, android.BuildParams{
+			Rule:   android.Cp,
+			Input:  inputJar,
+			Output: dexOutputFile,
+		})
+	}
+
+	j.dexJarFile = dexOutputFile
+
+	dexOutputFile = j.dexpreopt(ctx, dexOutputFile)
+
+	j.maybeStrippedDexJarFile = dexOutputFile
+
+	ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
+		ctx.ModuleName()+".jar", dexOutputFile)
+}
+
+func (j *DexImport) DexJar() android.Path {
+	return j.dexJarFile
+}
+
+// dex_import imports a `.jar` file containing classes.dex files.
+//
+// A dex_import module cannot be used as a dependency of a java_* or android_* module, it can only be installed
+// to the device.
+func DexImportFactory() android.Module {
+	module := &DexImport{}
+
+	module.AddProperties(&module.properties)
+
+	android.InitPrebuiltModule(module, &module.properties.Jars)
+	InitJavaModule(module, android.DeviceSupported)
+	return module
+}
+
 //
 // Defaults
 //
@@ -1962,6 +2071,7 @@
 		&ImportProperties{},
 		&AARImportProperties{},
 		&sdkLibraryProperties{},
+		&DexImportProperties{},
 	)
 
 	android.InitDefaultsModule(module)
diff --git a/java/java_resources.go b/java/java_resources.go
index 6c1fd39..7161168 100644
--- a/java/java_resources.go
+++ b/java/java_resources.go
@@ -39,20 +39,20 @@
 	var excludeFiles []string
 
 	for _, exclude := range excludeResourceDirs {
-		dirs := ctx.Glob(android.PathForModuleSrc(ctx).Join(ctx, exclude).String(), nil)
+		dirs := ctx.Glob(android.PathForSource(ctx, ctx.ModuleDir()).Join(ctx, exclude).String(), nil)
 		for _, dir := range dirs {
 			excludeDirs = append(excludeDirs, dir.String())
-			excludeFiles = append(excludeFiles, dir.(android.ModuleSrcPath).Join(ctx, "**/*").String())
+			excludeFiles = append(excludeFiles, dir.(android.SourcePath).Join(ctx, "**/*").String())
 		}
 	}
 
-	excludeFiles = append(excludeFiles, ctx.ExpandSources(excludeResourceFiles, nil).Strings()...)
+	excludeFiles = append(excludeFiles, android.PathsForModuleSrc(ctx, excludeResourceFiles).Strings()...)
 
 	excludeFiles = append(excludeFiles, resourceExcludes...)
 
 	for _, resourceDir := range resourceDirs {
 		// resourceDir may be a glob, resolve it first
-		dirs := ctx.Glob(android.PathForModuleSrc(ctx).Join(ctx, resourceDir).String(), excludeDirs)
+		dirs := ctx.Glob(android.PathForSource(ctx, ctx.ModuleDir()).Join(ctx, resourceDir).String(), excludeDirs)
 		for _, dir := range dirs {
 			files := ctx.GlobFiles(filepath.Join(dir.String(), "**/*"), excludeFiles)
 
@@ -96,7 +96,7 @@
 func resourceFilesToJarArgs(ctx android.ModuleContext,
 	res, exclude []string) (args []string, deps android.Paths) {
 
-	files := ctx.ExpandSources(res, exclude)
+	files := android.PathsForModuleSrcExcludes(ctx, res, exclude)
 
 	lastDir := ""
 	for i, f := range files {
diff --git a/java/java_test.go b/java/java_test.go
index 952da11..35dd696 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -79,6 +79,7 @@
 	ctx.RegisterModuleType("java_system_modules", android.ModuleFactoryAdaptor(SystemModulesFactory))
 	ctx.RegisterModuleType("java_genrule", android.ModuleFactoryAdaptor(genRuleFactory))
 	ctx.RegisterModuleType("java_plugin", android.ModuleFactoryAdaptor(PluginFactory))
+	ctx.RegisterModuleType("dex_import", android.ModuleFactoryAdaptor(DexImportFactory))
 	ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(android.FileGroupFactory))
 	ctx.RegisterModuleType("genrule", android.ModuleFactoryAdaptor(genrule.GenRuleFactory))
 	ctx.RegisterModuleType("droiddoc", android.ModuleFactoryAdaptor(DroiddocFactory))
@@ -330,6 +331,11 @@
 			name: "baz",
 			jars: ["b.jar"],
 		}
+
+		dex_import {
+			name: "qux",
+			jars: ["b.jar"],
+		}
 		`)
 
 	javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
@@ -344,6 +350,8 @@
 	if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != bazJar.String() {
 		t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, bazJar.String())
 	}
+
+	ctx.ModuleForTests("qux", "android_common").Rule("Cp")
 }
 
 func TestDefaults(t *testing.T) {
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 6441c63..18866d5 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -675,6 +675,34 @@
 	if module.sdkLibraryProperties.Api_packages == nil {
 		mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
 	}
+
+	missing_current_api := false
+
+	for _, scope := range []string{"", "system-", "test-"} {
+		for _, api := range []string{"current.txt", "removed.txt"} {
+			path := path.Join(mctx.ModuleDir(), "api", scope+api)
+			p := android.ExistentPathForSource(mctx, path)
+			if !p.Valid() {
+				mctx.ModuleErrorf("Current api file %#v doesn't exist", path)
+				missing_current_api = true
+			}
+		}
+	}
+
+	if missing_current_api {
+		script := "build/soong/scripts/gen-java-current-api-files.sh"
+		p := android.ExistentPathForSource(mctx, script)
+
+		if !p.Valid() {
+			panic(fmt.Sprintf("script file %s doesn't exist", script))
+		}
+
+		mctx.ModuleErrorf("One or more current api files are missing. "+
+			"You can update them by:\n"+
+			"%s %q && m update-api", script, mctx.ModuleDir())
+		return
+	}
+
 	// for public API stubs
 	module.createStubsLibrary(mctx, apiScopePublic)
 	module.createDocs(mctx, apiScopePublic)
diff --git a/python/python.go b/python/python.go
index 6d16020..6eb9b6e 100644
--- a/python/python.go
+++ b/python/python.go
@@ -414,7 +414,7 @@
 		panic(fmt.Errorf("unknown Python Actual_version: %q for module: %q.",
 			p.properties.Actual_version, ctx.ModuleName()))
 	}
-	expandedSrcs := ctx.ExpandSources(srcs, exclude_srcs)
+	expandedSrcs := android.PathsForModuleSrcExcludes(ctx, srcs, exclude_srcs)
 	requiresSrcs := true
 	if p.bootstrapper != nil && !p.bootstrapper.autorun() {
 		requiresSrcs = false
@@ -424,7 +424,7 @@
 	}
 
 	// expand data files from "data" property.
-	expandedData := ctx.ExpandSources(p.properties.Data, nil)
+	expandedData := android.PathsForModuleSrc(ctx, p.properties.Data)
 
 	// sanitize pkg_path.
 	pkgPath := String(p.properties.Pkg_path)
diff --git a/scripts/gen-java-current-api-files.sh b/scripts/gen-java-current-api-files.sh
new file mode 100755
index 0000000..517d391
--- /dev/null
+++ b/scripts/gen-java-current-api-files.sh
@@ -0,0 +1,33 @@
+#!/bin/bash -e
+
+# Copyright (C) 2019 The Android Open Source Project
+#
+# 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.
+
+if [[ -z "$1" ]]; then
+  echo "usage: $0 <modulePath>" >&2
+  exit 1
+fi
+
+api_dir=$1/api
+
+mkdir -p "$api_dir"
+
+scopes=("" system- test-)
+apis=(current removed)
+
+for scope in "${scopes[@]}"; do
+  for api in "${apis[@]}"; do
+    touch "${api_dir}/${scope}${api}.txt"
+  done
+done
diff --git a/xml/xml.go b/xml/xml.go
index d89327f..7c670fb 100644
--- a/xml/xml.go
+++ b/xml/xml.go
@@ -79,7 +79,7 @@
 	p.PrebuiltEtc.GenerateAndroidBuildActions(ctx)
 
 	if p.properties.Schema != nil {
-		schema := ctx.ExpandSource(proptools.String(p.properties.Schema), "schema")
+		schema := android.PathForModuleSrc(ctx, proptools.String(p.properties.Schema))
 
 		switch schema.Ext() {
 		case ".dtd":