Merge "Fix aar rules"
diff --git a/android/config.go b/android/config.go
index 6d81a38..122b99b 100644
--- a/android/config.go
+++ b/android/config.go
@@ -918,6 +918,17 @@
 		"invalid override rule %q in PRODUCT_CERTIFICATE_OVERRIDES should be <module_name>:<certificate_module_name>")
 }
 
+func (c *deviceConfig) OverridePackageNameFor(name string) string {
+	newName, overridden := findOverrideValue(
+		c.config.productVariables.PackageNameOverrides,
+		name,
+		"invalid override rule %q in PRODUCT_PACKAGE_NAME_OVERRIDES should be <module_name>:<package_name>")
+	if overridden {
+		return newName
+	}
+	return name
+}
+
 func findOverrideValue(overrides []string, name string, errorMsg string) (newValue string, overridden bool) {
 	if overrides == nil || len(overrides) == 0 {
 		return "", false
diff --git a/android/testing.go b/android/testing.go
index d318839..b7a043e 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -190,14 +190,14 @@
 	return BuildParams{}, searchedOutputs
 }
 
-// MaybeOutput finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputspath whose String() or Rel()
+// MaybeOutput finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputs whose String() or Rel()
 // value matches the provided string.  Returns an empty BuildParams if no rule is found.
 func (m TestingModule) MaybeOutput(file string) BuildParams {
 	p, _ := m.maybeOutput(file)
 	return p
 }
 
-// Output finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputspath whose String() or Rel()
+// Output finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputs whose String() or Rel()
 // value matches the provided string.  Panics if no rule is found.
 func (m TestingModule) Output(file string) BuildParams {
 	p, searchedOutputs := m.maybeOutput(file)
@@ -208,6 +208,19 @@
 	return p
 }
 
+// AllOutputs returns all 'BuildParams.Output's and 'BuildParams.Outputs's in their full path string forms.
+func (m TestingModule) AllOutputs() []string {
+	var outputFullPaths []string
+	for _, p := range m.module.BuildParamsForTests() {
+		outputs := append(WritablePaths(nil), p.Outputs...)
+		if p.Output != nil {
+			outputs = append(outputs, p.Output)
+		}
+		outputFullPaths = append(outputFullPaths, outputs.Strings()...)
+	}
+	return outputFullPaths
+}
+
 func FailIfErrored(t *testing.T, errs []error) {
 	t.Helper()
 	if len(errs) > 0 {
diff --git a/android/variable.go b/android/variable.go
index 67e876a..2cccd50 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -271,6 +271,7 @@
 
 	ManifestPackageNameOverrides []string `json:",omitempty"`
 	CertificateOverrides         []string `json:",omitempty"`
+	PackageNameOverrides         []string `json:",omitempty"`
 
 	EnforceSystemCertificate          *bool    `json:",omitempty"`
 	EnforceSystemCertificateWhitelist []string `json:",omitempty"`
diff --git a/apex/apex.go b/apex/apex.go
index 0aedb1a..46c9dcf 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -570,6 +570,11 @@
 				}
 			case executableTag:
 				if cc, ok := child.(*cc.Module); ok {
+					if !cc.Arch().Native {
+						// There is only one 'bin' directory so we shouldn't bother copying in
+						// native-bridge'd binaries and only use main ones.
+						return true
+					}
 					fileToCopy, dirInApex := getCopyManifestForExecutable(cc)
 					filesInfo = append(filesInfo, apexFile{fileToCopy, depName, cc.Arch().ArchType, dirInApex, nativeExecutable, cc})
 					return true
diff --git a/java/app.go b/java/app.go
index 45ef489..cc863e6 100644
--- a/java/app.go
+++ b/java/app.go
@@ -82,6 +82,9 @@
 	installJniLibs []jniLib
 
 	bundleFile android.Path
+
+	// the install APK name is normally the same as the module name, but can be overridden with PRODUCT_PACKAGE_NAME_OVERRIDES.
+	installApkName string
 }
 
 func (a *AndroidApp) ExportedProguardFlagFiles() android.Paths {
@@ -215,11 +218,11 @@
 		// framework-res.apk is installed as system/framework/framework-res.apk
 		installDir = "framework"
 	} else if Bool(a.appProperties.Privileged) {
-		installDir = filepath.Join("priv-app", ctx.ModuleName())
+		installDir = filepath.Join("priv-app", a.installApkName)
 	} else {
-		installDir = filepath.Join("app", ctx.ModuleName())
+		installDir = filepath.Join("app", a.installApkName)
 	}
-	a.dexpreopter.installPath = android.PathForModuleInstall(ctx, installDir, ctx.ModuleName()+".apk")
+	a.dexpreopter.installPath = android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
 
 	if ctx.ModuleName() != "framework-res" {
 		a.Module.compile(ctx, a.aaptSrcJar)
@@ -276,6 +279,9 @@
 }
 
 func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
+	// Check if the install APK name needs to be overridden.
+	a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(ctx.ModuleName())
+
 	// Process all building blocks, from AAPT to certificates.
 	a.aaptBuildActions(ctx)
 
@@ -307,9 +313,9 @@
 		// framework-res.apk is installed as system/framework/framework-res.apk
 		ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), ctx.ModuleName()+".apk", a.outputFile)
 	} else if Bool(a.appProperties.Privileged) {
-		ctx.InstallFile(android.PathForModuleInstall(ctx, "priv-app", ctx.ModuleName()), ctx.ModuleName()+".apk", a.outputFile)
+		ctx.InstallFile(android.PathForModuleInstall(ctx, "priv-app", a.installApkName), a.installApkName+".apk", a.outputFile)
 	} else {
-		ctx.InstallFile(android.PathForModuleInstall(ctx, "app", ctx.ModuleName()), ctx.ModuleName()+".apk", a.outputFile)
+		ctx.InstallFile(android.PathForModuleInstall(ctx, "app", a.installApkName), a.installApkName+".apk", a.outputFile)
 	}
 }
 
