Merge "Add a script to inject values into manifests"
diff --git a/android/paths.go b/android/paths.go
index 8cc3182..af2f956 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -950,7 +950,8 @@
 		if ctx.InstallInData() {
 			partition = "data"
 		} else if ctx.InstallInRecovery() {
-			partition = "recovery/root"
+			// the layout of recovery partion is the same as that of system partition
+			partition = "recovery/root/system"
 		} else if ctx.SocSpecific() {
 			partition = ctx.DeviceConfig().VendorPath()
 		} else if ctx.DeviceSpecific() {
diff --git a/cc/binary.go b/cc/binary.go
index 04b912a..4a6eb93 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -357,11 +357,6 @@
 }
 
 func (binary *binaryDecorator) install(ctx ModuleContext, file android.Path) {
-	// <recovery>/bin is a symlink to /system/bin. Recovery binaries are all in /sbin.
-	if ctx.inRecovery() {
-		binary.baseInstaller.dir = "sbin"
-	}
-
 	binary.baseInstaller.install(ctx, file)
 	for _, symlink := range binary.Properties.Symlinks {
 		binary.symlinks = append(binary.symlinks,
diff --git a/cc/builder.go b/cc/builder.go
index bc3652e..51d3195 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -726,11 +726,14 @@
 	baseName, exportedHeaderFlags string, isVndkExt bool) android.OptionalPath {
 
 	outputFile := android.PathForModuleOut(ctx, baseName+".abidiff")
-
+	libName := strings.TrimSuffix(baseName, filepath.Ext(baseName))
 	localAbiCheckAllowFlags := append([]string(nil), abiCheckAllowFlags...)
 	if exportedHeaderFlags == "" {
 		localAbiCheckAllowFlags = append(localAbiCheckAllowFlags, "-advice-only")
 	}
+	if inList(libName, llndkLibraries) {
+		localAbiCheckAllowFlags = append(localAbiCheckAllowFlags, "-consider-opaque-types-different")
+	}
 	if isVndkExt {
 		localAbiCheckAllowFlags = append(localAbiCheckAllowFlags, "-allow-extensions")
 	}
@@ -743,7 +746,7 @@
 		Implicit:    referenceDump,
 		Args: map[string]string{
 			"referenceDump": referenceDump.String(),
-			"libName":       baseName[0:(len(baseName) - len(filepath.Ext(baseName)))],
+			"libName":       libName,
 			"arch":          ctx.Arch().ArchType.Name,
 			"allowFlags":    strings.Join(localAbiCheckAllowFlags, " "),
 		},
diff --git a/cc/cc.go b/cc/cc.go
index 36b2f95..6438bcd 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -571,7 +571,7 @@
 		isVariantOnProductionDevice = sanitize.isVariantOnProductionDevice()
 	}
 	vendorAvailable := Bool(ctx.mod.VendorProperties.Vendor_available)
-	return !skipAbiChecks && isVariantOnProductionDevice && ctx.ctx.Device() && ((ctx.useVndk() && ctx.isVndk() && vendorAvailable) || inList(ctx.baseModuleName(), llndkLibraries))
+	return !skipAbiChecks && isVariantOnProductionDevice && ctx.ctx.Device() && ((ctx.useVndk() && ctx.isVndk() && (vendorAvailable || ctx.isVndkExt())) || inList(ctx.baseModuleName(), llndkLibraries))
 }
 
 func (ctx *moduleContextImpl) selectedStl() string {
diff --git a/cc/cmakelists.go b/cc/cmakelists.go
index c25578e..a2f46cd 100644
--- a/cc/cmakelists.go
+++ b/cc/cmakelists.go
@@ -62,10 +62,14 @@
 
 	outputDebugInfo = (getEnvVariable(envVariableGenerateDebugInfo, ctx) == envVariableTrue)
 
+	// Track which projects have already had CMakeLists.txt generated to keep the first
+	// variant for each project.
+	seenProjects := map[string]bool{}
+
 	ctx.VisitAllModules(func(module android.Module) {
 		if ccModule, ok := module.(*Module); ok {
 			if compiledModule, ok := ccModule.compiler.(CompiledInterface); ok {
-				generateCLionProject(compiledModule, ctx, ccModule)
+				generateCLionProject(compiledModule, ctx, ccModule, seenProjects)
 			}
 		}
 	})
@@ -114,14 +118,22 @@
 	return nil
 }
 
-func generateCLionProject(compiledModule CompiledInterface, ctx android.SingletonContext, ccModule *Module) {
+func generateCLionProject(compiledModule CompiledInterface, ctx android.SingletonContext, ccModule *Module,
+	seenProjects map[string]bool) {
 	srcs := compiledModule.Srcs()
 	if len(srcs) == 0 {
 		return
 	}
 
-	// Ensure the directory hosting the cmakelists.txt exists
+	// Only write CMakeLists.txt for the first variant of each architecture of each module
 	clionproject_location := getCMakeListsForModule(ccModule, ctx)
+	if seenProjects[clionproject_location] {
+		return
+	}
+
+	seenProjects[clionproject_location] = true
+
+	// Ensure the directory hosting the cmakelists.txt exists
 	projectDir := path.Dir(clionproject_location)
 	os.MkdirAll(projectDir, os.ModePerm)
 
diff --git a/cc/compiler.go b/cc/compiler.go
index 10cec8c..8d034c9 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -332,6 +332,10 @@
 			"-D__ANDROID_API__="+version, "-D__ANDROID_VNDK__")
 	}
 
+	if ctx.inRecovery() {
+		flags.GlobalFlags = append(flags.GlobalFlags, "-D__ANDROID_RECOVERY__")
+	}
+
 	instructionSet := String(compiler.Properties.Instruction_set)
 	if flags.RequiredInstructionSet != "" {
 		instructionSet = flags.RequiredInstructionSet
diff --git a/cc/config/global.go b/cc/config/global.go
index c734c2e..dee7640 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -89,6 +89,9 @@
 
 	deviceGlobalLldflags = append(ClangFilterUnknownLldflags(deviceGlobalLdflags),
 		[]string{
+			// TODO(b/109657296): needs --no-rosegment until Android
+			// stack unwinder can handle the read-only segment.
+			"-Wl,--no-rosegment",
 			"-Wl,--pack-dyn-relocs=android",
 			"-fuse-ld=lld",
 		}...)
diff --git a/cc/sabi.go b/cc/sabi.go
index f5a7c77..42b2f35 100644
--- a/cc/sabi.go
+++ b/cc/sabi.go
@@ -74,8 +74,13 @@
 
 	// RSClang does not support recent mcpu option likes exynos-m2.
 	// So we need overriding mcpu option when we want to use it.
-	if ctx.Arch().CpuVariant == "exynos-m2" {
-		flags.ToolingCFlags = append(flags.ToolingCFlags, "-mcpu=cortex-a53")
+	mappedArch := map[string]string{
+		"exynos-m2":  "cortex-a53",
+		"cortex-a55": "cortex-a53",
+		"cortex-a75": "cortex-a57",
+	}
+	if arch, ok := mappedArch[ctx.Arch().CpuVariant]; ok {
+		flags.ToolingCFlags = append(flags.ToolingCFlags, "-mcpu="+arch)
 	}
 
 	return flags
diff --git a/cc/vndk_prebuilt.go b/cc/vndk_prebuilt.go
index 9c9545d..849bb3f 100644
--- a/cc/vndk_prebuilt.go
+++ b/cc/vndk_prebuilt.go
@@ -21,7 +21,8 @@
 )
 
 var (
-	vndkSuffix = ".vndk."
+	vndkSuffix     = ".vndk."
+	binder32Suffix = ".binder32"
 )
 
 // Creates vndk prebuilts that include the VNDK version.
@@ -53,6 +54,10 @@
 	// Target arch name of the snapshot (e.g. 'arm64' for variant 'aosp_arm64_ab')
 	Target_arch *string
 
+	// If the prebuilt snapshot lib is built with 32 bit binder, this must be set to true.
+	// The lib with 64 bit binder does not need to set this property.
+	Binder32bit *bool
+
 	// Prebuilt files for each arch.
 	Srcs []string `android:"arch_variant"`
 }
@@ -67,10 +72,14 @@
 }
 
 func (p *vndkPrebuiltLibraryDecorator) NameSuffix() string {
+	suffix := p.version()
 	if p.arch() != "" {
-		return vndkSuffix + p.version() + "." + p.arch()
+		suffix += "." + p.arch()
 	}
-	return vndkSuffix + p.version()
+	if Bool(p.properties.Binder32bit) {
+		suffix += binder32Suffix
+	}
+	return vndkSuffix + suffix
 }
 
 func (p *vndkPrebuiltLibraryDecorator) version() string {
@@ -81,6 +90,13 @@
 	return String(p.properties.Target_arch)
 }
 
