Merge "Fix ext4 image's root directory permissions of APEX packages."
diff --git a/android/config.go b/android/config.go
index 695a298..cca1c7a 100644
--- a/android/config.go
+++ b/android/config.go
@@ -351,6 +351,10 @@
 
 var _ bootstrap.ConfigBlueprintToolLocation = (*config)(nil)
 
+func (c *config) HostToolPath(ctx PathContext, tool string) Path {
+	return PathForOutput(ctx, "host", c.PrebuiltOS(), "bin", tool)
+}
+
 // HostSystemTool looks for non-hermetic tools from the system we're running on.
 // Generally shouldn't be used, but useful to find the XCode SDK, etc.
 func (c *config) HostSystemTool(name string) string {
diff --git a/android/prebuilt_etc.go b/android/prebuilt_etc.go
index cc1f846..83c38db 100644
--- a/android/prebuilt_etc.go
+++ b/android/prebuilt_etc.go
@@ -44,6 +44,9 @@
 	Recovery_available *bool
 
 	InRecovery bool `blueprint:"mutated"`
+
+	// Whether this module is directly installable to one of the partitions. Default: true.
+	Installable *bool
 }
 
 type PrebuiltEtc struct {
@@ -96,6 +99,10 @@
 	return String(p.properties.Sub_dir)
 }
 
