diff --git a/java/app.go b/java/app.go index 4f4a8d375..bddfd8fa1 100755 --- a/java/app.go +++ b/java/app.go @@ -45,6 +45,7 @@ func RegisterAppBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory) ctx.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory) ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory) + ctx.RegisterModuleType("override_runtime_resource_overlay", OverrideRuntimeResourceOverlayModuleFactory) ctx.RegisterModuleType("android_app_import", AndroidAppImportFactory) ctx.RegisterModuleType("android_test_import", AndroidTestImportFactory) ctx.RegisterModuleType("runtime_resource_overlay", RuntimeResourceOverlayFactory) @@ -131,6 +132,15 @@ type overridableAppProperties struct { Logging_parent *string } +// runtime_resource_overlay properties that can be overridden by override_runtime_resource_overlay +type OverridableRuntimeResourceOverlayProperties struct { + // the package name of this app. The package name in the manifest file is used if one was not given. + Package_name *string + + // the target package name of this overlay app. The target package name in the manifest file is used if one was not given. + Target_package_name *string +} + type AndroidApp struct { Library aapt @@ -988,6 +998,27 @@ func OverrideAndroidTestModuleFactory() android.Module { return m } +type OverrideRuntimeResourceOverlay struct { + android.ModuleBase + android.OverrideModuleBase +} + +func (i *OverrideRuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleContext) { + // All the overrides happen in the base module. + // TODO(jungjw): Check the base module type. +} + +// override_runtime_resource_overlay is used to create a module based on another +// runtime_resource_overlay module by overriding some of its properties. +func OverrideRuntimeResourceOverlayModuleFactory() android.Module { + m := &OverrideRuntimeResourceOverlay{} + m.AddProperties(&OverridableRuntimeResourceOverlayProperties{}) + + android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon) + android.InitOverrideModule(m) + return m +} + type AndroidAppImport struct { android.ModuleBase android.DefaultableModuleBase @@ -1383,9 +1414,11 @@ func AndroidTestImportFactory() android.Module { type RuntimeResourceOverlay struct { android.ModuleBase android.DefaultableModuleBase + android.OverridableModuleBase aapt - properties RuntimeResourceOverlayProperties + properties RuntimeResourceOverlayProperties + overridableProperties OverridableRuntimeResourceOverlayProperties certificate Certificate @@ -1452,7 +1485,21 @@ func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleC // Compile and link resources r.aapt.hasNoCode = true // Do not remove resources without default values nor dedupe resource configurations with the same value - r.aapt.buildActions(ctx, r, "--no-resource-deduping", "--no-resource-removal") + aaptLinkFlags := []string{"--no-resource-deduping", "--no-resource-removal"} + // Allow the override of "package name" and "overlay target package name" + manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName()) + if overridden || r.overridableProperties.Package_name != nil { + // The product override variable has a priority over the package_name property. + if !overridden { + manifestPackageName = *r.overridableProperties.Package_name + } + aaptLinkFlags = append(aaptLinkFlags, "--rename-manifest-package "+manifestPackageName) + } + if r.overridableProperties.Target_package_name != nil { + aaptLinkFlags = append(aaptLinkFlags, + "--rename-overlay-target-package "+*r.overridableProperties.Target_package_name) + } + r.aapt.buildActions(ctx, r, aaptLinkFlags...) // Sign the built package _, certificates := collectAppDeps(ctx, false, false) @@ -1503,10 +1550,12 @@ func RuntimeResourceOverlayFactory() android.Module { module := &RuntimeResourceOverlay{} module.AddProperties( &module.properties, - &module.aaptProperties) - - InitJavaModule(module, android.DeviceSupported) + &module.aaptProperties, + &module.overridableProperties) + android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) + android.InitDefaultableModule(module) + android.InitOverridableModule(module, &module.properties.Overrides) return module } diff --git a/java/app_test.go b/java/app_test.go index c1a0cdd44..aae73ca63 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -2566,3 +2566,78 @@ func TestRuntimeResourceOverlay(t *testing.T) { t.Errorf("Unexpected LOCAL_OVERRIDES_PACKAGES value: %v, expected: %v", overrides, expectedOverrides) } } + +func TestOverrideRuntimeResourceOverlay(t *testing.T) { + ctx, _ := testJava(t, ` + runtime_resource_overlay { + name: "foo_overlay", + certificate: "platform", + product_specific: true, + sdk_version: "current", + } + + override_runtime_resource_overlay { + name: "bar_overlay", + base: "foo_overlay", + package_name: "com.android.bar.overlay", + target_package_name: "com.android.bar", + } + `) + + expectedVariants := []struct { + moduleName string + variantName string + apkPath string + overrides []string + targetVariant string + packageFlag string + targetPackageFlag string + }{ + { + variantName: "android_common", + apkPath: "/target/product/test_device/product/overlay/foo_overlay.apk", + overrides: nil, + targetVariant: "android_common", + packageFlag: "", + targetPackageFlag: "", + }, + { + variantName: "android_common_bar_overlay", + apkPath: "/target/product/test_device/product/overlay/bar_overlay.apk", + overrides: []string{"foo_overlay"}, + targetVariant: "android_common_bar", + packageFlag: "com.android.bar.overlay", + targetPackageFlag: "com.android.bar", + }, + } + for _, expected := range expectedVariants { + variant := ctx.ModuleForTests("foo_overlay", expected.variantName) + + // Check the final apk name + outputs := variant.AllOutputs() + expectedApkPath := buildDir + expected.apkPath + found := false + for _, o := range outputs { + if o == expectedApkPath { + found = true + break + } + } + if !found { + t.Errorf("Can't find %q in output files.\nAll outputs:%v", expectedApkPath, outputs) + } + + // Check if the overrides field values are correctly aggregated. + mod := variant.Module().(*RuntimeResourceOverlay) + if !reflect.DeepEqual(expected.overrides, mod.properties.Overrides) { + t.Errorf("Incorrect overrides property value, expected: %q, got: %q", + expected.overrides, mod.properties.Overrides) + } + + // Check aapt2 flags. + res := variant.Output("package-res.apk") + aapt2Flags := res.Args["flags"] + checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag) + checkAapt2LinkFlag(t, aapt2Flags, "rename-overlay-target-package", expected.targetPackageFlag) + } +}