Merge "bp2build: cc_object converter."
diff --git a/android/arch.go b/android/arch.go
index 2decea8..6fb70c9 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -1609,13 +1609,15 @@
 		} else {
 			buildTargets = firstTarget(targets, "lib64", "lib32")
 		}
+	case "first_prefer32":
+		buildTargets = firstTarget(targets, "lib32", "lib64")
 	case "prefer32":
 		buildTargets = filterMultilibTargets(targets, "lib32")
 		if len(buildTargets) == 0 {
 			buildTargets = filterMultilibTargets(targets, "lib64")
 		}
 	default:
-		return nil, fmt.Errorf(`compile_multilib must be "both", "first", "32", "64", or "prefer32" found %q`,
+		return nil, fmt.Errorf(`compile_multilib must be "both", "first", "32", "64", "prefer32" or "first_prefer32" found %q`,
 			multilib)
 	}
 
diff --git a/android/config.go b/android/config.go
index 9162eaa..c6885dd 100644
--- a/android/config.go
+++ b/android/config.go
@@ -128,7 +128,7 @@
 
 	// If testAllowNonExistentPaths is true then PathForSource and PathForModuleSrc won't error
 	// in tests when a path doesn't exist.
-	testAllowNonExistentPaths bool
+	TestAllowNonExistentPaths bool
 
 	// The list of files that when changed, must invalidate soong_build to
 	// regenerate build.ninja.
@@ -256,7 +256,7 @@
 
 		// Set testAllowNonExistentPaths so that test contexts don't need to specify every path
 		// passed to PathForSource or PathForModuleSrc.
-		testAllowNonExistentPaths: true,
+		TestAllowNonExistentPaths: true,
 
 		BazelContext: noopBazelContext{},
 	}
diff --git a/android/paths.go b/android/paths.go
index 58e1f74..ada4da6 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -586,7 +586,7 @@
 		p := pathForModuleSrc(ctx, sPath)
 		if exists, _, err := ctx.Config().fs.Exists(p.String()); err != nil {
 			ReportPathErrorf(ctx, "%s: %s", p, err.Error())
-		} else if !exists && !ctx.Config().testAllowNonExistentPaths {
+		} else if !exists && !ctx.Config().TestAllowNonExistentPaths {
 			ReportPathErrorf(ctx, "module source path %q does not exist", p)
 		}
 
@@ -1022,7 +1022,7 @@
 		}
 	} else if exists, _, err := ctx.Config().fs.Exists(path.String()); err != nil {
 		ReportPathErrorf(ctx, "%s: %s", path, err.Error())
-	} else if !exists && !ctx.Config().testAllowNonExistentPaths {
+	} else if !exists && !ctx.Config().TestAllowNonExistentPaths {
 		ReportPathErrorf(ctx, "source path %q does not exist", path)
 	}
 	return path
diff --git a/apex/allowed_deps.txt b/apex/allowed_deps.txt
index add0e1e..4e7039c 100644
--- a/apex/allowed_deps.txt
+++ b/apex/allowed_deps.txt
@@ -176,6 +176,8 @@
 ExtServices-core(minSdkVersion:current)
 flatbuffer_headers(minSdkVersion:(no version))
 fmtlib(minSdkVersion:29)
+fmtlib_ndk(minSdkVersion:29)
+framework-mediaprovider(minSdkVersion:30)
 framework-permission(minSdkVersion:30)
 framework-permission(minSdkVersion:current)
 framework-permission-s(minSdkVersion:30)
@@ -240,6 +242,7 @@
 libbacktrace_sys.rust_sysroot(minSdkVersion:29)
 libbase(minSdkVersion:29)
 libbase_headers(minSdkVersion:29)
+libbase_ndk(minSdkVersion:29)
 libbinder_headers(minSdkVersion:29)
 libbinder_headers_platform_shared(minSdkVersion:29)
 libbinderthreadstateutils(minSdkVersion:29)
@@ -315,6 +318,8 @@
 libfmq(minSdkVersion:29)
 libfmq-base(minSdkVersion:29)
 libFraunhoferAAC(minSdkVersion:29)