+func (p *PrebuiltEtc) Installable() bool {
+	return p.properties.Installable == nil || Bool(p.properties.Installable)
+}
+
 func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx ModuleContext) {
 	p.sourceFilePath = ctx.ExpandSource(String(p.properties.Src), "src")
 	filename := String(p.properties.Filename)
@@ -128,6 +135,7 @@
 			fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", p.outputFilePath.String())
 			fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", "$(OUT_DIR)/"+p.installDirPath.RelPathString())
 			fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", p.outputFilePath.Base())
+			fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE :=", !p.Installable())
 			if p.additionalDependencies != nil {
 				fmt.Fprint(w, "LOCAL_ADDITIONAL_DEPENDENCIES :=")
 				for _, path := range *p.additionalDependencies {
diff --git a/android/variable.go b/android/variable.go
index f2ba89b..2686049 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -95,6 +95,9 @@
 			Lto      struct {
 				Never *bool
 			}
+			Sanitize struct {
+				Address *bool
+			}
 		}
 
 		Pdk struct {
diff --git a/cc/cc_test.go b/cc/cc_test.go
index fba38a2..e4904f2 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -1738,13 +1738,16 @@
 	ctx := testCc(t, `
 		cc_library_shared {
 			name: "libFoo",
+			srcs: ["foo.c"],
 			stubs: {
 				symbol_file: "foo.map.txt",
 				versions: ["1", "2", "3"],
 			},
 		}
+
 		cc_library_shared {
 			name: "libBar",
+			srcs: ["bar.c"],
 			shared_libs: ["libFoo#1"],
 		}`)
 
@@ -1786,4 +1789,11 @@
 	if !strings.Contains(libFlags, libFoo1StubPath) {
 		t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
 	}
+
+	libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("cc")
+	cFlags := libBarCompileRule.Args["cFlags"]
+	libFoo1VersioningMacro := "-D__LIBFOO_API__=1"
+	if !strings.Contains(cFlags, libFoo1VersioningMacro) {
+		t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags)
+	}
 }
diff --git a/cc/config/clang.go b/cc/config/clang.go
index bbc78fa..74e8ae8 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -97,9 +97,8 @@
 	pctx.StaticVariable("ClangExtraCflags", strings.Join([]string{
 		"-D__compiler_offsetof=__builtin_offsetof",
 
-		// Make implicit fallthrough an error in the future.
+		// -Wimplicit fallthrough is not enabled by -Wall.
 		"-Wimplicit-fallthrough",
-		"-Wno-error=implicit-fallthrough",
 
 		// Help catch common 32/64-bit errors.
 		"-Werror=int-conversion",
diff --git a/cc/config/x86_linux_bionic_host.go b/cc/config/x86_linux_bionic_host.go
index 5fb88e6..fb1cdeb 100644
--- a/cc/config/x86_linux_bionic_host.go
+++ b/cc/config/x86_linux_bionic_host.go
@@ -124,7 +124,7 @@
 func (t *toolchainLinuxBionic) ToolchainClangCflags() string {
 	return "-m64 -march=x86-64" +
 		// TODO: We're not really android, but we don't have a triple yet b/31393676
-		" -U__ANDROID__ -fno-emulated-tls"
+		" -U__ANDROID__"
 }
 
 func (t *toolchainLinuxBionic) ToolchainClangLdflags() string {
diff --git a/cc/library.go b/cc/library.go
index aafe365..975f325 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -15,7 +15,9 @@
 package cc
 
 import (
+	"regexp"
 	"strings"
+	"sync"
 
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/pathtools"
@@ -443,6 +445,8 @@
 	return name + library.MutatedProperties.VariantName
 }
 
+var versioningMacroNamesListMutex sync.Mutex
+
 func (library *libraryDecorator) linkerInit(ctx BaseModuleContext) {
 	location := InstallInSystem
 	if library.baseLinker.sanitize.inSanitizerDir() {
@@ -453,6 +457,18 @@
 	// Let baseLinker know whether this variant is for stubs or not, so that
 	// it can omit things that are not required for linking stubs.
 	library.baseLinker.dynamicProperties.BuildStubs = library.buildStubs()
+
+	if library.buildStubs() {
+		macroNames := versioningMacroNamesList(ctx.Config())
+		myName := versioningMacroName(ctx.ModuleName())
+		versioningMacroNamesListMutex.Lock()
+		defer versioningMacroNamesListMutex.Unlock()
+		if (*macroNames)[myName] == "" {
+			(*macroNames)[myName] = ctx.ModuleName()
+		} else if (*macroNames)[myName] != ctx.ModuleName() {
+			ctx.ModuleErrorf("Macro name %q for versioning conflicts with macro name from module %q ", myName, (*macroNames)[myName])
+		}
+	}
 }
 
 func (library *libraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
@@ -715,6 +731,10 @@
 		library.reuseExportedFlags = append(library.reuseExportedFlags, flags...)
 	}
 
+	if library.buildStubs() {
+		library.reexportFlags([]string{"-D" + versioningMacroName(ctx.ModuleName()) + "=" + library.stubsVersion()})
+	}
+
 	return out
 }
 
@@ -823,6 +843,23 @@
 	return library.MutatedProperties.StubsVersion
 }
 
+func versioningMacroNamesList(config android.Config) *map[string]string {
+	return config.Once("versioningMacroNamesList", func() interface{} {
+		m := make(map[string]string)
+		return &m
+	}).(*map[string]string)
+}
+
+// alphanumeric and _ characters are preserved.
+// other characters are all converted to _
+var charsNotForMacro = regexp.MustCompile("[^a-zA-Z0-9_]+")
+
+func versioningMacroName(moduleName string) string {
+	macroName := charsNotForMacro.ReplaceAllString(moduleName, "_")
+	macroName = strings.ToUpper(moduleName)
+	return "__" + macroName + "_API__"
+}
+
 func NewLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
 	module := newModule(hod, android.MultilibBoth)
 
diff --git a/cmd/zip2zip/zip2zip.go b/cmd/zip2zip/zip2zip.go
index c4fb3d6..491267b 100644
--- a/cmd/zip2zip/zip2zip.go
+++ b/cmd/zip2zip/zip2zip.go
@@ -148,8 +148,13 @@
 				} else {
 					if pathtools.IsGlob(input) {
 						// If the input is a glob then the output is a directory.
-						_, name := filepath.Split(file.Name)
-						newName = filepath.Join(output, name)
+						rel, err := filepath.Rel(constantPartOfPattern(input), file.Name)
+						if err != nil {
+							return err
+						} else if strings.HasPrefix("../", rel) {
+							return fmt.Errorf("globbed path %q was not in %q", file.Name, constantPartOfPattern(input))
+						}
+						newName = filepath.Join(output, rel)
 					} else {
 						// Otherwise it is a file.
 						newName = output
@@ -277,3 +282,24 @@
 	}
 	return false, nil
 }
+
+func constantPartOfPattern(pattern string) string {
+	ret := ""
+	for pattern != "" {
+		var first string
+		first, pattern = splitFirst(pattern)
+		if pathtools.IsGlob(first) {
+			return ret
+		}
+		ret = filepath.Join(ret, first)
+	}
+	return ret
+}
+
+func splitFirst(path string) (string, string) {
+	i := strings.IndexRune(path, filepath.Separator)
+	if i < 0 {
+		return path, ""
+	}
+	return path[:i], path[i+1:]
+}
diff --git a/cmd/zip2zip/zip2zip_test.go b/cmd/zip2zip/zip2zip_test.go
index ae16494..2c4e005 100644
--- a/cmd/zip2zip/zip2zip_test.go
+++ b/cmd/zip2zip/zip2zip_test.go
@@ -352,6 +352,60 @@
 			"a/b",
 		},
 	},
+	{
+		name: "recursive glob",
+
+		inputFiles: []string{
+			"a/a/a",
+			"a/a/b",
+		},
+		args: []string{"a/**/*:b"},
+		outputFiles: []string{
+			"b/a/a",
+			"b/a/b",
+		},
+	},
+	{
+		name: "glob",
+
+		inputFiles: []string{
+			"a/a/a",
+			"a/a/b",
+			"a/b",
+			"a/c",
+		},
+		args: []string{"a/*:b"},
+		outputFiles: []string{
+			"b/b",
+			"b/c",
+		},
+	},
+	{
+		name: "top level glob",
+
+		inputFiles: []string{
+			"a",
+			"b",
+		},
+		args: []string{"*:b"},
+		outputFiles: []string{
+			"b/a",
+			"b/b",
+		},
+	},
+	{
+		name: "multilple glob",
+
+		inputFiles: []string{
+			"a/a/a",
+			"a/a/b",
+		},
+		args: []string{"a/*/*:b"},
+		outputFiles: []string{
+			"b/a/a",
+			"b/a/b",
+		},
+	},
 }
 
 func errorString(e error) string {
@@ -416,3 +470,45 @@
 		})
 	}
 }
