Apply PRODUCT_ENFORCE_RRO_TARGETS to dependencies.
With this change, users don't need to figure out which libraries actually hold the resources to be overlaid when targetting apps with a core lib dependency (e.g. Settings, SystemUI). Fixes: 169898727 Test: app_test.go Change-Id: I3c3b9dc0a377b1828db1199858a73d080a173205
This commit is contained in:
parent
3c72ce8696
commit
c779cd403f
|
@ -916,6 +916,10 @@ func (c *config) EnforceRROForModule(name string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (c *config) EnforceRROExemptedForModule(name string) bool {
|
||||
return InList(name, c.productVariables.EnforceRROExemptedTargets)
|
||||
}
|
||||
|
||||
func (c *config) EnforceRROExcludedOverlay(path string) bool {
|
||||
excluded := c.productVariables.EnforceRROExcludedOverlays
|
||||
if len(excluded) > 0 {
|
||||
|
|
59
java/aar.go
59
java/aar.go
|
@ -34,10 +34,16 @@ type AndroidLibraryDependency interface {
|
|||
ExportedStaticPackages() android.Paths
|
||||
ExportedManifests() android.Paths
|
||||
ExportedAssets() android.OptionalPath
|
||||
SetRROEnforcedForDependent(enforce bool)
|
||||
IsRROEnforced(ctx android.BaseModuleContext) bool
|
||||
}
|
||||
|
||||
func init() {
|
||||
RegisterAARBuildComponents(android.InitRegistrationContext)
|
||||
|
||||
android.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
|
||||
ctx.TopDown("propagate_rro_enforcement", propagateRROEnforcementMutator).Parallel()
|
||||
})
|
||||
}
|
||||
|
||||
func RegisterAARBuildComponents(ctx android.RegistrationContext) {
|
||||
|
@ -82,6 +88,9 @@ type aaptProperties struct {
|
|||
|
||||
// do not include AndroidManifest from dependent libraries
|
||||
Dont_merge_manifests *bool
|
||||
|
||||
// true if RRO is enforced for any of the dependent modules
|
||||
RROEnforcedForDependent bool `blueprint:"mutated"`
|
||||
}
|
||||
|
||||
type aapt struct {
|
||||
|
@ -117,6 +126,18 @@ type split struct {
|
|||
path android.Path
|
||||
}
|
||||
|
||||
// Propagate RRO enforcement flag to static lib dependencies transitively.
|
||||
func propagateRROEnforcementMutator(ctx android.TopDownMutatorContext) {
|
||||
m := ctx.Module()
|
||||
if d, ok := m.(AndroidLibraryDependency); ok && d.IsRROEnforced(ctx) {
|
||||
ctx.VisitDirectDepsWithTag(staticLibTag, func(d android.Module) {
|
||||
if a, ok := d.(AndroidLibraryDependency); ok {
|
||||
a.SetRROEnforcedForDependent(true)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (a *aapt) ExportPackage() android.Path {
|
||||
return a.exportPackage
|
||||
}
|
||||
|
@ -133,6 +154,17 @@ func (a *aapt) ExportedAssets() android.OptionalPath {
|
|||
return a.assetPackage
|
||||
}
|
||||
|
||||
func (a *aapt) SetRROEnforcedForDependent(enforce bool) {
|
||||
a.aaptProperties.RROEnforcedForDependent = enforce
|
||||
}
|
||||
|
||||
func (a *aapt) IsRROEnforced(ctx android.BaseModuleContext) bool {
|
||||
// True if RRO is enforced for this module or...
|
||||
return ctx.Config().EnforceRROForModule(ctx.ModuleName()) ||
|
||||
// if RRO is enforced for any of its dependents, and this module is not exempted.
|
||||
(a.aaptProperties.RROEnforcedForDependent && !ctx.Config().EnforceRROExemptedForModule(ctx.ModuleName()))
|
||||
}
|
||||
|
||||
func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext sdkContext,
|
||||
manifestPath android.Path) (compileFlags, linkFlags []string, linkDeps android.Paths,
|
||||
resDirs, overlayDirs []globbedResourceDir, rroDirs []rroDir, resZips android.Paths) {
|
||||
|
@ -156,7 +188,7 @@ func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext sdkContext,
|
|||
dir: dir,
|
||||
files: androidResourceGlob(ctx, dir),
|
||||
})
|
||||
resOverlayDirs, resRRODirs := overlayResourceGlob(ctx, dir)
|
||||
resOverlayDirs, resRRODirs := overlayResourceGlob(ctx, a, dir)
|
||||
overlayDirs = append(overlayDirs, resOverlayDirs...)
|
||||
rroDirs = append(rroDirs, resRRODirs...)
|
||||
}
|
||||
|
@ -412,14 +444,16 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStati
|
|||
assets = append(assets, aarDep.ExportedAssets().Path())
|
||||
}
|
||||
|
||||
outer:
|
||||
for _, d := range aarDep.ExportedRRODirs() {
|
||||
for _, e := range staticRRODirs {
|
||||
if d.path == e.path {
|
||||
continue outer
|
||||
if !ctx.Config().EnforceRROExemptedForModule(ctx.ModuleName()) {
|
||||
outer:
|
||||
for _, d := range aarDep.ExportedRRODirs() {
|
||||
for _, e := range staticRRODirs {
|
||||
if d.path == e.path {
|
||||
continue outer
|
||||
}
|
||||
}
|
||||
staticRRODirs = append(staticRRODirs, d)
|
||||
}
|
||||
staticRRODirs = append(staticRRODirs, d)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -621,6 +655,17 @@ func (a *AARImport) ExportedAssets() android.OptionalPath {
|
|||
return android.OptionalPath{}
|
||||
}
|
||||
|
||||
// RRO enforcement is not available on aar_import since its RRO dirs are not
|
||||
// exported.
|
||||
func (a *AARImport) SetRROEnforcedForDependent(enforce bool) {
|
||||
}
|
||||
|
||||
// RRO enforcement is not available on aar_import since its RRO dirs are not
|
||||
// exported.
|
||||
func (a *AARImport) IsRROEnforced(ctx android.BaseModuleContext) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (a *AARImport) Prebuilt() *android.Prebuilt {
|
||||
return &a.prebuilt
|
||||
}
|
||||
|
|
|
@ -66,13 +66,13 @@ type globbedResourceDir struct {
|
|||
files android.Paths
|
||||
}
|
||||
|
||||
func overlayResourceGlob(ctx android.ModuleContext, dir android.Path) (res []globbedResourceDir,
|
||||
func overlayResourceGlob(ctx android.ModuleContext, a *aapt, dir android.Path) (res []globbedResourceDir,
|
||||
rroDirs []rroDir) {
|
||||
|
||||
overlayData := ctx.Config().Get(overlayDataKey).([]overlayGlobResult)
|
||||
|
||||
// Runtime resource overlays (RRO) may be turned on by the product config for some modules
|
||||
rroEnabled := ctx.Config().EnforceRROForModule(ctx.ModuleName())
|
||||
rroEnabled := a.IsRROEnforced(ctx)
|
||||
|
||||
for _, data := range overlayData {
|
||||
files := data.paths.PathsInDirectory(filepath.Join(data.dir, dir.String()))
|
||||
|
|
117
java/app_test.go
117
java/app_test.go
|
@ -848,19 +848,17 @@ func TestAndroidResources(t *testing.T) {
|
|||
"lib": {
|
||||
buildDir + "/.intermediates/lib2/android_common/package-res.apk",
|
||||
"lib/res/res/values/strings.xml",
|
||||
"device/vendor/blah/overlay/lib/res/values/strings.xml",
|
||||
},
|
||||
},
|
||||
|
||||
rroDirs: map[string][]string{
|
||||
"foo": {
|
||||
"device:device/vendor/blah/overlay/foo/res",
|
||||
// Enforce RRO on "foo" could imply RRO on static dependencies, but for now it doesn't.
|
||||
// "device/vendor/blah/overlay/lib/res",
|
||||
"product:product/vendor/blah/overlay/foo/res",
|
||||
"device:device/vendor/blah/overlay/lib/res",
|
||||
},
|
||||
"bar": nil,
|
||||
"lib": nil,
|
||||
"lib": {"device:device/vendor/blah/overlay/lib/res"},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -3401,3 +3399,114 @@ func TestOverrideRuntimeResourceOverlay(t *testing.T) {
|
|||
checkAapt2LinkFlag(t, aapt2Flags, "rename-overlay-target-package", expected.targetPackageFlag)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnforceRRO_propagatesToDependencies(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
enforceRROTargets []string
|
||||
enforceRROExemptTargets []string
|
||||
rroDirs map[string][]string
|
||||
}{
|
||||
{
|
||||
name: "no RRO",
|
||||
enforceRROTargets: nil,
|
||||
enforceRROExemptTargets: nil,
|
||||
rroDirs: map[string][]string{
|
||||
"foo": nil,
|
||||
"bar": nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "enforce RRO on all",
|
||||
enforceRROTargets: []string{"*"},
|
||||
enforceRROExemptTargets: nil,
|
||||
rroDirs: map[string][]string{
|
||||
"foo": {"product/vendor/blah/overlay/lib2/res"},
|
||||
"bar": {"product/vendor/blah/overlay/lib2/res"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "enforce RRO on foo",
|
||||
enforceRROTargets: []string{"foo"},
|
||||
enforceRROExemptTargets: nil,
|
||||
rroDirs: map[string][]string{
|
||||
"foo": {"product/vendor/blah/overlay/lib2/res"},
|
||||
"bar": {"product/vendor/blah/overlay/lib2/res"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "enforce RRO on foo, bar exempted",
|
||||
enforceRROTargets: []string{"foo"},
|
||||
enforceRROExemptTargets: []string{"bar"},
|
||||
rroDirs: map[string][]string{
|
||||
"foo": {"product/vendor/blah/overlay/lib2/res"},
|
||||
"bar": nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
productResourceOverlays := []string{
|
||||
"product/vendor/blah/overlay",
|
||||
}
|
||||
|
||||
fs := map[string][]byte{
|
||||
"lib2/res/values/strings.xml": nil,
|
||||
"product/vendor/blah/overlay/lib2/res/values/strings.xml": nil,
|
||||
}
|
||||
|
||||
bp := `
|
||||
android_app {
|
||||
name: "foo",
|
||||
sdk_version: "current",
|
||||
resource_dirs: [],
|
||||
static_libs: ["lib"],
|
||||
}
|
||||
|
||||
android_app {
|
||||
name: "bar",
|
||||
sdk_version: "current",
|
||||
resource_dirs: [],
|
||||
static_libs: ["lib"],
|
||||
}
|
||||
|
||||
android_library {
|
||||
name: "lib",
|
||||
sdk_version: "current",
|
||||
resource_dirs: [],
|
||||
static_libs: ["lib2"],
|
||||
}
|
||||
|
||||
android_library {
|
||||
name: "lib2",
|
||||
sdk_version: "current",
|
||||
resource_dirs: ["lib2/res"],
|
||||
}
|
||||
`
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
config := testAppConfig(nil, bp, fs)
|
||||
config.TestProductVariables.ProductResourceOverlays = productResourceOverlays
|
||||
if testCase.enforceRROTargets != nil {
|
||||
config.TestProductVariables.EnforceRROTargets = testCase.enforceRROTargets
|
||||
}
|
||||
if testCase.enforceRROExemptTargets != nil {
|
||||
config.TestProductVariables.EnforceRROExemptedTargets = testCase.enforceRROExemptTargets
|
||||
}
|
||||
|
||||
ctx := testContext()
|
||||
run(t, ctx, config)
|
||||
|
||||
modules := []string{"foo", "bar"}
|
||||
for _, moduleName := range modules {
|
||||
module := ctx.ModuleForTests(moduleName, "android_common")
|
||||
mkEntries := android.AndroidMkEntriesForTest(t, config, "", module.Module())[0]
|
||||
actualRRODirs := mkEntries.EntryMap["LOCAL_SOONG_PRODUCT_RRO_DIRS"]
|
||||
if !reflect.DeepEqual(actualRRODirs, testCase.rroDirs[moduleName]) {
|
||||
t.Errorf("exected %s LOCAL_SOONG_PRODUCT_RRO_DIRS entry: %v\ngot:%q",
|
||||
moduleName, testCase.rroDirs[moduleName], actualRRODirs)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,6 +102,10 @@ func testContext() *android.TestContext {
|
|||
|
||||
dexpreopt.RegisterToolModulesForTest(ctx)
|
||||
|
||||
ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
|
||||
ctx.TopDown("propagate_rro_enforcement", propagateRROEnforcementMutator).Parallel()
|
||||
})
|
||||
|
||||
return ctx
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue