Merge changes from topic "soong_instrumentation_for"

* changes:
  Fix instrumentation_for to match LOCAL_INSTRUMENTATION_FOR
  Fix incremental build issue in aapt2
  Support main_class property in java_binary modules
  Always allow duplicates with identical CRC32 and size
diff --git a/cmd/merge_zips/merge_zips.go b/cmd/merge_zips/merge_zips.go
index f383de9..8e71a97 100644
--- a/cmd/merge_zips/merge_zips.go
+++ b/cmd/merge_zips/merge_zips.go
@@ -173,6 +173,10 @@
 	return ze.content.FileHeader.CRC32
 }
 
+func (ze zipEntry) Size() uint64 {
+	return ze.content.FileHeader.UncompressedSize64
+}
+
 func (ze zipEntry) WriteToZip(dest string, zw *zip.Writer) error {
 	return zw.CopyFrom(ze.content, dest)
 }
@@ -195,6 +199,10 @@
 	return crc32.ChecksumIEEE(be.content)
 }
 
+func (be bufferEntry) Size() uint64 {
+	return uint64(len(be.content))
+}
+
 func (be bufferEntry) WriteToZip(dest string, zw *zip.Writer) error {
 	w, err := zw.CreateHeader(be.fh)
 	if err != nil {
@@ -215,6 +223,7 @@
 	String() string
 	IsDir() bool
 	CRC32() uint32
+	Size() uint64
 	WriteToZip(dest string, zw *zip.Writer) error
 }
 
@@ -369,25 +378,27 @@
 					return fmt.Errorf("Directory/file mismatch at %v from %v and %v\n",
 						dest, existingSource, source)
 				}
+
 				if ignoreDuplicates {
 					continue
 				}
+
 				if emulateJar &&
 					file.Name == jar.ManifestFile || file.Name == jar.ModuleInfoClass {
 					// Skip manifest and module info files that are not from the first input file
 					continue
 				}
-				if !source.IsDir() {
-					if emulateJar {
-						if existingSource.CRC32() != source.CRC32() {
-							fmt.Fprintf(os.Stdout, "WARNING: Duplicate path %v found in %v and %v\n",
-								dest, existingSource, source)
-						}
-					} else {
-						return fmt.Errorf("Duplicate path %v found in %v and %v\n",
-							dest, existingSource, source)
-					}
+
+				if source.IsDir() {
+					continue
 				}
+
+				if existingSource.CRC32() == source.CRC32() && existingSource.Size() == source.Size() {
+					continue
+				}
+
+				return fmt.Errorf("Duplicate path %v found in %v and %v\n",
+					dest, existingSource, source)
 			}
 		}
 	}
diff --git a/cmd/merge_zips/merge_zips_test.go b/cmd/merge_zips/merge_zips_test.go
index f91111f..19fa5ed 100644
--- a/cmd/merge_zips/merge_zips_test.go
+++ b/cmd/merge_zips/merge_zips_test.go
@@ -88,6 +88,14 @@
 			ignoreDuplicates: true,
 		},
 		{
+			name: "duplicates identical",
+			in: [][]testZipEntry{
+				{a},
+				{a},
+			},
+			out: []testZipEntry{a},
+		},
+		{
 			name: "sort",
 			in: [][]testZipEntry{
 				{be, bc, bDir, bbDir, bbb, A, metainfDir, manifestFile},
diff --git a/java/aapt2.go b/java/aapt2.go
index 70c7507..5553bfd 100644
--- a/java/aapt2.go
+++ b/java/aapt2.go
@@ -111,7 +111,8 @@
 
 var aapt2LinkRule = pctx.AndroidStaticRule("aapt2Link",
 	blueprint.RuleParams{
-		Command: `${config.Aapt2Cmd} link -o $out $flags --java $genDir --proguard $proguardOptions ` +
+		Command: `rm -rf $genDir && ` +
+			`${config.Aapt2Cmd} link -o $out $flags --java $genDir --proguard $proguardOptions ` +
 			`--output-text-symbols ${rTxt} $inFlags && ` +
 			`${config.SoongZipCmd} -write_if_changed -jar -o $genJar -C $genDir -D $genDir &&` +
 			`${config.ExtractJarPackagesCmd} -i $genJar -o $extraPackages --prefix '--extra-packages '`,
diff --git a/java/aar.go b/java/aar.go
index 35fb96f..a06d191 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -250,6 +250,8 @@
 		}
 
 		switch ctx.OtherModuleDependencyTag(module) {
+		case instrumentationForTag:
+			// Nothing, instrumentationForTag is treated as libTag for javac but not for aapt2.
 		case libTag, frameworkResTag:
 			if exportPackage != nil {
 				sharedLibs = append(sharedLibs, exportPackage)
diff --git a/java/app.go b/java/app.go
index d21b62a..5d25dcf 100644
--- a/java/app.go
+++ b/java/app.go
@@ -318,12 +318,6 @@
 }
 
 func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	if String(a.appTestProperties.Instrumentation_for) != "" {
-		a.AndroidApp.extraLinkFlags = append(a.AndroidApp.extraLinkFlags,
-			"--rename-instrumentation-target-package",
-			String(a.appTestProperties.Instrumentation_for))
-	}
-
 	a.generateAndroidBuildActions(ctx)
 
 	a.testConfig = tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config, a.testProperties.Test_config_template, a.manifestPath)
@@ -335,6 +329,12 @@
 	android.ExtractSourceDeps(ctx, a.testProperties.Test_config_template)
 	android.ExtractSourcesDeps(ctx, a.testProperties.Data)
 	a.AndroidApp.DepsMutator(ctx)
+	if a.appTestProperties.Instrumentation_for != nil {
+		// The android_app dependency listed in instrumentation_for needs to be added to the classpath for javac,
+		// but not added to the aapt2 link includes like a normal android_app or android_library dependency, so
+		// use instrumentationForTag instead of libTag.
+		ctx.AddVariationDependencies(nil, instrumentationForTag, String(a.appTestProperties.Instrumentation_for))
+	}
 }
 
 func AndroidTestFactory() android.Module {
diff --git a/java/builder.go b/java/builder.go
index f55a7c7..cefb916 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -399,6 +399,17 @@
 	})
 }
 