+
+func TestConstantPartOfPattern(t *testing.T) {
+	testCases := []struct{ in, out string }{
+		{
+			in:  "",
+			out: "",
+		},
+		{
+			in:  "a",
+			out: "a",
+		},
+		{
+			in:  "*",
+			out: "",
+		},
+		{
+			in:  "a/a",
+			out: "a/a",
+		},
+		{
+			in:  "a/*",
+			out: "a",
+		},
+		{
+			in:  "a/*/a",
+			out: "a",
+		},
+		{
+			in:  "a/**/*",
+			out: "a",
+		},
+	}
+
+	for _, test := range testCases {
+		t.Run(test.in, func(t *testing.T) {
+			got := constantPartOfPattern(test.in)
+			if got != test.out {
+				t.Errorf("want %q, got %q", test.out, got)
+			}
+		})
+	}
+}
diff --git a/java/aapt2.go b/java/aapt2.go
index 5553bfd..86eb9c8 100644
--- a/java/aapt2.go
+++ b/java/aapt2.go
@@ -188,3 +188,18 @@
 		},
 	})
 }
+
+var aapt2ConvertRule = pctx.AndroidStaticRule("aapt2Convert",
+	blueprint.RuleParams{
+		Command:     `${config.Aapt2Cmd} convert --output-format proto $in -o $out`,
+		CommandDeps: []string{"${config.Aapt2Cmd}"},
+	})
+
+func aapt2Convert(ctx android.ModuleContext, out android.WritablePath, in android.Path) {
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        aapt2ConvertRule,
+		Input:       in,
+		Output:      out,
+		Description: "convert to proto",
+	})
+}
diff --git a/java/aar.go b/java/aar.go
index 3ab07cc..a49aef0 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -413,6 +413,10 @@
 	return a.sdkVersion()
 }
 