+libfuse(minSdkVersion:30)
+libfuse_jni(minSdkVersion:30)
 libgav1(minSdkVersion:29)
 libgcc(minSdkVersion:(no version))
 libgcc_stripped(minSdkVersion:(no version))
@@ -468,6 +473,7 @@
 libzstd(minSdkVersion:(no version))
 media_ndk_headers(minSdkVersion:29)
 media_plugin_headers(minSdkVersion:29)
+MediaProvider(minSdkVersion:30)
 mediaswcodec(minSdkVersion:29)
 metrics-constants-protos(minSdkVersion:29)
 modules-utils-build(minSdkVersion:29)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 181946b..bbc4b93 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -2039,7 +2039,7 @@
 		},
 		{
 			name:          "Updatable apex with non-stable transitive dep",
-			expectedError: "compiles against Android API, but dependency \"transitive-jar\" is compiling against non-public Android API.",
+			expectedError: "compiles against Android API, but dependency \"transitive-jar\" is compiling against private API.",
 			bp: `
 				apex {
 					name: "myapex",
diff --git a/cc/fuzz.go b/cc/fuzz.go
index d7da5ab..9fe5b17 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -20,6 +20,8 @@
 	"sort"
 	"strings"
 
+	"github.com/google/blueprint/proptools"
+
 	"android/soong/android"
 	"android/soong/cc/config"
 )
@@ -172,7 +174,7 @@
 // This function takes a module and determines if it is a unique shared library
 // that should be installed in the fuzz target output directories. This function
 // returns true, unless:
-//  - The module is not a shared library, or
+//  - The module is not an installable shared library, or
 //  - The module is a header, stub, or vendor-linked library, or
 //  - The module is a prebuilt and its source is available, or
 //  - The module is a versioned member of an SDK snapshot.
@@ -209,6 +211,11 @@
 		if _, isLLndkStubLibrary := ccLibrary.linker.(*stubDecorator); isLLndkStubLibrary {
 			return false
 		}
+		// Discard installable:false libraries because they are expected to be absent
+		// in runtime.
+		if !proptools.BoolDefault(ccLibrary.Properties.Installable, true) {
+			return false
+		}
 	}
 
 	// If the same library is present both as source and a prebuilt we must pick
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index 57563eb..e15324b 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -282,11 +282,14 @@
 		Input:  p.sourceFilePath,
 	})
 
-	if p.Installable() {
-		installPath := ctx.InstallFile(p.installDirPath, p.outputFilePath.Base(), p.outputFilePath)
-		for _, sl := range p.properties.Symlinks {
-			ctx.InstallSymlink(p.installDirPath, sl, installPath)
-		}
+	if !p.Installable() {
+		p.SkipInstall()
+	}
+
+	// Call InstallFile even when uninstallable to make the module included in the package
+	installPath := ctx.InstallFile(p.installDirPath, p.outputFilePath.Base(), p.outputFilePath)
+	for _, sl := range p.properties.Symlinks {
+		ctx.InstallSymlink(p.installDirPath, sl, installPath)
 	}
 }
 
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index c315124..282e936 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -82,10 +82,6 @@
 		deviceDir := android.PathForOutput(ctx, ctx.Config().DeviceName())
 
 		artModules := global.ArtApexJars
-		// With EMMA_INSTRUMENT_FRAMEWORK=true the Core libraries depend on jacoco.
-		if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
-			artModules = artModules.Append("com.android.art", "jacocoagent")
-		}
 		frameworkModules := global.BootJars.RemoveList(artModules)
 
 		artSubdir := "apex/art_boot_images/javalib"
diff --git a/java/java.go b/java/java.go
index 69ec2a4..dbfad02 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1014,6 +1014,7 @@
 const (
 	// TODO(jiyong) rename these for better readability. Make the allowed
 	// and disallowed link types explicit
+	// order is important here. See rank()
 	javaCore linkType = iota
 	javaSdk
 	javaSystem
@@ -1022,6 +1023,31 @@
 	javaPlatform
 )
 
+func (lt linkType) String() string {
+	switch lt {
+	case javaCore:
+		return "core Java API"
+	case javaSdk:
+		return "Android API"
+	case javaSystem:
+		return "system API"
+	case javaModule:
+		return "module API"
+	case javaSystemServer:
+		return "system server API"
+	case javaPlatform:
+		return "private API"
+	default:
+		panic(fmt.Errorf("unrecognized linktype: %v", lt))
+	}
+}
+
+// rank determins the total order among linkTypes. A link type of rank A can link to another link
+// type of rank B only when B <= A
+func (lt linkType) rank() int {
+	return int(lt)
+}
+
 type linkTypeContext interface {
 	android.Module
 	getLinkType(name string) (ret linkType, stubs bool)
@@ -1081,44 +1107,13 @@
 		return
 	}
 	otherLinkType, _ := to.getLinkType(ctx.OtherModuleName(to))
-	commonMessage := " In order to fix this, consider adjusting sdk_version: OR platform_apis: " +
-		"property of the source or target module so that target module is built with the same " +
-		"or smaller API set when compared to the source."
 
-	switch myLinkType {
-	case javaCore:
-		if otherLinkType != javaCore {
-			ctx.ModuleErrorf("compiles against core Java API, but dependency %q is compiling against non-core Java APIs."+commonMessage,
-				ctx.OtherModuleName(to))
-		}
-		break
-	case javaSdk:
-		if otherLinkType != javaCore && otherLinkType != javaSdk {
-			ctx.ModuleErrorf("compiles against Android API, but dependency %q is compiling against non-public Android API."+commonMessage,
-				ctx.OtherModuleName(to))
-		}
-		break
-	case javaSystem:
-		if otherLinkType == javaPlatform || otherLinkType == javaModule || otherLinkType == javaSystemServer {
-			ctx.ModuleErrorf("compiles against system API, but dependency %q is compiling against private API."+commonMessage,
-				ctx.OtherModuleName(to))
-		}
-		break
-	case javaModule:
-		if otherLinkType == javaPlatform || otherLinkType == javaSystemServer {
-			ctx.ModuleErrorf("compiles against module API, but dependency %q is compiling against private API."+commonMessage,
-				ctx.OtherModuleName(to))
-		}
-		break
-	case javaSystemServer:
-		if otherLinkType == javaPlatform {
-			ctx.ModuleErrorf("compiles against system server API, but dependency %q is compiling against private API."+commonMessage,
-				ctx.OtherModuleName(to))
-		}
-		break
-	case javaPlatform:
-		// no restriction on link-type
-		break
+	if myLinkType.rank() < otherLinkType.rank() {
+		ctx.ModuleErrorf("compiles against %v, but dependency %q is compiling against %v. "+
+			"In order to fix this, consider adjusting sdk_version: OR platform_apis: "+
+			"property of the source or target module so that target module is built "+
+			"with the same or smaller API set when compared to the source.",
+			myLinkType, ctx.OtherModuleName(to), otherLinkType)
 	}
 }
 
diff --git a/java/java_test.go b/java/java_test.go
index e7776c3..0ef4db6 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -127,7 +127,6 @@
 	}
 
 	t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
-
 	return ctx, config
 }
 
@@ -1179,6 +1178,110 @@
 	}
 }
 
+func TestJavaLint(t *testing.T) {
+	ctx, _ := testJavaWithFS(t, `
+		java_library {
+			name: "foo",
+			srcs: [
+				"a.java",
+				"b.java",
+				"c.java",
+			],
+			min_sdk_version: "29",
+			sdk_version: "system_current",
+		}
+       `, map[string][]byte{
+		"lint-baseline.xml": nil,
+	})
+
+	foo := ctx.ModuleForTests("foo", "android_common")
+	rule := foo.Rule("lint")
+
+	if !strings.Contains(rule.RuleParams.Command, "--baseline lint-baseline.xml") {
+		t.Error("did not pass --baseline flag")
+	}
+}
+
+func TestJavaLintWithoutBaseline(t *testing.T) {
+	ctx, _ := testJavaWithFS(t, `
+		java_library {
+			name: "foo",
+			srcs: [
+				"a.java",
+				"b.java",
+				"c.java",
+			],
+			min_sdk_version: "29",
+			sdk_version: "system_current",
+		}
+       `, map[string][]byte{})
+
+	foo := ctx.ModuleForTests("foo", "android_common")
+	rule := foo.Rule("lint")
+
+	if strings.Contains(rule.RuleParams.Command, "--baseline") {
+		t.Error("passed --baseline flag for non existent file")
+	}
+}
+
+func TestJavaLintRequiresCustomLintFileToExist(t *testing.T) {
+	config := testConfig(
+		nil,
+		`
+		java_library {
+			name: "foo",
+			srcs: [
+			],
+			min_sdk_version: "29",
+			sdk_version: "system_current",
+			lint: {
+				baseline_filename: "mybaseline.xml",
+			},
+		}
+     `, map[string][]byte{
+			"build/soong/java/lint_defaults.txt":                   nil,
+			"prebuilts/cmdline-tools/tools/bin/lint":               nil,
+			"prebuilts/cmdline-tools/tools/lib/lint-classpath.jar": nil,
+			"framework/aidl":                     nil,
+			"a.java":                             nil,
+			"AndroidManifest.xml":                nil,
+			"build/make/target/product/security": nil,
+		})
+	config.TestAllowNonExistentPaths = false
+	testJavaErrorWithConfig(t,
+		"source path \"mybaseline.xml\" does not exist",
+		config,
+	)
+}
+
+func TestJavaLintUsesCorrectBpConfig(t *testing.T) {
+	ctx, _ := testJavaWithFS(t, `
+		java_library {
+			name: "foo",
+			srcs: [
+				"a.java",
+				"b.java",
+				"c.java",
+			],
+			min_sdk_version: "29",
+			sdk_version: "system_current",
+			lint: {
+				error_checks: ["SomeCheck"],
+				baseline_filename: "mybaseline.xml",
+			},
+		}
+       `, map[string][]byte{
+		"mybaseline.xml": nil,
+	})
+
+	foo := ctx.ModuleForTests("foo", "android_common")
+	rule := foo.Rule("lint")
+
+	if !strings.Contains(rule.RuleParams.Command, "--baseline mybaseline.xml") {
+		t.Error("did not use the correct file for baseline")
+	}
+}
+
 func TestGeneratedSources(t *testing.T) {
 	ctx, _ := testJavaWithFS(t, `
 		java_library {
diff --git a/java/lint.go b/java/lint.go
index c9e0cdd..8272595 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -19,6 +19,8 @@
 	"sort"
 	"strings"
 
+	"github.com/google/blueprint/proptools"
+
 	"android/soong/android"
 )
 
@@ -46,6 +48,9 @@
 
 		// Modules that provide extra lint checks
 		Extra_check_modules []string
+
+		// Name of the file that lint uses as the baseline. Defaults to "lint-baseline.xml".
+		Baseline_filename *string
 	}
 }
 
