Merge "Add i18n-module-host-exports to the SDK list."
diff --git a/android/defs.go b/android/defs.go
index f5bd362..38ecb05 100644
--- a/android/defs.go
+++ b/android/defs.go
@@ -20,7 +20,7 @@
 	"testing"
 
 	"github.com/google/blueprint"
-	_ "github.com/google/blueprint/bootstrap"
+	"github.com/google/blueprint/bootstrap"
 	"github.com/google/blueprint/proptools"
 )
 
@@ -200,3 +200,8 @@
 
 	return content
 }
+
+// GlobToListFileRule creates a rule that writes a list of files matching a pattern to a file.
+func GlobToListFileRule(ctx ModuleContext, pattern string, excludes []string, file WritablePath) {
+	bootstrap.GlobFile(ctx.blueprintModuleContext(), pattern, excludes, file.String())
+}
diff --git a/android/module.go b/android/module.go
index 0bd64ed..429f311 100644
--- a/android/module.go
+++ b/android/module.go
@@ -331,6 +331,8 @@
 type ModuleContext interface {
 	BaseModuleContext
 
+	blueprintModuleContext() blueprint.ModuleContext
+
 	// Deprecated: use ModuleContext.Build instead.
 	ModuleBuild(pctx PackageContext, params ModuleBuildParams)
 
@@ -2596,6 +2598,10 @@
 	m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
 }
 
+func (m *moduleContext) blueprintModuleContext() blueprint.ModuleContext {
+	return m.bp
+}
+
 // SrcIsModule decodes module references in the format ":name" into the module name, or empty string if the input
 // was not a module reference.
 func SrcIsModule(s string) (module string) {
diff --git a/apex/androidmk.go b/apex/androidmk.go
index 6c76ad3f..e7f8b7f 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -425,6 +425,15 @@
 				for _, dist := range data.Entries.GetDistForGoals(a) {
 					fmt.Fprintf(w, dist)
 				}
+
+				if a.coverageOutputPath.String() != "" {
+					goal := "apps_only"
+					distFile := a.coverageOutputPath.String()
+					fmt.Fprintf(w, "ifneq (,$(filter $(my_register_name),$(TARGET_BUILD_APPS)))\n"+
+						" $(call dist-for-goals,%s,%s:ndk_apis_usedby_apex/$(notdir %s))\n"+
+						"endif",
+						goal, distFile, distFile)
+				}
 			}
 		}}
 }
diff --git a/cc/config/vndk.go b/cc/config/vndk.go
index a548452..8a0d7bd 100644
--- a/cc/config/vndk.go
+++ b/cc/config/vndk.go
@@ -21,10 +21,10 @@
 	"android.hardware.automotive.occupant_awareness-ndk_platform",
 	"android.hardware.light-ndk_platform",
 	"android.hardware.identity-ndk_platform",
-	"android.hardware.keymint-unstable-ndk_platform",
 	"android.hardware.nfc@1.2",
 	"android.hardware.power-ndk_platform",
 	"android.hardware.rebootescrow-ndk_platform",
+	"android.hardware.security.keymint-unstable-ndk_platform",
 	"android.hardware.vibrator-ndk_platform",
 	"android.system.keystore2-unstable-ndk_platform",
 	"libbinder",
diff --git a/java/aar.go b/java/aar.go
index 3b6b34e..3750f72 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -17,6 +17,7 @@
 import (
 	"fmt"
 	"path/filepath"
+	"strconv"
 	"strings"
 
 	"android/soong/android"
@@ -192,22 +193,31 @@
 		rroDirs = append(rroDirs, resRRODirs...)
 	}
 
-	var assetFiles android.Paths
-	for _, dir := range assetDirs {
-		assetFiles = append(assetFiles, androidResourceGlob(ctx, dir)...)
+	var assetDeps android.Paths
+	for i, dir := range assetDirs {
+		// Add a dependency on every file in the asset directory.  This ensures the aapt2
+		// rule will be rerun if one of the files in the asset directory is modified.
+		assetDeps = append(assetDeps, androidResourceGlob(ctx, dir)...)
+
+		// Add a dependency on a file that contains a list of all the files in the asset directory.
+		// This ensures the aapt2 rule will be run if a file is removed from the asset directory,
+		// or a file is added whose timestamp is older than the output of aapt2.
+		assetFileListFile := android.PathForModuleOut(ctx, "asset_dir_globs", strconv.Itoa(i)+".glob")
+		androidResourceGlobList(ctx, dir, assetFileListFile)
+		assetDeps = append(assetDeps, assetFileListFile)
 	}
 
 	assetDirStrings := assetDirs.Strings()
 	if a.noticeFile.Valid() {
 		assetDirStrings = append(assetDirStrings, filepath.Dir(a.noticeFile.Path().String()))
-		assetFiles = append(assetFiles, a.noticeFile.Path())
+		assetDeps = append(assetDeps, a.noticeFile.Path())
 	}
 
 	linkFlags = append(linkFlags, "--manifest "+manifestPath.String())
 	linkDeps = append(linkDeps, manifestPath)
 
 	linkFlags = append(linkFlags, android.JoinWithPrefix(assetDirStrings, "-A "))
-	linkDeps = append(linkDeps, assetFiles...)
+	linkDeps = append(linkDeps, assetDeps...)
 
 	// SDK version flags
 	minSdkVersion, err := sdkContext.minSdkVersion().effectiveVersionString(ctx)
diff --git a/java/android_resources.go b/java/android_resources.go
index 720d3a5..4d420cf 100644
--- a/java/android_resources.go
+++ b/java/android_resources.go
@@ -38,10 +38,21 @@
 	"*~",
 }
 
