Fix resource overlay order for static libraries
If a static library has static library dependencies then all resources
need to be moved to an overlay to maintain the correct ordering so
that a static library resource overlays the same resource in a
dependency.
Also fix the ordering of transitive static dependencies, a direct
dependency should override a transitive dependency.
Expand TestEnforceRRO to include a transitive static library and
verify both the direct resources and overlays, and rename it to
TestAndroidResources.
Bug: 124108931
Test: TestAndroidResources
Change-Id: I355f835a2ffb728af28aa208d951794c609e7409
diff --git a/java/app_test.go b/java/app_test.go
index 103f24b..317c752 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -164,11 +164,12 @@
}
}
-func TestEnforceRRO(t *testing.T) {
+func TestAndroidResources(t *testing.T) {
testCases := []struct {
name string
enforceRROTargets []string
enforceRROExcludedOverlays []string
+ resourceFiles map[string][]string
overlayFiles map[string][]string
rroDirs map[string][]string
}{
@@ -176,17 +177,29 @@
name: "no RRO",
enforceRROTargets: nil,
enforceRROExcludedOverlays: nil,
+ resourceFiles: map[string][]string{
+ "foo": nil,
+ "bar": {"bar/res/res/values/strings.xml"},
+ "lib": nil,
+ "lib2": {"lib2/res/res/values/strings.xml"},
+ },
overlayFiles: map[string][]string{
- "foo": []string{
+ "foo": {
+ buildDir + "/.intermediates/lib2/android_common/package-res.apk",
buildDir + "/.intermediates/lib/android_common/package-res.apk",
"foo/res/res/values/strings.xml",
"device/vendor/blah/static_overlay/foo/res/values/strings.xml",
"device/vendor/blah/overlay/foo/res/values/strings.xml",
},
- "bar": []string{
+ "bar": {
"device/vendor/blah/static_overlay/bar/res/values/strings.xml",
"device/vendor/blah/overlay/bar/res/values/strings.xml",
},
+ "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": nil,
@@ -197,25 +210,38 @@
name: "enforce RRO on foo",
enforceRROTargets: []string{"foo"},
enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
+ resourceFiles: map[string][]string{
+ "foo": nil,
+ "bar": {"bar/res/res/values/strings.xml"},
+ "lib": nil,
+ "lib2": {"lib2/res/res/values/strings.xml"},
+ },
overlayFiles: map[string][]string{
- "foo": []string{
+ "foo": {
+ buildDir + "/.intermediates/lib2/android_common/package-res.apk",
buildDir + "/.intermediates/lib/android_common/package-res.apk",
"foo/res/res/values/strings.xml",
"device/vendor/blah/static_overlay/foo/res/values/strings.xml",
},
- "bar": []string{
+ "bar": {
"device/vendor/blah/static_overlay/bar/res/values/strings.xml",
"device/vendor/blah/overlay/bar/res/values/strings.xml",
},
+ "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": []string{
+ "foo": {
"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",
},
"bar": nil,
+ "lib": nil,
},
},
{
@@ -226,20 +252,32 @@
"device/vendor/blah/static_overlay/foo",
"device/vendor/blah/static_overlay/bar/res",
},
+ resourceFiles: map[string][]string{
+ "foo": nil,
+ "bar": {"bar/res/res/values/strings.xml"},
+ "lib": nil,
+ "lib2": {"lib2/res/res/values/strings.xml"},
+ },
overlayFiles: map[string][]string{
- "foo": []string{
+ "foo": {
+ buildDir + "/.intermediates/lib2/android_common/package-res.apk",
buildDir + "/.intermediates/lib/android_common/package-res.apk",
"foo/res/res/values/strings.xml",
"device/vendor/blah/static_overlay/foo/res/values/strings.xml",
},
- "bar": []string{"device/vendor/blah/static_overlay/bar/res/values/strings.xml"},
+ "bar": {"device/vendor/blah/static_overlay/bar/res/values/strings.xml"},
+ "lib": {
+ buildDir + "/.intermediates/lib2/android_common/package-res.apk",
+ "lib/res/res/values/strings.xml",
+ },
},
rroDirs: map[string][]string{
- "foo": []string{
+ "foo": {
"device/vendor/blah/overlay/foo/res",
"device/vendor/blah/overlay/lib/res",
},
- "bar": []string{"device/vendor/blah/overlay/bar/res"},
+ "bar": {"device/vendor/blah/overlay/bar/res"},
+ "lib": {"device/vendor/blah/overlay/lib/res"},
},
},
}
@@ -254,6 +292,7 @@
"foo/res/res/values/strings.xml": nil,
"bar/res/res/values/strings.xml": nil,
"lib/res/res/values/strings.xml": nil,
+ "lib2/res/res/values/strings.xml": nil,
"device/vendor/blah/overlay/foo/res/values/strings.xml": nil,
"device/vendor/blah/overlay/bar/res/values/strings.xml": nil,
"device/vendor/blah/overlay/lib/res/values/strings.xml": nil,
@@ -277,6 +316,12 @@
android_library {
name: "lib",
resource_dirs: ["lib/res"],
+ static_libs: ["lib2"],
+ }
+
+ android_library {
+ name: "lib2",
+ resource_dirs: ["lib2/res"],
}
`
@@ -294,40 +339,52 @@
ctx := testAppContext(config, bp, fs)
run(t, ctx, config)
- getOverlays := func(moduleName string) ([]string, []string) {
- module := ctx.ModuleForTests(moduleName, "android_common")
- overlayFile := module.MaybeOutput("aapt2/overlay.list")
- var overlayFiles []string
- if overlayFile.Rule != nil {
- for _, o := range overlayFile.Inputs.Strings() {
- overlayOutput := module.MaybeOutput(o)
- if overlayOutput.Rule != nil {
- // If the overlay is compiled as part of this module (i.e. a .arsc.flat file),
- // verify the inputs to the .arsc.flat rule.
- overlayFiles = append(overlayFiles, overlayOutput.Inputs.Strings()...)
- } else {
- // Otherwise, verify the full path to the output of the other module
- overlayFiles = append(overlayFiles, o)
- }
+ resourceListToFiles := func(module android.TestingModule, list []string) (files []string) {
+ for _, o := range list {
+ res := module.MaybeOutput(o)
+ if res.Rule != nil {
+ // If the overlay is compiled as part of this module (i.e. a .arsc.flat file),
+ // verify the inputs to the .arsc.flat rule.
+ files = append(files, res.Inputs.Strings()...)
+ } else {
+ // Otherwise, verify the full path to the output of the other module
+ files = append(files, o)
}
}
-
- rroDirs := module.Module().(*AndroidApp).rroDirs.Strings()
-
- return overlayFiles, rroDirs
+ return files
}
- apps := []string{"foo", "bar"}
- for _, app := range apps {
- overlayFiles, rroDirs := getOverlays(app)
-
- if !reflect.DeepEqual(overlayFiles, testCase.overlayFiles[app]) {
- t.Errorf("expected %s overlay files:\n %#v\n got:\n %#v",
- app, testCase.overlayFiles[app], overlayFiles)
+ getResources := func(moduleName string) (resourceFiles, overlayFiles, rroDirs []string) {
+ module := ctx.ModuleForTests(moduleName, "android_common")
+ resourceList := module.MaybeOutput("aapt2/res.list")
+ if resourceList.Rule != nil {
+ resourceFiles = resourceListToFiles(module, resourceList.Inputs.Strings())
}
- if !reflect.DeepEqual(rroDirs, testCase.rroDirs[app]) {
+ overlayList := module.MaybeOutput("aapt2/overlay.list")
+ if overlayList.Rule != nil {
+ overlayFiles = resourceListToFiles(module, overlayList.Inputs.Strings())
+ }
+
+ rroDirs = module.Module().(AndroidLibraryDependency).ExportedRRODirs().Strings()
+
+ return resourceFiles, overlayFiles, rroDirs
+ }
+
+ modules := []string{"foo", "bar", "lib", "lib2"}
+ for _, module := range modules {
+ resourceFiles, overlayFiles, rroDirs := getResources(module)
+
+ if !reflect.DeepEqual(resourceFiles, testCase.resourceFiles[module]) {
+ t.Errorf("expected %s resource files:\n %#v\n got:\n %#v",
+ module, testCase.resourceFiles[module], resourceFiles)
+ }
+ if !reflect.DeepEqual(overlayFiles, testCase.overlayFiles[module]) {
+ t.Errorf("expected %s overlay files:\n %#v\n got:\n %#v",
+ module, testCase.overlayFiles[module], overlayFiles)
+ }
+ if !reflect.DeepEqual(rroDirs, testCase.rroDirs[module]) {
t.Errorf("expected %s rroDirs: %#v\n got:\n %#v",
- app, testCase.rroDirs[app], rroDirs)
+ module, testCase.rroDirs[module], rroDirs)
}
}
})