+func (a *AARImport) targetSdkVersion() string {
+	return a.sdkVersion()
+}
+
 var _ AndroidLibraryDependency = (*AARImport)(nil)
 
 func (a *AARImport) ExportPackage() android.Path {
diff --git a/java/android_manifest.go b/java/android_manifest.go
index 168a22d..36f24ff 100644
--- a/java/android_manifest.go
+++ b/java/android_manifest.go
@@ -58,7 +58,7 @@
 		Output: fixedManifest,
 		Args: map[string]string{
 			"minSdkVersion":    sdkVersionOrDefault(ctx, sdkContext.minSdkVersion()),
-			"targetSdkVersion": sdkVersionOrDefault(ctx, sdkContext.sdkVersion()),
+			"targetSdkVersion": sdkVersionOrDefault(ctx, sdkContext.targetSdkVersion()),
 			"args":             strings.Join(args, " "),
 		},
 	})
diff --git a/java/androidmk.go b/java/androidmk.go
index e395c9b..0700b58 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -209,6 +209,9 @@
 				if app.headerJarFile != nil {
 					fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", app.headerJarFile.String())
 				}
+				if app.bundleFile != nil {
+					fmt.Fprintln(w, "LOCAL_SOONG_BUNDLE :=", app.bundleFile.String())
+				}
 				if app.jacocoReportClassesFile != nil {
 					fmt.Fprintln(w, "LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR :=", app.jacocoReportClassesFile.String())
 				}
@@ -290,6 +293,9 @@
 	data := a.Library.AndroidMk()
 
 	data.Extra = append(data.Extra, func(w io.Writer, outputFile android.Path) {
+		if a.aarFile != nil {
+			fmt.Fprintln(w, "LOCAL_SOONG_AAR :=", a.aarFile.String())
+		}
 		if a.proguardDictionary != nil {
 			fmt.Fprintln(w, "LOCAL_SOONG_PROGUARD_DICT :=", a.proguardDictionary.String())
 		}
@@ -448,6 +454,14 @@
 					fmt.Fprintln(w, dstubs.Name()+"-check-last-released-api:",
 						dstubs.checkLastReleasedApiTimestamp.String())
 				}
+				if dstubs.checkNullabilityWarningsTimestamp != nil {
+					fmt.Fprintln(w, ".PHONY:", dstubs.Name()+"-check-nullability-warnings")
+					fmt.Fprintln(w, dstubs.Name()+"-check-nullability-warnings:",
+						dstubs.checkNullabilityWarningsTimestamp.String())
+
+					fmt.Fprintln(w, ".PHONY:", "droidcore")
+					fmt.Fprintln(w, "droidcore: ", dstubs.Name()+"-check-nullability-warnings")
+				}
 				apiFilePrefix := "INTERNAL_PLATFORM_"
 				if String(dstubs.properties.Api_tag_name) != "" {
 					apiFilePrefix += String(dstubs.properties.Api_tag_name) + "_"
diff --git a/java/app.go b/java/app.go
index 7ca20ce..392ad3f 100644
--- a/java/app.go
+++ b/java/app.go
@@ -83,6 +83,8 @@
 	extraLinkFlags []string
 
 	installJniLibs []jniLib
+
+	bundleFile android.Path
 }
 
 func (a *AndroidApp) ExportedProguardFlagFiles() android.Paths {
@@ -277,6 +279,10 @@
 	CreateAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates)
 	a.outputFile = packageFile
 
+	bundleFile := android.PathForModuleOut(ctx, "base.zip")
+	BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile)
+	a.bundleFile = bundleFile
+
 	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)
diff --git a/java/app_builder.go b/java/app_builder.go
index 424aec8..b0983bd 100644
--- a/java/app_builder.go
+++ b/java/app_builder.go
@@ -63,7 +63,7 @@
 	})
 
 func CreateAppPackage(ctx android.ModuleContext, outputFile android.WritablePath,
-	resJarFile, jniJarFile, dexJarFile android.Path, certificates []Certificate) {
+	packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate) {
 
 	unsignedApk := android.PathForModuleOut(ctx, "unsigned.apk")
 
@@ -71,7 +71,7 @@
 	if dexJarFile != nil {
 		inputs = append(inputs, dexJarFile)
 	}
-	inputs = append(inputs, resJarFile)
+	inputs = append(inputs, packageFile)
 	if jniJarFile != nil {
 		inputs = append(inputs, jniJarFile)
 	}
@@ -134,6 +134,70 @@
 	})
 }
 
