Merge "Use toybox md5sum instead of md5 on macOS."
diff --git a/apex/apex.go b/apex/apex.go
index 9c9d6ae..1e99ff8 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -142,6 +142,7 @@
 	keyTag         = dependencyTag{name: "key"}
 	certificateTag = dependencyTag{name: "certificate"}
 	usesTag        = dependencyTag{name: "uses"}
+	androidAppTag  = dependencyTag{name: "androidApp"}
 )
 
 var (
@@ -333,6 +334,9 @@
 
 	// A txt file containing list of files that are whitelisted to be included in this APEX.
 	Whitelisted_files *string
+
+	// List of APKs to package inside APEX
+	Apps []string
 }
 
 type apexTargetBundleProperties struct {
@@ -367,6 +371,7 @@
 	goBinary
 	javaSharedLib
 	nativeTest
+	app
 )
 
 type apexPackaging int
@@ -431,6 +436,8 @@
 		return "JAVA_LIBRARIES"
 	case nativeTest:
 		return "NATIVE_TESTS"
+	case app:
+		return "APPS"
 	default:
 		panic(fmt.Errorf("unknown class %d", class))
 	}
@@ -633,6 +640,10 @@
 		{Mutator: "arch", Variation: "android_common"},
 	}, javaLibTag, a.properties.Java_libs...)
 
+	ctx.AddFarVariationDependencies([]blueprint.Variation{
+		{Mutator: "arch", Variation: "android_common"},
+	}, androidAppTag, a.properties.Apps...)
+
 	if String(a.properties.Key) == "" {
 		ctx.ModuleErrorf("key is missing")
 		return
@@ -813,6 +824,12 @@
 	return
 }
 
+func getCopyManifestForAndroidApp(app *java.AndroidApp, pkgName string) (fileToCopy android.Path, dirInApex string) {
+	dirInApex = filepath.Join("app", pkgName)
+	fileToCopy = app.OutputFile()
+	return
+}
+
 // Context "decorator", overriding the InstallBypassMake method to always reply `true`.
 type flattenedApexContext struct {
 	android.ModuleContext
@@ -977,6 +994,14 @@
 				if prebuilt, ok := child.(*Prebuilt); ok && prebuilt.isForceDisabled() {
 					a.prebuiltFileToDelete = prebuilt.InstallFilename()
 				}
+			case androidAppTag:
+				if ap, ok := child.(*java.AndroidApp); ok {
+					fileToCopy, dirInApex := getCopyManifestForAndroidApp(ap, ctx.DeviceConfig().OverridePackageNameFor(depName))
+					filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, app, ap, nil})
+					return true
+				} else {
+					ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
+				}
 			}
 		} else {
 			// indirect dependencies
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 8de4cef..e2d85ae 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -103,6 +103,7 @@
 	ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(android.FileGroupFactory))
 	ctx.RegisterModuleType("java_library", android.ModuleFactoryAdaptor(java.LibraryFactory))
 	ctx.RegisterModuleType("java_import", android.ModuleFactoryAdaptor(java.ImportFactory))
+	ctx.RegisterModuleType("android_app", android.ModuleFactoryAdaptor(java.AndroidAppFactory))
 
 	ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
 		ctx.BottomUp("prebuilts", android.PrebuiltMutator).Parallel()
@@ -210,31 +211,33 @@
 		"system/sepolicy/apex/myapex_keytest-file_contexts": nil,
 		"system/sepolicy/apex/otherapex-file_contexts":      nil,
 		"system/sepolicy/apex/commonapex-file_contexts":     nil,