+// androidResourceGlob returns the list of files in the given directory, using the standard
+// exclusion patterns for Android resources.
 func androidResourceGlob(ctx android.ModuleContext, dir android.Path) android.Paths {
 	return ctx.GlobFiles(filepath.Join(dir.String(), "**/*"), androidResourceIgnoreFilenames)
 }
 
+// androidResourceGlobList creates a rule to write the list of files in the given directory, using
+// the standard exclusion patterns for Android resources, to the given output file.
+func androidResourceGlobList(ctx android.ModuleContext, dir android.Path,
+	fileListFile android.WritablePath) {
+
+	android.GlobToListFileRule(ctx, filepath.Join(dir.String(), "**/*"),
+		androidResourceIgnoreFilenames, fileListFile)
+}
+
 type overlayType int
 
 const (
diff --git a/rust/builder.go b/rust/builder.go
index 6079e30..8ec2da2 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -189,6 +189,7 @@
 	implicits = append(implicits, rustLibsToPaths(deps.ProcMacros)...)
 	implicits = append(implicits, deps.StaticLibs...)
 	implicits = append(implicits, deps.SharedLibs...)
+	implicits = append(implicits, deps.srcProviderFiles...)
 
 	if deps.CrtBegin.Valid() {
 		implicits = append(implicits, deps.CrtBegin.Path(), deps.CrtEnd.Path())
diff --git a/rust/library.go b/rust/library.go
index b7bf5e7..4ac52b4 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -433,6 +433,7 @@
 	if library.sourceProvider != nil {
 		// Assume the first source from the source provider is the library entry point.
 		srcPath = library.sourceProvider.Srcs()[0]
+		deps.srcProviderFiles = append(deps.srcProviderFiles, library.sourceProvider.Srcs()...)
 	} else {
 		srcPath, _ = srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs)
 	}
diff --git a/rust/protobuf.go b/rust/protobuf.go
index 0e79089..4fba34f 100644
--- a/rust/protobuf.go
+++ b/rust/protobuf.go
@@ -46,7 +46,7 @@
 var _ SourceProvider = (*protobufDecorator)(nil)
 
 type ProtobufProperties struct {
-	// List of realtive paths to proto files that will be used to generate the source
+	// List of relative paths to proto files that will be used to generate the source
 	Protos []string `android:"path,arch_variant"`
 
 	// List of additional flags to pass to aprotoc
@@ -80,6 +80,10 @@
 
 	protoFiles := android.PathsForModuleSrc(ctx, proto.Properties.Protos)
 
+	if len(protoFiles) == 0 {
+		ctx.PropertyErrorf("protos", "at least one protobuf must be defined.")
+	}
+
 	// Add exported dependency include paths
 	for _, include := range deps.depIncludePaths {
 		protoFlags.Flags = append(protoFlags.Flags, "-I"+include.String())
@@ -91,7 +95,7 @@
 	stemFile := android.PathForModuleOut(ctx, "mod_"+stem+".rs")
 
 	// stemFile must be first here as the first path in BaseSourceProvider.OutputFiles is the library entry-point.
-	outputs := android.WritablePaths{stemFile}
+	var outputs android.WritablePaths
 
 	rule := android.NewRuleBuilder(pctx, ctx)
 	for _, protoFile := range protoFiles {
@@ -112,14 +116,12 @@
 		outputs = append(outputs, ruleOutputs...)
 	}
 
-	rule.Command().
-		Implicits(outputs.Paths()).
-		Text("printf '" + proto.genModFileContents(ctx, protoNames) + "' >").
-		Output(stemFile)
+	android.WriteFileRule(ctx, stemFile, proto.genModFileContents(ctx, protoNames))
 
 	rule.Build("protoc_"+ctx.ModuleName(), "protoc "+ctx.ModuleName())
 
-	proto.BaseSourceProvider.OutputFiles = outputs.Paths()
+	// stemFile must be first here as the first path in BaseSourceProvider.OutputFiles is the library entry-point.
+	proto.BaseSourceProvider.OutputFiles = append(android.Paths{stemFile}, outputs.Paths()...)
 
 	// mod_stem.rs is the entry-point for our library modules, so this is what we return.
 	return stemFile
@@ -145,7 +147,7 @@
 			"}")
 	}
 
-	return strings.Join(lines, "\\n")
+	return strings.Join(lines, "\n")
 }
 
 func (proto *protobufDecorator) setupPlugin(ctx ModuleContext, protoFlags android.ProtoFlags, outDir android.ModuleOutPath) (android.Paths, android.ProtoFlags) {
diff --git a/rust/rust.go b/rust/rust.go
index 531d961..3d70121 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -245,7 +245,8 @@
 	CrtEnd   android.OptionalPath
 
 	// Paths to generated source files
-	SrcDeps android.Paths
+	SrcDeps          android.Paths
+	srcProviderFiles android.Paths
 }
 
 type RustLibraries []RustLibrary