Merge "NDK sysroot: include each license file only once"
diff --git a/cc/builder.go b/cc/builder.go
index 5a77d3e..7d207b0 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -236,29 +236,30 @@
 }
 
 type builderFlags struct {
-	globalFlags    string
-	arFlags        string
-	asFlags        string
-	cFlags         string
-	toolingCFlags  string // A separate set of Cflags for clang LibTooling tools
-	conlyFlags     string
-	cppFlags       string
-	ldFlags        string
-	libFlags       string
-	yaccFlags      string
-	protoFlags     string
-	protoOutParams string
-	tidyFlags      string
-	sAbiFlags      string
-	yasmFlags      string
-	aidlFlags      string
-	rsFlags        string
-	toolchain      config.Toolchain
-	clang          bool
-	tidy           bool
-	coverage       bool
-	sAbiDump       bool
-	protoRoot      bool
+	globalFlags     string
+	arFlags         string
+	asFlags         string
+	cFlags          string
+	toolingCFlags   string // A separate set of cFlags for clang LibTooling tools
+	toolingCppFlags string // A separate set of cppFlags for clang LibTooling tools
+	conlyFlags      string
+	cppFlags        string
+	ldFlags         string
+	libFlags        string
+	yaccFlags       string
+	protoFlags      string
+	protoOutParams  string
+	tidyFlags       string
+	sAbiFlags       string
+	yasmFlags       string
+	aidlFlags       string
+	rsFlags         string
+	toolchain       config.Toolchain
+	clang           bool
+	tidy            bool
+	coverage        bool
+	sAbiDump        bool
+	protoRoot       bool
 
 	systemIncludeFlags string
 
@@ -330,7 +331,7 @@
 	toolingCppflags := strings.Join([]string{
 		commonFlags,
 		flags.toolingCFlags,
-		flags.cppFlags,
+		flags.toolingCppFlags,
 	}, " ")
 
 	cppflags := strings.Join([]string{
diff --git a/cc/config/clang.go b/cc/config/clang.go
index 36afc68..186d790 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -93,8 +93,10 @@
 })
 
 var ClangLibToolingUnknownCflags = []string{
+	// Remove -flto and other flto dependent flags.
 	"-flto*",
 	"-fsanitize*",
+	"-fwhole-program-vtables",
 }
 
 func init() {
diff --git a/cc/sabi.go b/cc/sabi.go
index 42b2f35..72a3c5c 100644
--- a/cc/sabi.go
+++ b/cc/sabi.go
@@ -71,6 +71,7 @@
 	// Assuming that the cflags which clang LibTooling tools cannot
 	// understand have not been converted to ninja variables yet.
 	flags.ToolingCFlags = filterOutWithPrefix(flags.CFlags, config.ClangLibToolingUnknownCflags)
+	flags.ToolingCppFlags = filterOutWithPrefix(flags.CppFlags, config.ClangLibToolingUnknownCflags)
 
 	// RSClang does not support recent mcpu option likes exynos-m2.
 	// So we need overriding mcpu option when we want to use it.
diff --git a/cc/util.go b/cc/util.go
index 8de4210..93cf536 100644
--- a/cc/util.go
+++ b/cc/util.go
@@ -59,29 +59,30 @@
 
 func flagsToBuilderFlags(in Flags) builderFlags {
 	return builderFlags{
-		globalFlags:    strings.Join(in.GlobalFlags, " "),
-		arFlags:        strings.Join(in.ArFlags, " "),
-		asFlags:        strings.Join(in.AsFlags, " "),
-		cFlags:         strings.Join(in.CFlags, " "),
-		toolingCFlags:  strings.Join(in.ToolingCFlags, " "),
-		conlyFlags:     strings.Join(in.ConlyFlags, " "),
-		cppFlags:       strings.Join(in.CppFlags, " "),
-		yaccFlags:      strings.Join(in.YaccFlags, " "),
-		protoFlags:     strings.Join(in.protoFlags, " "),
-		protoOutParams: strings.Join(in.protoOutParams, ","),
-		aidlFlags:      strings.Join(in.aidlFlags, " "),
-		rsFlags:        strings.Join(in.rsFlags, " "),
-		ldFlags:        strings.Join(in.LdFlags, " "),
-		libFlags:       strings.Join(in.libFlags, " "),
-		tidyFlags:      strings.Join(in.TidyFlags, " "),
-		sAbiFlags:      strings.Join(in.SAbiFlags, " "),
-		yasmFlags:      strings.Join(in.YasmFlags, " "),
-		toolchain:      in.Toolchain,
-		clang:          in.Clang,
-		coverage:       in.Coverage,
-		tidy:           in.Tidy,
-		sAbiDump:       in.SAbiDump,
-		protoRoot:      in.ProtoRoot,
+		globalFlags:     strings.Join(in.GlobalFlags, " "),
+		arFlags:         strings.Join(in.ArFlags, " "),
+		asFlags:         strings.Join(in.AsFlags, " "),
+		cFlags:          strings.Join(in.CFlags, " "),
+		toolingCFlags:   strings.Join(in.ToolingCFlags, " "),
+		toolingCppFlags: strings.Join(in.ToolingCppFlags, " "),
+		conlyFlags:      strings.Join(in.ConlyFlags, " "),
+		cppFlags:        strings.Join(in.CppFlags, " "),
+		yaccFlags:       strings.Join(in.YaccFlags, " "),
+		protoFlags:      strings.Join(in.protoFlags, " "),
+		protoOutParams:  strings.Join(in.protoOutParams, ","),
+		aidlFlags:       strings.Join(in.aidlFlags, " "),
+		rsFlags:         strings.Join(in.rsFlags, " "),
+		ldFlags:         strings.Join(in.LdFlags, " "),
+		libFlags:        strings.Join(in.libFlags, " "),
+		tidyFlags:       strings.Join(in.TidyFlags, " "),
+		sAbiFlags:       strings.Join(in.SAbiFlags, " "),
+		yasmFlags:       strings.Join(in.YasmFlags, " "),
+		toolchain:       in.Toolchain,
+		clang:           in.Clang,
+		coverage:        in.Coverage,
+		tidy:            in.Tidy,
+		sAbiDump:        in.SAbiDump,
+		protoRoot:       in.ProtoRoot,
 
 		systemIncludeFlags: strings.Join(in.SystemIncludeFlags, " "),
 
diff --git a/cmd/pom2bp/pom2bp.go b/cmd/pom2bp/pom2bp.go
index 9ce6b50..a39642f 100644
--- a/cmd/pom2bp/pom2bp.go
+++ b/cmd/pom2bp/pom2bp.go
@@ -104,6 +104,24 @@
 
 var excludes = make(Exclude)
 
+type HostModuleNames map[string]bool
+
+func (n HostModuleNames) IsHostModule(groupId string, artifactId string) bool {
+	_, found := n[groupId + ":" + artifactId]
+	return found
+}
+
+func (n HostModuleNames) String() string {
+	return ""
+}
+
+func (n HostModuleNames) Set(v string) error {
+	n[v] = true
+	return nil
+}
+
+var hostModuleNames = HostModuleNames{}
+
 var sdkVersion string
 var useVersion string
 
@@ -160,6 +178,14 @@
 	return p.Packaging == "jar"
 }
 
+func (p Pom) IsHostModule() bool {
+	return hostModuleNames.IsHostModule(p.GroupId, p.ArtifactId)
+}
+
+func (p Pom) IsDeviceModule() bool {
+	return !p.IsHostModule()
+}
+
 func (p Pom) BpName() string {
 	if p.BpTarget == "" {
 		p.BpTarget = rewriteNames.MavenToBp(p.GroupId, p.ArtifactId)
@@ -278,11 +304,11 @@
     ],{{end}}
 }
 
-{{if .IsAar}}android_library{{else}}java_library_static{{end}} {
-    name: "{{.BpName}}",
+{{if .IsAar}}android_library{{else}}{{if .IsDeviceModule}}java_library_static{{else}}java_library_host{{end}}{{end}} {
+    name: "{{.BpName}}",{{if .IsDeviceModule}}
     sdk_version: "{{.SdkVersion}}",{{if .IsAar}}
     min_sdk_version: "{{.MinSdkVersion}}",
-    manifest: "manifests/{{.BpName}}/AndroidManifest.xml",{{end}}
+    manifest: "manifests/{{.BpName}}/AndroidManifest.xml",{{end}}{{end}}
     static_libs: [
         "{{.BpName}}-nodeps",{{range .BpJarDeps}}
         "{{.}}",{{end}}{{range .BpAarDeps}}
@@ -422,6 +448,7 @@
 	flag.Var(&excludes, "exclude", "Exclude module")
 	flag.Var(&extraDeps, "extra-deps", "Extra dependencies needed when depending on a module")
 	flag.Var(&rewriteNames, "rewrite", "Regex(es) to rewrite artifact names")
+	flag.Var(&hostModuleNames, "host", "Specifies that the corresponding module (specified in the form 'module.group:module.artifact') is a host module")
 	flag.StringVar(&sdkVersion, "sdk-version", "", "What to write to LOCAL_SDK_VERSION")
 	flag.StringVar(&useVersion, "use-version", "", "Only read artifacts of a specific version")
 	flag.Bool("static-deps", false, "Ignored")
diff --git a/java/droiddoc.go b/java/droiddoc.go
index ac4f86f..52db705 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -88,6 +88,24 @@
 		},
 		"outDir", "srcJarDir", "stubsDir", "docStubsDir", "srcJars", "javaVersion", "bootclasspathArgs",
 		"classpathArgs", "sourcepath", "opts", "docZip")
+
+	metalavaApiCheck = pctx.AndroidStaticRule("metalavaApiCheck",
+		blueprint.RuleParams{
+			Command: `( rm -rf "$srcJarDir" && mkdir -p "$srcJarDir" && ` +
+				`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
+				`${config.JavaCmd} -jar ${config.MetalavaJar} -encoding UTF-8 -source $javaVersion @$out.rsp @$srcJarDir/list ` +
+				`$bootclasspathArgs $classpathArgs -sourcepath $sourcepath --no-banner --color --quiet ` +
+				`$opts && touch $out ) || ` +
+				`( echo -e "$msg" ; exit 38 )`,
+			CommandDeps: []string{
+				"${config.ZipSyncCmd}",
+				"${config.JavaCmd}",
+				"${config.MetalavaJar}",
+			},
+			Rspfile:        "$out.rsp",
+			RspfileContent: "$in",
+		},
+		"srcJarDir", "srcJars", "javaVersion", "bootclasspathArgs", "classpathArgs", "sourcepath", "opts", "msg")
 )
 
 func init() {
@@ -288,10 +306,9 @@
 	doclavaDocsFlags  string
 	postDoclavaCmds   string
 
-	metalavaStubsFlags              string
-	metalavaAnnotationsFlags        string
-	metalavaJavadocFlags            string
-	metalavaCompatibilityCheckFlags string
+	metalavaStubsFlags       string
+	metalavaAnnotationsFlags string
+	metalavaJavadocFlags     string
 
 	metalavaDokkaFlags string
 }
@@ -1014,38 +1031,6 @@
 		docStubsDir + " " + classpathArgs + " -format dac -dacRoot /reference/kotlin -output " + outDir
 }
 
-func (d *Droiddoc) collectMetalavaCompatibilityCheckFlags(ctx android.ModuleContext,
-	implicits *android.Paths) string {
-	var flags string
-	if d.checkCurrentApi() && !ctx.Config().IsPdkBuild() {
-		apiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Api_file),
-			"check_api.current.api_file")
-		removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Removed_api_file),
-			"check_api.current_removed_api_file")
-
-		*implicits = append(*implicits, apiFile)
-		*implicits = append(*implicits, removedApiFile)
-
-		flags = " --check-compatibility:api:current " + apiFile.String() +
-			" --check-compatibility:removed:current " + removedApiFile.String() + " "
-	}
-
-	if d.checkLastReleasedApi() && !ctx.Config().IsPdkBuild() {
-		apiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
-			"check_api.last_released.api_file")
-		removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Removed_api_file),
-			"check_api.last_released.removed_api_file")
-
-		*implicits = append(*implicits, apiFile)
-		*implicits = append(*implicits, removedApiFile)
-
-		flags = flags + " --check-compatibility:api:released " + apiFile.String() +
-			" --check-compatibility:removed:released " + removedApiFile.String() + " "
-	}
-
-	return flags
-}
-
 func (d *Droiddoc) transformMetalava(ctx android.ModuleContext, implicits android.Paths,
 	implicitOutputs android.WritablePaths, outDir, docStubsDir, javaVersion,
 	bootclasspathArgs, classpathArgs, opts string) {
@@ -1117,6 +1102,29 @@
 	})
 }
 
+func (d *Droiddoc) transformMetalavaCheckApi(ctx android.ModuleContext, apiFile, removedApiFile android.Path,
+	implicits android.Paths, javaVersion, bootclasspathArgs, classpathArgs, opts, msg string,
+	output android.WritablePath) {
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        metalavaApiCheck,
+		Description: "Metalava Check API",
+		Output:      output,
+		Inputs:      d.Javadoc.srcFiles,
+		Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
+			implicits...),
+		Args: map[string]string{
+			"srcJarDir":         android.PathForModuleOut(ctx, "srcjars").String(),
+			"srcJars":           strings.Join(d.Javadoc.srcJars.Strings(), " "),
+			"javaVersion":       javaVersion,
+			"bootclasspathArgs": bootclasspathArgs,
+			"classpathArgs":     classpathArgs,
+			"sourcepath":        strings.Join(d.Javadoc.sourcepaths.Strings(), ":"),
+			"opts":              opts,
+			"msg":               msg,
+		},
+	})
+}
+
 func (d *Droiddoc) transformUpdateApi(ctx android.ModuleContext, apiFile, removedApiFile android.Path,
 	output android.WritablePath) {
 	ctx.Build(pctx, android.BuildParams{
@@ -1152,6 +1160,7 @@
 	}
 
 	flags, err := d.initBuilderFlags(ctx, &implicits, deps)
+	metalavaCheckApiImplicits := implicits
 	if err != nil {
 		return
 	}
@@ -1159,7 +1168,6 @@
 	flags.doclavaStubsFlags, flags.metalavaStubsFlags = d.collectStubsFlags(ctx, &implicitOutputs)
 	if Bool(d.properties.Metalava_enabled) {
 		flags.metalavaAnnotationsFlags = d.collectMetalavaAnnotationsFlags(ctx, &implicits, &implicitOutputs)
-		flags.metalavaCompatibilityCheckFlags = d.collectMetalavaCompatibilityCheckFlags(ctx, &implicits)
 		outDir := android.PathForModuleOut(ctx, "out").String()
 		docStubsDir := android.PathForModuleOut(ctx, "docStubsDir").String()
 		// TODO(nanzhang): Add a Soong property to handle documentation args.
@@ -1169,7 +1177,7 @@
 					flags.dokkaClasspathArgs, outDir, docStubsDir)
 				d.transformMetalava(ctx, implicits, implicitOutputs, outDir, docStubsDir, javaVersion,
 					flags.bootClasspathArgs, flags.classpathArgs, flags.metalavaStubsFlags+
-						flags.metalavaAnnotationsFlags+" "+flags.metalavaCompatibilityCheckFlags+" "+
+						flags.metalavaAnnotationsFlags+" "+
 						strings.Split(flags.args, "--generate-documentation")[0]+
 						flags.metalavaDokkaFlags+" "+strings.Split(flags.args, "--generate-documentation")[1])
 			} else {
@@ -1178,7 +1186,7 @@
 				flags.doclavaDocsFlags = d.collectDoclavaDocsFlags(ctx, &implicits, jsilver, doclava)
 				d.transformMetalava(ctx, implicits, implicitOutputs, outDir, docStubsDir, javaVersion,
 					flags.bootClasspathArgs, flags.classpathArgs, flags.metalavaStubsFlags+
-						flags.metalavaAnnotationsFlags+" "+flags.metalavaCompatibilityCheckFlags+" "+
+						flags.metalavaAnnotationsFlags+" "+
 						strings.Split(flags.args, "--generate-documentation")[0]+
 						flags.metalavaJavadocFlags+flags.doclavaDocsFlags+
 						" "+strings.Split(flags.args, "--generate-documentation")[1])
@@ -1186,8 +1194,7 @@
 		} else {
 			d.transformMetalava(ctx, implicits, implicitOutputs, outDir, docStubsDir, javaVersion,
 				flags.bootClasspathArgs, flags.classpathArgs,
-				flags.metalavaStubsFlags+flags.metalavaAnnotationsFlags+" "+
-					flags.metalavaCompatibilityCheckFlags+flags.args)
+				flags.metalavaStubsFlags+flags.metalavaAnnotationsFlags+" "+flags.args)
 		}
 	} else {
 		flags.doclavaDocsFlags = d.collectDoclavaDocsFlags(ctx, &implicits, jsilver, doclava)
@@ -1203,8 +1210,8 @@
 		removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Removed_api_file),
 			"check_api.current_removed_api_file")
 
+		d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
 		if !Bool(d.properties.Metalava_enabled) {
-			d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
 			d.transformCheckApi(ctx, apiFile, removedApiFile, checkApiClasspath,
 				fmt.Sprintf(`\n******************************\n`+
 					`You have tried to change the API from what has been previously approved.\n\n`+
@@ -1217,6 +1224,23 @@
 					`      you will need approval.\n`+
 					`******************************\n`, ctx.ModuleName()), String(d.properties.Check_api.Current.Args),
 				d.checkCurrentApiTimestamp)
+		} else {
+			opts := flags.args + " --check-compatibility:api:current " + apiFile.String() +
+				" --check-compatibility:removed:current " + removedApiFile.String() + " "
+
+			d.transformMetalavaCheckApi(ctx, apiFile, removedApiFile, metalavaCheckApiImplicits,
+				javaVersion, flags.bootClasspathArgs, flags.classpathArgs, opts,
+				fmt.Sprintf(`\n******************************\n`+
+					`You have tried to change the API from what has been previously approved.\n\n`+
+					`To make these errors go away, you have two choices:\n`+
+					`   1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
+					`      errors above.\n\n`+
+					`   2. You can update current.txt by executing the following command:\n`+
+					`         make %s-update-current-api\n\n`+
+					`      To submit the revised current.txt to the main Android repository,\n`+
+					`      you will need approval.\n`+
+					`******************************\n`, ctx.ModuleName()),
+				d.checkCurrentApiTimestamp)
 		}
 
 		d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
@@ -1229,15 +1253,25 @@
 		removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Removed_api_file),
 			"check_api.last_released.removed_api_file")
 
+		d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
 		if !Bool(d.properties.Metalava_enabled) {
-			d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
-
 			d.transformCheckApi(ctx, apiFile, removedApiFile, checkApiClasspath,
 				`\n******************************\n`+
 					`You have tried to change the API from what has been previously released in\n`+
 					`an SDK.  Please fix the errors listed above.\n`+
 					`******************************\n`, String(d.properties.Check_api.Last_released.Args),
 				d.checkLastReleasedApiTimestamp)
+		} else {
+			opts := flags.args + " --check-compatibility:api:released " + apiFile.String() +
+				" --check-compatibility:removed:released " + removedApiFile.String() + " "
+
+			d.transformMetalavaCheckApi(ctx, apiFile, removedApiFile, metalavaCheckApiImplicits,
+				javaVersion, flags.bootClasspathArgs, flags.classpathArgs, opts,
+				`\n******************************\n`+
+					`You have tried to change the API from what has been previously released in\n`+
+					`an SDK.  Please fix the errors listed above.\n`+
+					`******************************\n`,
+				d.checkLastReleasedApiTimestamp)
 		}
 	}
 }