-		"mylib.cpp":                            nil,
-		"mylib_common.cpp":                     nil,
-		"mytest.cpp":                           nil,
-		"mytest1.cpp":                          nil,
-		"mytest2.cpp":                          nil,
-		"mytest3.cpp":                          nil,
-		"myprebuilt":                           nil,
-		"my_include":                           nil,
-		"foo/bar/MyClass.java":                 nil,
-		"prebuilt.jar":                         nil,
-		"vendor/foo/devkeys/test.x509.pem":     nil,
-		"vendor/foo/devkeys/test.pk8":          nil,
-		"testkey.x509.pem":                     nil,
-		"testkey.pk8":                          nil,
-		"testkey.override.x509.pem":            nil,
-		"testkey.override.pk8":                 nil,
-		"vendor/foo/devkeys/testkey.avbpubkey": nil,
-		"vendor/foo/devkeys/testkey.pem":       nil,
-		"NOTICE":                               nil,
-		"custom_notice":                        nil,
-		"testkey2.avbpubkey":                   nil,
-		"testkey2.pem":                         nil,
-		"myapex-arm64.apex":                    nil,
-		"myapex-arm.apex":                      nil,
-		"frameworks/base/api/current.txt":      nil,
+		"mylib.cpp":                                  nil,
+		"mylib_common.cpp":                           nil,
+		"mytest.cpp":                                 nil,
+		"mytest1.cpp":                                nil,
+		"mytest2.cpp":                                nil,
+		"mytest3.cpp":                                nil,
+		"myprebuilt":                                 nil,
+		"my_include":                                 nil,
+		"foo/bar/MyClass.java":                       nil,
+		"prebuilt.jar":                               nil,
+		"vendor/foo/devkeys/test.x509.pem":           nil,
+		"vendor/foo/devkeys/test.pk8":                nil,
+		"testkey.x509.pem":                           nil,
+		"testkey.pk8":                                nil,
+		"testkey.override.x509.pem":                  nil,
+		"testkey.override.pk8":                       nil,
+		"vendor/foo/devkeys/testkey.avbpubkey":       nil,
+		"vendor/foo/devkeys/testkey.pem":             nil,
+		"NOTICE":                                     nil,
+		"custom_notice":                              nil,
+		"testkey2.avbpubkey":                         nil,
+		"testkey2.pem":                               nil,
+		"myapex-arm64.apex":                          nil,
+		"myapex-arm.apex":                            nil,
+		"frameworks/base/api/current.txt":            nil,
+		"build/make/core/proguard.flags":             nil,
+		"build/make/core/proguard_basic_keeps.flags": nil,
 	})
 
 	return ctx, config
