Add a prod var to override package names.
Currently only java/app.go is affected by package name overrides. When
the var is used, the corresponding module's install APK name is changed
to the overriding name.
Bug: 122957760
Test: app_test.go + TreeHugger
Change-Id: Ie522da3d7280970d740d779cf2694560feae6180
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/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)
+ }
+ }
+ })
+ }
+}