+func (p *vndkPrebuiltLibraryDecorator) binderBit() string {
+	if Bool(p.properties.Binder32bit) {
+		return "32"
+	}
+	return "64"
+}
+
 func (p *vndkPrebuiltLibraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
 	p.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), p.NameSuffix())
 	return p.libraryDecorator.linkerFlags(ctx, flags)
@@ -114,6 +130,9 @@
 	if len(arches) == 0 || arches[0].ArchType.String() != p.arch() {
 		return
 	}
+	if ctx.DeviceConfig().BinderBitness() != p.binderBit() {
+		return
+	}
 	if p.shared() {
 		if ctx.isVndkSp() {
 			p.baseInstaller.subDir = "vndk-sp-" + p.version()
diff --git a/java/androidmk.go b/java/androidmk.go
index 0840198..ab9ceeb 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -333,6 +333,9 @@
 				if ddoc.apiFile != nil {
 					fmt.Fprintln(w, apiFilePrefix+"API_FILE := ", ddoc.apiFile.String())
 				}
+				if ddoc.dexApiFile != nil {
+					fmt.Fprintln(w, apiFilePrefix+"DEX_API_FILE := ", ddoc.dexApiFile.String())
+				}
 				if ddoc.privateApiFile != nil {
 					fmt.Fprintln(w, apiFilePrefix+"PRIVATE_API_FILE := ", ddoc.privateApiFile.String())
 				}
diff --git a/java/droiddoc.go b/java/droiddoc.go
index b641041..ca99e76 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -203,6 +203,9 @@
 	// the generated public API filename by Doclava.
 	Api_filename *string
 
+	// the generated public Dex API filename by Doclava.
+	Dex_api_filename *string
+
 	// the generated private API filename by Doclava.
 	Private_api_filename *string
 
@@ -266,6 +269,7 @@
 
 	properties        DroiddocProperties
 	apiFile           android.WritablePath
+	dexApiFile        android.WritablePath
 	privateApiFile    android.WritablePath
 	privateDexApiFile android.WritablePath
 	removedApiFile    android.WritablePath
@@ -753,6 +757,12 @@
 		implicitOutputs = append(implicitOutputs, d.privateApiFile)
 	}
 
+	if String(d.properties.Dex_api_filename) != "" {
+		d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
+		args = args + " -dexApi " + d.dexApiFile.String()
+		implicitOutputs = append(implicitOutputs, d.dexApiFile)
+	}
+
 	if String(d.properties.Private_dex_api_filename) != "" {
 		d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
 		args = args + " -privateDexApi " + d.privateDexApiFile.String()
diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go
index 50318bb..3f4b076 100644
--- a/java/prebuilt_apis.go
+++ b/java/prebuilt_apis.go
@@ -50,6 +50,20 @@
 	// no need to implement
 }
 
+func parseJarPath(ctx android.BaseModuleContext, path string) (module string, apiver string, scope string) {
+	elements := strings.Split(path, "/")
+
+	apiver = elements[0]
+	scope = elements[1]
+	if scope != "public" && scope != "system" && scope != "test" && scope != "core" {
+		// scope must be public, system or test
+		return
+	}
+
+	module = strings.TrimSuffix(elements[2], ".jar")
+	return
+}
+
 func parseApiFilePath(ctx android.BaseModuleContext, path string) (module string, apiver int, scope string) {
 	elements := strings.Split(path, "/")
 	ver, err := strconv.Atoi(elements[0])
@@ -70,6 +84,22 @@
 	return
 }
 
+func createImport(mctx android.TopDownMutatorContext, module string, scope string, apiver string, path string) {
+	props := struct {
+		Name        *string
+		Jars        []string
+		Sdk_version *string
+		Installable *bool
+	}{}
+	props.Name = proptools.StringPtr("sdk_" + scope + "_" + apiver + "_" + module)
+	props.Jars = append(props.Jars, path)
+	// TODO(hansson): change to scope after migration is done.
+	props.Sdk_version = proptools.StringPtr("current")
+	props.Installable = proptools.BoolPtr(false)
+
+	mctx.CreateModule(android.ModuleFactoryAdaptor(ImportFactory), &props)
+}
+
 func createFilegroup(mctx android.TopDownMutatorContext, module string, scope string, apiver string, path string) {
 	fgName := module + ".api." + scope + "." + apiver
 	filegroupProps := struct {
@@ -81,55 +111,82 @@
 	mctx.CreateModule(android.ModuleFactoryAdaptor(android.FileGroupFactory), &filegroupProps)
 }
 
+func prebuiltSdkStubs(mctx android.TopDownMutatorContext) {
+	mydir := mctx.ModuleDir() + "/"
+	// <apiver>/<scope>/<module>.jar
+	files, err := mctx.GlobWithDeps(mydir+"*/*/*.jar", nil)
+	if err != nil {
+		mctx.ModuleErrorf("failed to glob jar files under %q: %s", mydir, err)
+	}
+	if len(files) == 0 {
+		mctx.ModuleErrorf("no jar file found under %q", mydir)
+	}
+
+	for _, f := range files {
+		// create a Import module for each jar file
+		localPath := strings.TrimPrefix(f, mydir)
+		module, apiver, scope := parseJarPath(mctx, localPath)
+
+		if len(module) != 0 {
+			createImport(mctx, module, scope, apiver, localPath)
+		}
+	}
+}
+
+func prebuiltApiFiles(mctx android.TopDownMutatorContext) {
+	mydir := mctx.ModuleDir() + "/"
+	// <apiver>/<scope>/api/<module>.txt
+	files, err := mctx.GlobWithDeps(mydir+"*/*/api/*.txt", nil)
+	if err != nil {
+		mctx.ModuleErrorf("failed to glob api txt files under %q: %s", mydir, err)
+	}
+	if len(files) == 0 {
+		mctx.ModuleErrorf("no api file found under %q", mydir)
+	}
+
+	// construct a map to find out the latest api file path
+	// for each (<module>, <scope>) pair.
+	type latestApiInfo struct {
+		module string
+		scope  string
+		apiver int
+		path   string
+	}
+	m := make(map[string]latestApiInfo)
+
+	for _, f := range files {
+		// create a filegroup for each api txt file
+		localPath := strings.TrimPrefix(f, mydir)
+		module, apiver, scope := parseApiFilePath(mctx, localPath)
+		createFilegroup(mctx, module, scope, strconv.Itoa(apiver), localPath)
+
+		// find the latest apiver
+		key := module + "." + scope
+		info, ok := m[key]
+		if !ok {
+			m[key] = latestApiInfo{module, scope, apiver, localPath}
+		} else if apiver > info.apiver {
+			info.apiver = apiver
+			info.path = localPath
+		}
+	}
+	// create filegroups for the latest version of (<module>, <scope>) pairs
+	// sort the keys in order to make build.ninja stable
+	keys := make([]string, 0, len(m))
+	for k := range m {
+		keys = append(keys, k)
+	}
+	sort.Strings(keys)
+	for _, k := range keys {
+		info := m[k]
+		createFilegroup(mctx, info.module, info.scope, "latest", info.path)
+	}
+}
+
 func prebuiltApisMutator(mctx android.TopDownMutatorContext) {
 	if _, ok := mctx.Module().(*prebuiltApis); ok {
-		mydir := mctx.ModuleDir() + "/"
-		// <apiver>/<scope>/api/<module>.txt
-		files, err := mctx.GlobWithDeps(mydir+"*/*/api/*.txt", nil)
-		if err != nil {
-			mctx.ModuleErrorf("failed to glob api txt files under %q: %s", mydir, err)
-		}
-		if len(files) == 0 {
-			mctx.ModuleErrorf("no api file found under %q", mydir)
-		}
-
-		// construct a map to find out the latest api file path
-		// for each (<module>, <scope>) pair.
-		type latestApiInfo struct {
-			module string
-			scope  string
-			apiver int
-			path   string
-		}
-		m := make(map[string]latestApiInfo)
-
-		for _, f := range files {
-			// create a filegroup for each api txt file
-			localPath := strings.TrimPrefix(f, mydir)
-			module, apiver, scope := parseApiFilePath(mctx, localPath)
-			createFilegroup(mctx, module, scope, strconv.Itoa(apiver), localPath)
-
-			// find the latest apiver
-			key := module + "." + scope
-			info, ok := m[key]
-			if !ok {
-				m[key] = latestApiInfo{module, scope, apiver, localPath}
-			} else if apiver > info.apiver {
-				info.apiver = apiver
-				info.path = localPath
-			}
-		}
-		// create filegroups for the latest version of (<module>, <scope>) pairs
-		// sort the keys in order to make build.ninja stable
-		keys := make([]string, 0, len(m))
-		for k := range m {
-			keys = append(keys, k)
-		}
-		sort.Strings(keys)
-		for _, k := range keys {
-			info := m[k]
-			createFilegroup(mctx, info.module, info.scope, "latest", info.path)
-		}
+		prebuiltApiFiles(mctx)
+		prebuiltSdkStubs(mctx)
 	}
 }
 
diff --git a/java/sdk_library.go b/java/sdk_library.go
index abd2dc2..aee528f 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -106,6 +106,11 @@
 	// list of package names that must be hidden from the API
 	Hidden_api_packages []string
 
+	Errorprone struct {
+		// List of javac flags that should only be used when running errorprone.
+		Javacflags []string
+	}
+
 	// TODO: determines whether to create HTML doc or not
 	//Html_doc *bool
 }
@@ -445,6 +450,9 @@
 		Device_specific  *bool
 		Product_specific *bool
 		Required         []string
+		Errorprone       struct {
+			Javacflags []string
+		}
 	}{}
 
 	props.Name = proptools.StringPtr(module.implName())
@@ -453,6 +461,7 @@
 	props.Static_libs = module.properties.Static_libs
 	// XML file is installed along with the impl lib
 	props.Required = []string{module.xmlFileName()}
+	props.Errorprone.Javacflags = module.properties.Errorprone.Javacflags
 
 	if module.SocSpecific() {
 		props.Soc_specific = proptools.BoolPtr(true)