Merge "DO NOT MERGE, Make default -Wimplicit-fallthrough as error."
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/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..0d4edfe 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())
 		}
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..476eb60 100644
--- a/java/app_builder.go
+++ b/java/app_builder.go
@@ -134,6 +134,50 @@
 	})
 }
 
+var buildBundleModule = pctx.AndroidStaticRule("buildBundleModule",
+	blueprint.RuleParams{
+		Command: `${config.Zip2ZipCmd} -i ${in} -o ${out}.res.zip AndroidManifest.xml:manifest/AndroidManifest.xml resources.pb "res/**/*" "assets/**/*" &&` +
+			`${config.Zip2ZipCmd} -i ${dexJar} -o ${out}.dex.zip "classes*.dex:dex/" && ` +
+			`${config.MergeZipsCmd} ${out} ${out}.res.zip ${out}.dex.zip ${jniJar} && ` +
+			`rm ${out}.res.zip ${out}.dex.zip`,
+		CommandDeps: []string{
+			"${config.Zip2ZipCmd}",
+			"${config.MergeZipsCmd}",
+		},
+	}, "dexJar", "jniJar")
+
+// Builds an app into a module suitable for input to bundletool
+func BuildBundleModule(ctx android.ModuleContext, outputFile android.WritablePath,
+	resJarFile, jniJarFile, dexJarFile android.Path) {
+
+	protoResJarFile := android.PathForModuleOut(ctx, "package-res.pb.apk")
+	aapt2Convert(ctx, protoResJarFile, resJarFile)
+
+	var deps android.Paths
+	var jniPath string
+	var dexPath string
+	if dexJarFile != nil {
+		deps = append(deps, dexJarFile)
+		dexPath = dexJarFile.String()
+	}
+	if jniJarFile != nil {
+		deps = append(deps, jniJarFile)
+		jniPath = jniJarFile.String()
+	}
+
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        buildBundleModule,
+		Implicits:   deps,
+		Input:       protoResJarFile,
+		Output:      outputFile,
+		Description: "bundle",
+		Args: map[string]string{
+			"dexJar": dexPath,
+			"jniJar": jniPath,
+		},
+	})
+}
+
 func TransformJniLibsToJar(ctx android.ModuleContext, outputFile android.WritablePath,
 	jniLibs []jniLib) {
 
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 23614ec..b724e15 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -484,6 +484,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) {
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/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
+			}
+		}
 	}
 }