@@ -344,6 +349,19 @@
 		cmd.FlagWithArg("--check ", checkOnly)
 	}
 
+	if lintFilename := proptools.StringDefault(l.properties.Lint.Baseline_filename, "lint-baseline.xml"); lintFilename != "" {
+		var lintBaseline android.OptionalPath
+		if String(l.properties.Lint.Baseline_filename) != "" {
+			// if manually specified, we require the file to exist
+			lintBaseline = android.OptionalPathForPath(android.PathForModuleSrc(ctx, lintFilename))
+		} else {
+			lintBaseline = android.ExistentPathForSource(ctx, ctx.ModuleDir(), lintFilename)
+		}
+		if lintBaseline.Valid() {
+			cmd.FlagWithInput("--baseline ", lintBaseline.Path())
+		}
+	}
+
 	cmd.Text("|| (").Text("cat").Input(text).Text("; exit 7)").Text(")")
 
 	rule.Command().Text("rm -rf").Flag(cacheDir.String()).Flag(homeDir.String())
diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go
index 1e90149..c91b321 100644
--- a/java/prebuilt_apis.go
+++ b/java/prebuilt_apis.go
@@ -106,14 +106,18 @@
 	mctx.CreateModule(ImportFactory, &props)
 }
 
-func createFilegroup(mctx android.LoadHookContext, name string, path string) {
-	filegroupProps := struct {
+func createApiModule(mctx android.LoadHookContext, name string, path string) {
+	genruleProps := struct {
 		Name *string
 		Srcs []string
+		Out  []string
+		Cmd  *string
 	}{}
-	filegroupProps.Name = proptools.StringPtr(name)
-	filegroupProps.Srcs = []string{path}
-	mctx.CreateModule(android.FileGroupFactory, &filegroupProps)
+	genruleProps.Name = proptools.StringPtr(name)
+	genruleProps.Srcs = []string{path}
+	genruleProps.Out = []string{name}
+	genruleProps.Cmd = proptools.StringPtr("cp $(in) $(out)")
+	mctx.CreateModule(genrule.GenRuleFactory, &genruleProps)
 }
 
 func createEmptyFile(mctx android.LoadHookContext, name string) {
@@ -205,16 +209,16 @@
 		path    string
 	}
 
-	// Create filegroups for all (<module>, <scope, <version>) triplets,
-	// and a "latest" filegroup variant for each (<module>, <scope>) pair
-	moduleName := func(module, scope, version string) string {
+	// Create modules for all (<module>, <scope, <version>) triplets,
+	// and a "latest" module variant for each (<module>, <scope>) pair
+	apiModuleName := func(module, scope, version string) string {
 		return module + ".api." + scope + "." + version
 	}
 	m := make(map[string]latestApiInfo)
 	for _, f := range files {
 		localPath := strings.TrimPrefix(f, mydir)
 		module, apiver, scope := parseApiFilePath(mctx, localPath)
-		createFilegroup(mctx, moduleName(module, scope, apiver), localPath)
+		createApiModule(mctx, apiModuleName(module, scope, apiver), localPath)
 
 		version, err := strconv.Atoi(apiver)
 		if err != nil {
@@ -239,8 +243,8 @@
 	// Sort the keys in order to make build.ninja stable
 	for _, k := range android.SortedStringKeys(m) {
 		info := m[k]
-		name := moduleName(info.module, info.scope, "latest")
-		createFilegroup(mctx, name, info.path)
+		name := apiModuleName(info.module, info.scope, "latest")
+		createApiModule(mctx, name, info.path)
 	}
 
 	// Create incompatibilities tracking files for all modules, if we have a "next" api.
@@ -258,14 +262,14 @@
 				referencedModule = "android"
 			}
 
-			createFilegroup(mctx, moduleName(referencedModule+"-incompatibilities", scope, "latest"), localPath)
+			createApiModule(mctx, apiModuleName(referencedModule+"-incompatibilities", scope, "latest"), localPath)
 
 			incompatibilities[referencedModule+"."+scope] = true
 		}
 		// Create empty incompatibilities files for remaining modules
 		for _, k := range android.SortedStringKeys(m) {
 			if _, ok := incompatibilities[k]; !ok {
-				createEmptyFile(mctx, moduleName(m[k].module+"-incompatibilities", m[k].scope, "latest"))
+				createEmptyFile(mctx, apiModuleName(m[k].module+"-incompatibilities", m[k].scope, "latest"))
 			}
 		}
 	}
@@ -279,10 +283,10 @@
 	}
 }
 
-// prebuilt_apis is a meta-module that generates filegroup modules for all
-// API txt files found under the directory where the Android.bp is located.
+// prebuilt_apis is a meta-module that generates modules for all API txt files
+// found under the directory where the Android.bp is located.
 // Specifically, an API file located at ./<ver>/<scope>/api/<module>.txt
-// generates a filegroup module named <module>-api.<scope>.<ver>.
+// generates a module named <module>-api.<scope>.<ver>.
 //
 // It also creates <module>-api.<scope>.latest for the latest <ver>.
 //
diff --git a/scripts/build-mainline-modules.sh b/scripts/build-mainline-modules.sh
index ac67438..b93c883 100755
--- a/scripts/build-mainline-modules.sh
+++ b/scripts/build-mainline-modules.sh
@@ -8,6 +8,7 @@
   com.android.art.testing
   com.android.conscrypt
   com.android.i18n
+  com.android.os.statsd
   com.android.runtime
   com.android.tzdata
 )