+var buildBundleModule = pctx.AndroidStaticRule("buildBundleModule",
+	blueprint.RuleParams{
+		Command:     `${config.MergeZipsCmd} ${out} ${in}`,
+		CommandDeps: []string{"${config.MergeZipsCmd}"},
+	})
+
+var bundleMungePackage = pctx.AndroidStaticRule("bundleMungePackage",
+	blueprint.RuleParams{
+		Command:     `${config.Zip2ZipCmd} -i ${in} -o ${out} AndroidManifest.xml:manifest/AndroidManifest.xml resources.pb "res/**/*" "assets/**/*"`,
+		CommandDeps: []string{"${config.Zip2ZipCmd}"},
+	})
+
+var bundleMungeDexJar = pctx.AndroidStaticRule("bundleMungeDexJar",
+	blueprint.RuleParams{
+		Command: `${config.Zip2ZipCmd} -i ${in} -o ${out} "classes*.dex:dex/" && ` +
+			`${config.Zip2ZipCmd} -i ${in} -o ${resJar} -x "classes*.dex" "**/*:root/"`,
+		CommandDeps: []string{"${config.Zip2ZipCmd}"},
+	}, "resJar")
+
+// Builds an app into a module suitable for input to bundletool
+func BuildBundleModule(ctx android.ModuleContext, outputFile android.WritablePath,
+	packageFile, jniJarFile, dexJarFile android.Path) {
+
+	protoResJarFile := android.PathForModuleOut(ctx, "package-res.pb.apk")
+	aapt2Convert(ctx, protoResJarFile, packageFile)
+
+	var zips android.Paths
+
+	mungedPackage := android.PathForModuleOut(ctx, "bundle", "apk.zip")
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        bundleMungePackage,
+		Input:       protoResJarFile,
+		Output:      mungedPackage,
+		Description: "bundle apk",
+	})
+	zips = append(zips, mungedPackage)
+
+	if dexJarFile != nil {
+		mungedDexJar := android.PathForModuleOut(ctx, "bundle", "dex.zip")
+		mungedResJar := android.PathForModuleOut(ctx, "bundle", "res.zip")
+		ctx.Build(pctx, android.BuildParams{
+			Rule:           bundleMungeDexJar,
+			Input:          dexJarFile,
+			Output:         mungedDexJar,
+			ImplicitOutput: mungedResJar,
+			Description:    "bundle dex",
+			Args: map[string]string{
+				"resJar": mungedResJar.String(),
+			},
+		})
+		zips = append(zips, mungedDexJar, mungedResJar)
+	}
+	if jniJarFile != nil {
+		zips = append(zips, jniJarFile)
+	}
+
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        buildBundleModule,
+		Inputs:      zips,
+		Output:      outputFile,
+		Description: "bundle",
+	})
+}
+
 func TransformJniLibsToJar(ctx android.ModuleContext, outputFile android.WritablePath,
 	jniLibs []jniLib) {
 
diff --git a/java/builder.go b/java/builder.go
index cefb916..c52e942 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -161,6 +161,7 @@
 	kotlincClasspath classpath
 
 	protoFlags       []string
+	protoDeps        android.Paths
 	protoOutTypeFlag string // The flag itself: --java_out
 	protoOutParams   string // Parameters to that flag: --java_out=$protoOutParams:$outDir
 	protoRoot        bool
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 23614ec..9dadb30 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -106,6 +106,12 @@
 		},
 		"srcJarDir", "srcJars", "javaVersion", "bootclasspathArgs", "classpathArgs", "sourcepathArgs", "opts", "msg")
 