@@ -1977,6 +1980,38 @@
 	`)
 }
 
+func TestApexWithApps(t *testing.T) {
+	ctx, _ := testApex(t, `
+		apex {
+			name: "myapex",
+			key: "myapex.key",
+			apps: [
+				"AppFoo",
+			],
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		android_app {
+			name: "AppFoo",
+			srcs: ["foo/bar/MyClass.java"],
+			sdk_version: "none",
+			system_modules: "none",
+		}
+	`)
+
+	module := ctx.ModuleForTests("myapex", "android_common_myapex")
+	apexRule := module.Rule("apexRule")
+	copyCmds := apexRule.Args["copy_commands"]
+
+	ensureContains(t, copyCmds, "image.apex/app/AppFoo/AppFoo.apk")
+
+}
+
 func TestMain(m *testing.M) {
 	run := func() int {
 		setUp()
diff --git a/cc/binary.go b/cc/binary.go
index fd00060..17e729c 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -50,6 +50,9 @@
 	// binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
 	// from PRODUCT_PACKAGES.
 	Overrides []string
+
+	// Inject boringssl hash into the shared library.  This is only intended for use by external/boringssl.
+	Inject_bssl_hash *bool `android:"arch_variant"`
 }
 
 func init() {
@@ -342,6 +345,8 @@
 			flagsToBuilderFlags(flags), afterPrefixSymbols)
 	}
 
+	outputFile = maybeInjectBoringSSLHash(ctx, outputFile, binary.Properties.Inject_bssl_hash, fileName)
+
 	if Bool(binary.baseLinker.Properties.Use_version_lib) {
 		if ctx.Host() {
 			versionedOutputFile := outputFile
diff --git a/cc/builder.go b/cc/builder.go
index 554706c..42d809a 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -551,7 +551,7 @@
 	flags builderFlags, outputFile android.ModuleOutPath, deps android.Paths) {
 
 	arCmd := "${config.ClangBin}/llvm-ar"
-	arFlags := "crsD"
+	arFlags := "crsPD"
 	if !ctx.Darwin() {
 		arFlags += " -format=gnu"
 	}
diff --git a/cc/library.go b/cc/library.go
index 52fd346..9178a52 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -771,18 +771,7 @@
 	}
 	library.unstrippedOutputFile = outputFile
 
-	// TODO(b/137267623): Remove this in favor of a cc_genrule when they support operating on shared libraries.
-	if Bool(library.Properties.Inject_bssl_hash) {
-		hashedOutputfile := outputFile
-		outputFile = android.PathForModuleOut(ctx, "unhashed", fileName)
-
-		rule := android.NewRuleBuilder()
-		rule.Command().
-			BuiltTool(ctx, "bssl_inject_hash").
-			FlagWithInput("-in-object ", outputFile).
-			FlagWithOutput("-o ", hashedOutputfile)
-		rule.Build(pctx, ctx, "injectCryptoHash", "inject crypto hash")
-	}
+	outputFile = maybeInjectBoringSSLHash(ctx, outputFile, library.Properties.Inject_bssl_hash, fileName)
 
 	if Bool(library.baseLinker.Properties.Use_version_lib) {
 		if ctx.Host() {
@@ -1296,3 +1285,38 @@
 		}
 	}
 }
+
+// maybeInjectBoringSSLHash adds a rule to run bssl_inject_hash on the output file if the module has the
+// inject_bssl_hash or if any static library dependencies have inject_bssl_hash set.  It returns the output path
+// that the linked output file should be written to.
+// TODO(b/137267623): Remove this in favor of a cc_genrule when they support operating on shared libraries.
+func maybeInjectBoringSSLHash(ctx android.ModuleContext, outputFile android.ModuleOutPath,
+	inject *bool, fileName string) android.ModuleOutPath {
+	// TODO(b/137267623): Remove this in favor of a cc_genrule when they support operating on shared libraries.
+	injectBoringSSLHash := Bool(inject)
+	ctx.VisitDirectDeps(func(dep android.Module) {
+		tag := ctx.OtherModuleDependencyTag(dep)
+		if tag == staticDepTag || tag == staticExportDepTag || tag == wholeStaticDepTag || tag == lateStaticDepTag {
+			if cc, ok := dep.(*Module); ok {
+				if library, ok := cc.linker.(*libraryDecorator); ok {
+					if Bool(library.Properties.Inject_bssl_hash) {
+						injectBoringSSLHash = true
+					}
+				}
+			}
+		}
+	})
+	if injectBoringSSLHash {
+		hashedOutputfile := outputFile
+		outputFile = android.PathForModuleOut(ctx, "unhashed", fileName)
+
+		rule := android.NewRuleBuilder()
+		rule.Command().
+			BuiltTool(ctx, "bssl_inject_hash").
+			FlagWithInput("-in-object ", outputFile).
+			FlagWithOutput("-o ", hashedOutputfile)
+		rule.Build(pctx, ctx, "injectCryptoHash", "inject crypto hash")
+	}
+
+	return outputFile
+}
diff --git a/java/app.go b/java/app.go
index 0af89fd..d00c4c0 100644
--- a/java/app.go
+++ b/java/app.go
@@ -139,6 +139,10 @@
 	return nil
 }
 
+func (a *AndroidApp) OutputFile() android.Path {
+	return a.outputFile
+}
+
 var _ AndroidLibraryDependency = (*AndroidApp)(nil)
 
 type Certificate struct {
diff --git a/java/builder.go b/java/builder.go
index f174cf0..9e068fa 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -229,10 +229,9 @@
 
 // Emits the rule to generate Xref input file (.kzip file) for the given set of source files and source jars
 // to compile with given set of builder flags, etc.
-func emitXrefRule(ctx android.ModuleContext, xrefFile android.WritablePath,
+func emitXrefRule(ctx android.ModuleContext, xrefFile android.WritablePath, idx int,
 	srcFiles, srcJars android.Paths,
-	flags javaBuilderFlags, deps android.Paths,
-	intermediatesDir string) {
+	flags javaBuilderFlags, deps android.Paths) {
 
 	deps = append(deps, srcJars...)
 
@@ -260,6 +259,11 @@
 		processor = "-processor " + flags.processor
 	}
 
+	intermediatesDir := "xref"
+	if idx >= 0 {
+		intermediatesDir += strconv.Itoa(idx)
+	}
+
 	ctx.Build(pctx,
 		android.BuildParams{
 			Rule:        kytheExtract,
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 63da6d2..9eaa1b6 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -294,8 +294,10 @@
 	android.InitDefaultableModule(module)
 }
 
-func apiCheckEnabled(apiToCheck ApiToCheck, apiVersionTag string) bool {
-	if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
+func apiCheckEnabled(ctx android.ModuleContext, apiToCheck ApiToCheck, apiVersionTag string) bool {
+	if ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") {
+		return false
+	} else if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
 		return true
 	} else if String(apiToCheck.Api_file) != "" {
 		panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
@@ -765,8 +767,8 @@
 }
 
 func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
-	if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
-		apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
+	if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
+		apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
 		String(d.properties.Api_filename) != "" {
 
 		d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
@@ -774,8 +776,8 @@
 		d.apiFilePath = d.apiFile
 	}
 
-	if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
-		apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
+	if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
+		apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
 		String(d.properties.Removed_api_filename) != "" {
 		d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
 		cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
@@ -993,7 +995,7 @@
 
 	rule.Build(pctx, ctx, "javadoc", desc)
 
-	if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
+	if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
 		!ctx.Config().IsPdkBuild() {
 
 		apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
@@ -1062,7 +1064,7 @@
 		rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
 	}
 
-	if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
+	if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
 		!ctx.Config().IsPdkBuild() {
 
 		apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
@@ -1192,16 +1194,16 @@
 }
 
 func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
-	if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
-		apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
+	if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
+		apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
 		String(d.properties.Api_filename) != "" {
 		d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
 		cmd.FlagWithOutput("--api ", d.apiFile)
 		d.apiFilePath = d.apiFile
 	}
 
-	if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
-		apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
+	if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
+		apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
 		String(d.properties.Removed_api_filename) != "" {
 		d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
 		cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
@@ -1458,7 +1460,7 @@
 
 	// Create rule for apicheck
 
-	if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
+	if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
 		!ctx.Config().IsPdkBuild() {
 
 		if len(d.Javadoc.properties.Out) > 0 {
@@ -1543,7 +1545,7 @@
 		rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
 	}
 
-	if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
+	if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
 		!ctx.Config().IsPdkBuild() {
 
 		if len(d.Javadoc.properties.Out) > 0 {
diff --git a/java/java.go b/java/java.go
index 87ee2f2..b05d7bb 100644
--- a/java/java.go
+++ b/java/java.go
@@ -25,6 +25,7 @@
 	"strings"
 
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/pathtools"
 	"github.com/google/blueprint/proptools"
 
 	"android/soong/android"
@@ -1151,27 +1152,20 @@
 			if len(uniqueSrcFiles) > 0 {
 				shardSrcs = shardPaths(uniqueSrcFiles, shardSize)
 				for idx, shardSrc := range shardSrcs {
-					classes := android.PathForModuleOut(ctx, "javac", jarName+strconv.Itoa(idx))
-					TransformJavaToClasses(ctx, classes, idx, shardSrc, nil, flags, extraJarDeps)
+					classes := j.compileJavaClasses(ctx, jarName, idx, shardSrc,
+						nil, flags, extraJarDeps)
 					jars = append(jars, classes)
 				}
 			}
 			if len(srcJars) > 0 {
-				classes := android.PathForModuleOut(ctx, "javac", jarName+strconv.Itoa(len(shardSrcs)))
-				TransformJavaToClasses(ctx, classes, len(shardSrcs), nil, srcJars, flags, extraJarDeps)
+				classes := j.compileJavaClasses(ctx, jarName, len(shardSrcs),
+					nil, srcJars, flags, extraJarDeps)
 				jars = append(jars, classes)
 			}
 		} else {
-			classes := android.PathForModuleOut(ctx, "javac", jarName)
-			TransformJavaToClasses(ctx, classes, -1, uniqueSrcFiles, srcJars, flags, extraJarDeps)
+			classes := j.compileJavaClasses(ctx, jarName, -1, uniqueSrcFiles, srcJars, flags, extraJarDeps)
 			jars = append(jars, classes)
 		}
-		if ctx.Config().EmitXrefRules() {
-			extractionFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".kzip")
-			emitXrefRule(ctx, extractionFile, uniqueSrcFiles, srcJars, flags, extraJarDeps, "xref")
-			j.kytheFiles = append(j.kytheFiles, extractionFile)
-
-		}
 		if ctx.Failed() {
 			return
 		}
@@ -1392,6 +1386,27 @@
 	j.outputFile = outputFile.WithoutRel()
 }
 
+func (j *Module) compileJavaClasses(ctx android.ModuleContext, jarName string, idx int,
+	srcFiles, srcJars android.Paths, flags javaBuilderFlags, extraJarDeps android.Paths) android.WritablePath {
+
+	kzipName := pathtools.ReplaceExtension(jarName, "kzip")
+	if idx >= 0 {
+		kzipName = strings.TrimSuffix(jarName, filepath.Ext(jarName)) + strconv.Itoa(idx) + ".kzip"
+		jarName += strconv.Itoa(idx)
+	}
+
+	classes := android.PathForModuleOut(ctx, "javac", jarName)
+	TransformJavaToClasses(ctx, classes, idx, srcFiles, srcJars, flags, extraJarDeps)
+
+	if ctx.Config().EmitXrefRules() {
+		extractionFile := android.PathForModuleOut(ctx, kzipName)
+		emitXrefRule(ctx, extractionFile, idx, srcFiles, srcJars, flags, extraJarDeps)
+		j.kytheFiles = append(j.kytheFiles, extractionFile)
+	}
+
+	return classes
+}
+
 // Check for invalid kotlinc flags. Only use this for flags explicitly passed by the user,
 // since some of these flags may be used internally.
 func CheckKotlincFlags(ctx android.ModuleContext, flags []string) {
diff --git a/rust/rust.go b/rust/rust.go
index 5a2514e..62ccfc7 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -173,6 +173,24 @@
 
 	android.InitDefaultableModule(mod)
 
+	// Explicitly disable unsupported targets.
+	android.AddLoadHook(mod, func(ctx android.LoadHookContext) {
+		disableTargets := struct {
+			Target struct {
+				Darwin struct {
+					Enabled *bool
+				}
+				Linux_bionic struct {
+					Enabled *bool
+				}
+			}
+		}{}
+		disableTargets.Target.Darwin.Enabled = proptools.BoolPtr(false)
+		disableTargets.Target.Linux_bionic.Enabled = proptools.BoolPtr(false)
+
+		ctx.AppendProperties(&disableTargets)
+	})
+
 	return mod
 }