diff --git a/java/app_test.go b/java/app_test.go
index 9d7ed0a..7e06dba 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -530,3 +530,66 @@
 		})
 	}
 }
+
+func TestPackageNameOverride(t *testing.T) {
+	testCases := []struct {
+		name                string
+		bp                  string
+		packageNameOverride string
+		expected            []string
+	}{
+		{
+			name: "default",
+			bp: `
+				android_app {
+					name: "foo",
+					srcs: ["a.java"],
+				}
+			`,
+			packageNameOverride: "",
+			expected: []string{
+				buildDir + "/.intermediates/foo/android_common/foo.apk",
+				buildDir + "/target/product/test_device/system/app/foo/foo.apk",
+			},
+		},
+		{
+			name: "overridden",
+			bp: `
+				android_app {
+					name: "foo",
+					srcs: ["a.java"],
+				}
+			`,
+			packageNameOverride: "foo:bar",
+			expected: []string{
+				// The package apk should be still be the original name for test dependencies.
+				buildDir + "/.intermediates/foo/android_common/foo.apk",
+				buildDir + "/target/product/test_device/system/app/bar/bar.apk",
+			},
+		},
+	}
+
+	for _, test := range testCases {
+		t.Run(test.name, func(t *testing.T) {
+			config := testConfig(nil)
+			if test.packageNameOverride != "" {
+				config.TestProductVariables.PackageNameOverrides = []string{test.packageNameOverride}
+			}
+			ctx := testAppContext(config, test.bp, nil)
+
+			run(t, ctx, config)
+			foo := ctx.ModuleForTests("foo", "android_common")
+
+			outputs := foo.AllOutputs()
+			outputMap := make(map[string]bool)
+			for _, o := range outputs {
+				outputMap[o] = true
+			}
+			for _, e := range test.expected {
+				if _, exist := outputMap[e]; !exist {
+					t.Errorf("Can't find %q in output files.\nAll outputs:%v", e, outputs)
+				}
+			}
+		})
+	}
+}
diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
index b50748b..17decd0 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -78,7 +78,6 @@
 	"bash":      Allowed,
 	"bc":        Allowed,
 	"bzip2":     Allowed,
-	"cp":        Allowed,
 	"date":      Allowed,
 	"dd":        Allowed,
 	"diff":      Allowed,
@@ -132,6 +131,7 @@
 	"cat":       Toybox,
 	"chmod":     Toybox,
 	"cmp":       Toybox,
+	"cp":        Toybox,
 	"comm":      Toybox,
 	"cut":       Toybox,
 	"dirname":   Toybox,