+	nullabilityWarningsCheck = pctx.AndroidStaticRule("nullabilityWarningsCheck",
+		blueprint.RuleParams{
+			Command: `( diff $expected $actual && touch $out ) || ( echo -e "$msg" ; exit 38 )`,
+		},
+		"expected", "actual", "msg")
+
 	dokka = pctx.AndroidStaticRule("dokka",
 		blueprint.RuleParams{
 			Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && ` +
@@ -354,6 +360,9 @@
 	// a list of top-level directories containing Java stub files to merge show/hide annotations from.
 	Merge_inclusion_annotations_dirs []string
 
+	// a file containing expected warnings produced by validation of nullability annotations.
+	Check_nullability_warnings *string
+
 	// if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
 	Create_doc_stubs *bool
 
@@ -484,6 +493,10 @@
 	return j.sdkVersion()
 }
 
+func (j *Javadoc) targetSdkVersion() string {
+	return j.sdkVersion()
+}
+
 func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
 	if ctx.Device() {
 		if !Bool(j.properties.No_standard_libs) {
@@ -1207,23 +1220,26 @@
 type Droidstubs struct {
 	Javadoc
 
-	properties             DroidstubsProperties
-	apiFile                android.WritablePath
-	apiXmlFile             android.WritablePath
-	lastReleasedApiXmlFile android.WritablePath
-	dexApiFile             android.WritablePath
-	privateApiFile         android.WritablePath
-	privateDexApiFile      android.WritablePath
-	removedApiFile         android.WritablePath
-	removedDexApiFile      android.WritablePath
-	apiMappingFile         android.WritablePath
-	exactApiFile           android.WritablePath
-	proguardFile           android.WritablePath
+	properties              DroidstubsProperties
+	apiFile                 android.WritablePath
+	apiXmlFile              android.WritablePath
+	lastReleasedApiXmlFile  android.WritablePath
+	dexApiFile              android.WritablePath
+	privateApiFile          android.WritablePath
+	privateDexApiFile       android.WritablePath
+	removedApiFile          android.WritablePath
+	removedDexApiFile       android.WritablePath
+	apiMappingFile          android.WritablePath
+	exactApiFile            android.WritablePath
+	proguardFile            android.WritablePath
+	nullabilityWarningsFile android.WritablePath
 
 	checkCurrentApiTimestamp      android.WritablePath
 	updateCurrentApiTimestamp     android.WritablePath
 	checkLastReleasedApiTimestamp android.WritablePath
 
+	checkNullabilityWarningsTimestamp android.WritablePath
+
 	annotationsZip android.WritablePath
 	apiVersionsXml android.WritablePath
 
@@ -1286,6 +1302,10 @@
 		}
 	}
 
+	if String(d.properties.Check_nullability_warnings) != "" {
+		android.ExtractSourceDeps(ctx, d.properties.Check_nullability_warnings)
+	}
+
 	if len(d.properties.Api_levels_annotations_dirs) != 0 {
 		for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
 			ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
@@ -1403,9 +1423,9 @@
 			flags += " --migrate-nullness " + previousApi.String()
 		}
 		if validatingNullability {
-			nullabilityWarningsTxt := android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
-			*implicitOutputs = append(*implicitOutputs, nullabilityWarningsTxt)
-			flags += " --nullability-warnings-txt " + nullabilityWarningsTxt.String()
+			d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
+			*implicitOutputs = append(*implicitOutputs, d.nullabilityWarningsFile)
+			flags += " --nullability-warnings-txt " + d.nullabilityWarningsFile.String()
 		}
 
 		d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
@@ -1681,6 +1701,36 @@
 			d.checkLastReleasedApiTimestamp)
 	}
 
+	if String(d.properties.Check_nullability_warnings) != "" {
+		if d.nullabilityWarningsFile == nil {
+			ctx.PropertyErrorf("check_nullability_warnings",
+				"Cannot specify check_nullability_warnings unless validating nullability")
+		}
+		checkNullabilityWarnings := ctx.ExpandSource(String(d.properties.Check_nullability_warnings),
+			"check_nullability_warnings")
+		d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
+		msg := fmt.Sprintf(`\n******************************\n`+
+			`The warnings encountered during nullability annotation validation did\n`+
+			`not match the checked in file of expected warnings. The diffs are shown\n`+
+			`above. You have two options:\n`+
+			`   1. Resolve the differences by editing the nullability annotations.\n`+
+			`   2. Update the file of expected warnings by running:\n`+
+			`         cp %s %s\n`+
+			`       and submitting the updated file as part of your change.`,
+			d.nullabilityWarningsFile, checkNullabilityWarnings)
+		ctx.Build(pctx, android.BuildParams{
+			Rule:        nullabilityWarningsCheck,
+			Description: "Nullability Warnings Check",
+			Output:      d.checkNullabilityWarningsTimestamp,
+			Implicits:   android.Paths{checkNullabilityWarnings, d.nullabilityWarningsFile},
+			Args: map[string]string{
+				"expected": checkNullabilityWarnings.String(),
+				"actual":   d.nullabilityWarningsFile.String(),
+				"msg":      msg,
+			},
+		})
+	}
+
 	if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
 
 		// Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
diff --git a/java/java.go b/java/java.go
index 0f95479..50c284a 100644
--- a/java/java.go
+++ b/java/java.go
@@ -183,6 +183,10 @@
 	// Defaults to sdk_version if not set.
 	Min_sdk_version *string
 
+	// if not blank, set the targetSdkVersion in the AndroidManifest.xml.
+	// Defaults to sdk_version if not set.
+	Target_sdk_version *string
+
 	// if true, compile against the platform APIs instead of an SDK.
 	Platform_apis *bool
 
@@ -425,11 +429,20 @@
 	return j.sdkVersion()
 }
 
+func (j *Module) targetSdkVersion() string {
+	if j.deviceProperties.Target_sdk_version != nil {
+		return *j.deviceProperties.Target_sdk_version
+	}
+	return j.sdkVersion()
+}
+
 type sdkContext interface {
 	// sdkVersion eturns the sdk_version property of the current module, or an empty string if it is not set.
 	sdkVersion() string
 	// minSdkVersion returns the min_sdk_version property of the current module, or sdkVersion() if it is not set.
 	minSdkVersion() string
+	// targetSdkVersion returns the target_sdk_version property of the current module, or sdkVersion() if it is not set.
+	targetSdkVersion() string
 }
 
 func sdkVersionOrDefault(ctx android.BaseContext, v string) string {
diff --git a/java/proto.go b/java/proto.go
index 8028039..0bb37c5 100644
--- a/java/proto.go
+++ b/java/proto.go
@@ -59,6 +59,7 @@
 		Description: "protoc " + protoFile.Rel(),
 		Output:      srcJarFile,
 		Input:       protoFile,
+		Implicits:   flags.protoDeps,
 		Args: map[string]string{
 			"protoBase":      protoBase,
 			"protoOut":       flags.protoOutTypeFlag,
@@ -93,14 +94,16 @@
 func protoFlags(ctx android.ModuleContext, j *CompilerProperties, p *android.ProtoProperties,
 	flags javaBuilderFlags) javaBuilderFlags {
 
+	var plugin string
+
 	switch String(p.Proto.Type) {
 	case "micro":
 		flags.protoOutTypeFlag = "--javamicro_out"
 	case "nano":
 		flags.protoOutTypeFlag = "--javanano_out"
 	case "lite":
-		flags.protoOutTypeFlag = "--java_out"
-		flags.protoOutParams = "lite"
+		plugin = "protoc-gen-javalite"
+		flags.protoOutTypeFlag = "--javalite_out"
 	case "full", "":
 		flags.protoOutTypeFlag = "--java_out"
 	default:
@@ -108,15 +111,15 @@
 			String(p.Proto.Type))
 	}
 
-	if len(j.Proto.Output_params) > 0 {
-		if flags.protoOutParams != "" {
-			flags.protoOutParams += ","
-		}
-		flags.protoOutParams += strings.Join(j.Proto.Output_params, ",")
-	}
-
+	flags.protoOutParams = strings.Join(j.Proto.Output_params, ",")
 	flags.protoFlags = android.ProtoFlags(ctx, p)
 	flags.protoRoot = android.ProtoCanonicalPathFromRoot(ctx, p)
 
+	if plugin != "" {
+		path := ctx.Config().HostToolPath(ctx, plugin)
+		flags.protoDeps = append(flags.protoDeps, path)
+		flags.protoFlags = append(flags.protoFlags, "--plugin="+path.String())
+	}
+
 	return flags
 }
diff --git a/scripts/build-ndk-prebuilts.sh b/scripts/build-ndk-prebuilts.sh
index 0143d1e..81f8564 100755
--- a/scripts/build-ndk-prebuilts.sh
+++ b/scripts/build-ndk-prebuilts.sh
@@ -44,18 +44,6 @@
     "Platform_version_active_codenames": ${PLATFORM_VERSION_ALL_CODENAMES},
 
     "DeviceName": "generic_arm64",
-    "DeviceArch": "arm64",
-    "DeviceArchVariant": "armv8-a",
-    "DeviceCpuVariant": "denver64",
-    "DeviceAbi": [
-        "arm64-v8a"
-    ],
-    "DeviceSecondaryArch": "arm",
-    "DeviceSecondaryArchVariant": "armv7-a-neon",
-    "DeviceSecondaryCpuVariant": "denver",
-    "DeviceSecondaryAbi": [
-        "armeabi-v7a"
-    ],
     "HostArch": "x86_64",
     "Malloc_not_svelte": false,
     "Safestack": false,
diff --git a/ui/build/path.go b/ui/build/path.go
index 52658ef..8260ff9 100644
--- a/ui/build/path.go
+++ b/ui/build/path.go
@@ -19,6 +19,7 @@
 	"io/ioutil"
 	"os"
 	"path/filepath"
+	"runtime"
 	"strings"
 
 	"github.com/google/blueprint/microfactory"
@@ -144,6 +145,13 @@
 	}
 
 	myPath, _ = filepath.Abs(myPath)
+
+	// Use the toybox prebuilts on linux
+	if runtime.GOOS == "linux" {
+		toyboxPath, _ := filepath.Abs("prebuilts/build-tools/toybox/linux-x86")
+		myPath = toyboxPath + string(os.PathListSeparator) + myPath
+	}
+
 	config.Environment().Set("PATH", myPath)
 	config.pathReplaced = true
 }
diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
index e846b03..b4d76c4 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -25,6 +25,10 @@
 
 	// Whether to exit with an error instead of invoking the underlying tool.
 	Error bool
+
+	// Whether we use a toybox prebuilt for this tool. Since we don't have
+	// toybox for Darwin, we'll use the host version instead.
+	Toybox bool
 }
 
 var Allowed = PathConfig{
@@ -55,6 +59,13 @@
 	Error:   true,
 }
 
+var Toybox = PathConfig{
+	Symlink: false,
+	Log:     true,
+	Error:   true,
+	Toybox:  true,
+}
+
 func GetConfig(name string) PathConfig {
 	if config, ok := Configuration[name]; ok {
 		return config
@@ -138,8 +149,6 @@
 	"todos":     Allowed,
 	"touch":     Allowed,
 	"tr":        Allowed,
-	"true":      Allowed,
-	"uname":     Allowed,
 	"uniq":      Allowed,
 	"unix2dos":  Allowed,
 	"unzip":     Allowed,
@@ -166,10 +175,9 @@
 	"ld.gold":    Forbidden,
 	"pkg-config": Forbidden,
 
-	// We've got prebuilts of these
-	//"dtc":  Forbidden,
-	//"lz4":  Forbidden,
-	//"lz4c": Forbidden,
+	// On linux we'll use the toybox version of these instead
+	"true":  Toybox,
+	"uname": Toybox,
 }
 
 func init() {
@@ -177,5 +185,13 @@
 		Configuration["md5"] = Allowed
 		Configuration["sw_vers"] = Allowed
 		Configuration["xcrun"] = Allowed
+
+		// We don't have toybox prebuilts for darwin, so allow the
+		// host versions.
+		for name, config := range Configuration {
+			if config.Toybox {
+				Configuration[name] = Allowed
+			}
+		}
 	}
 }