+func GenerateMainClassManifest(ctx android.ModuleContext, outputFile android.WritablePath, mainClass string) {
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        android.WriteFile,
+		Description: "manifest",
+		Output:      outputFile,
+		Args: map[string]string{
+			"content": "Main-Class: " + mainClass + "\n",
+		},
+	})
+}
+
 type classpath []android.Path
 
 func (x *classpath) FormJavaClassPath(optName string) string {
diff --git a/java/dex.go b/java/dex.go
index ce0c18e..625fb83 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -157,6 +157,8 @@
 	if !Bool(opt.Obfuscate) {
 		r8Flags = append(r8Flags, "-dontobfuscate")
 	}
+	// TODO(ccross): if this is an instrumentation test of an obfuscated app, use the
+	// dictionary of the app and move the app from libraryjars to injars.
 
 	return r8Flags, r8Deps
 }
@@ -171,8 +173,6 @@
 	outDir := android.PathForModuleOut(ctx, "dex")
 
 	if useR8 {
-		// TODO(ccross): if this is an instrumentation test of an obfuscated app, use the
-		// dictionary of the app and move the app from libraryjars to injars.
 		proguardDictionary := android.PathForModuleOut(ctx, "proguard_dictionary")
 		j.proguardDictionary = proguardDictionary
 		r8Flags, r8Deps := j.r8Flags(ctx, flags)
diff --git a/java/java.go b/java/java.go
index e5218bb..d7068c6 100644
--- a/java/java.go
+++ b/java/java.go
@@ -309,6 +309,9 @@
 	// list of extra progurad flag files
 	extraProguardFlagFiles android.Paths
 
+	// manifest file to use instead of properties.Manifest
+	overrideManifest android.OptionalPath
+
 	// list of SDK lib names that this java moudule is exporting
 	exportedSdkLibs []string
 
@@ -368,16 +371,17 @@
 }
 
 var (
-	staticLibTag     = dependencyTag{name: "staticlib"}
-	libTag           = dependencyTag{name: "javalib"}
-	annoTag          = dependencyTag{name: "annotation processor"}
-	bootClasspathTag = dependencyTag{name: "bootclasspath"}
-	systemModulesTag = dependencyTag{name: "system modules"}
-	frameworkResTag  = dependencyTag{name: "framework-res"}
-	frameworkApkTag  = dependencyTag{name: "framework-apk"}
-	kotlinStdlibTag  = dependencyTag{name: "kotlin-stdlib"}
-	proguardRaiseTag = dependencyTag{name: "proguard-raise"}
-	certificateTag   = dependencyTag{name: "certificate"}
+	staticLibTag          = dependencyTag{name: "staticlib"}
+	libTag                = dependencyTag{name: "javalib"}
+	annoTag               = dependencyTag{name: "annotation processor"}
+	bootClasspathTag      = dependencyTag{name: "bootclasspath"}
+	systemModulesTag      = dependencyTag{name: "system modules"}
+	frameworkResTag       = dependencyTag{name: "framework-res"}
+	frameworkApkTag       = dependencyTag{name: "framework-apk"}
+	kotlinStdlibTag       = dependencyTag{name: "kotlin-stdlib"}
+	proguardRaiseTag      = dependencyTag{name: "proguard-raise"}
+	certificateTag        = dependencyTag{name: "certificate"}
+	instrumentationForTag = dependencyTag{name: "instrumentation_for"}
 )
 
 type sdkDep struct {
@@ -817,7 +821,7 @@
 			switch tag {
 			case bootClasspathTag:
 				deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars()...)
-			case libTag:
+			case libTag, instrumentationForTag:
 				deps.classpath = append(deps.classpath, dep.HeaderJars()...)
 				// sdk lib names from dependencies are re-exported
 				j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
@@ -1193,8 +1197,8 @@
 	jars = append(jars, deps.staticJars...)
 	jars = append(jars, deps.staticResourceJars...)
 
-	var manifest android.OptionalPath
-	if j.properties.Manifest != nil {
+	manifest := j.overrideManifest
+	if !manifest.Valid() && j.properties.Manifest != nil {
 		manifest = android.OptionalPathForPath(ctx.ExpandSource(*j.properties.Manifest, "manifest"))
 	}
 
@@ -1536,6 +1540,9 @@
 type binaryProperties struct {
 	// installable script to execute the resulting jar
 	Wrapper *string
+
+	// Name of the class containing main to be inserted into the manifest as Main-Class.
+	Main_class *string
 }
 
 type Binary struct {
@@ -1556,6 +1563,15 @@
 func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	if ctx.Arch().ArchType == android.Common {
 		// Compile the jar
+		if j.binaryProperties.Main_class != nil {
+			if j.properties.Manifest != nil {
+				ctx.PropertyErrorf("main_class", "main_class cannot be used when manifest is set")
+			}
+			manifestFile := android.PathForModuleOut(ctx, "manifest.txt")
+			GenerateMainClassManifest(ctx, manifestFile, String(j.binaryProperties.Main_class))
+			j.overrideManifest = android.OptionalPathForPath(manifestFile)
+		}
+
 		j.Library.GenerateAndroidBuildActions(ctx)
 	} else {
 		// Handle the binary wrapper