blob: 061d9d3483c4b784de05d62fa7c4c3039bd4ef09 [file] [log] [blame]
Jaewoong Jungf9b44652020-12-21 12:29:12 -08001// Copyright 2020 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
17import (
18 "reflect"
19 "strings"
20 "testing"
21
22 "android/soong/android"
Lukacs T. Berki7690c092021-02-26 14:27:36 +010023 "android/soong/shared"
Jaewoong Jungf9b44652020-12-21 12:29:12 -080024)
25
26func TestRuntimeResourceOverlay(t *testing.T) {
27 fs := map[string][]byte{
28 "baz/res/res/values/strings.xml": nil,
29 "bar/res/res/values/strings.xml": nil,
30 }
31 bp := `
32 runtime_resource_overlay {
33 name: "foo",
34 certificate: "platform",
35 lineage: "lineage.bin",
36 product_specific: true,
37 static_libs: ["bar"],
38 resource_libs: ["baz"],
39 aaptflags: ["--keep-raw-values"],
40 }
41
42 runtime_resource_overlay {
43 name: "foo_themed",
44 certificate: "platform",
45 product_specific: true,
46 theme: "faza",
47 overrides: ["foo"],
48 }
49
50 android_library {
51 name: "bar",
52 resource_dirs: ["bar/res"],
53 }
54
55 android_app {
56 name: "baz",
57 sdk_version: "current",
58 resource_dirs: ["baz/res"],
59 }
60 `
61 config := testAppConfig(nil, bp, fs)
62 ctx := testContext(config)
63 run(t, ctx, config)
64
65 m := ctx.ModuleForTests("foo", "android_common")
66
67 // Check AAPT2 link flags.
68 aapt2Flags := m.Output("package-res.apk").Args["flags"]
69 expectedFlags := []string{"--keep-raw-values", "--no-resource-deduping", "--no-resource-removal"}
70 absentFlags := android.RemoveListFromList(expectedFlags, strings.Split(aapt2Flags, " "))
71 if len(absentFlags) > 0 {
72 t.Errorf("expected values, %q are missing in aapt2 link flags, %q", absentFlags, aapt2Flags)
73 }
74
75 // Check overlay.list output for static_libs dependency.
76 overlayList := m.Output("aapt2/overlay.list").Inputs.Strings()
77 staticLibPackage := buildDir + "/.intermediates/bar/android_common/package-res.apk"
78 if !inList(staticLibPackage, overlayList) {
79 t.Errorf("Stactic lib res package %q missing in overlay list: %q", staticLibPackage, overlayList)
80 }
81
82 // Check AAPT2 link flags for resource_libs dependency.
83 resourceLibFlag := "-I " + buildDir + "/.intermediates/baz/android_common/package-res.apk"
84 if !strings.Contains(aapt2Flags, resourceLibFlag) {
85 t.Errorf("Resource lib flag %q missing in aapt2 link flags: %q", resourceLibFlag, aapt2Flags)
86 }
87
88 // Check cert signing flag.
89 signedApk := m.Output("signed/foo.apk")
90 lineageFlag := signedApk.Args["flags"]
91 expectedLineageFlag := "--lineage lineage.bin"
92 if expectedLineageFlag != lineageFlag {
93 t.Errorf("Incorrect signing lineage flags, expected: %q, got: %q", expectedLineageFlag, lineageFlag)
94 }
95 signingFlag := signedApk.Args["certificates"]
96 expected := "build/make/target/product/security/platform.x509.pem build/make/target/product/security/platform.pk8"
97 if expected != signingFlag {
98 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
99 }
Colin Crossaa255532020-07-03 13:18:24 -0700100 androidMkEntries := android.AndroidMkEntriesForTest(t, ctx, m.Module())[0]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800101 path := androidMkEntries.EntryMap["LOCAL_CERTIFICATE"]
102 expectedPath := []string{"build/make/target/product/security/platform.x509.pem"}
103 if !reflect.DeepEqual(path, expectedPath) {
104 t.Errorf("Unexpected LOCAL_CERTIFICATE value: %v, expected: %v", path, expectedPath)
105 }
106
107 // Check device location.
108 path = androidMkEntries.EntryMap["LOCAL_MODULE_PATH"]
Lukacs T. Berki7690c092021-02-26 14:27:36 +0100109 expectedPath = []string{shared.JoinPath(buildDir, "../target/product/test_device/product/overlay")}
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800110 if !reflect.DeepEqual(path, expectedPath) {
111 t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath)
112 }
113
114 // A themed module has a different device location
115 m = ctx.ModuleForTests("foo_themed", "android_common")
Colin Crossaa255532020-07-03 13:18:24 -0700116 androidMkEntries = android.AndroidMkEntriesForTest(t, ctx, m.Module())[0]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800117 path = androidMkEntries.EntryMap["LOCAL_MODULE_PATH"]
Lukacs T. Berki7690c092021-02-26 14:27:36 +0100118 expectedPath = []string{shared.JoinPath(buildDir, "../target/product/test_device/product/overlay/faza")}
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800119 if !reflect.DeepEqual(path, expectedPath) {
120 t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath)
121 }
122
123 overrides := androidMkEntries.EntryMap["LOCAL_OVERRIDES_PACKAGES"]
124 expectedOverrides := []string{"foo"}
125 if !reflect.DeepEqual(overrides, expectedOverrides) {
126 t.Errorf("Unexpected LOCAL_OVERRIDES_PACKAGES value: %v, expected: %v", overrides, expectedOverrides)
127 }
128}
129
130func TestRuntimeResourceOverlay_JavaDefaults(t *testing.T) {
Colin Crossaa255532020-07-03 13:18:24 -0700131 ctx, _ := testJava(t, `
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800132 java_defaults {
133 name: "rro_defaults",
134 theme: "default_theme",
135 product_specific: true,
136 aaptflags: ["--keep-raw-values"],
137 }
138
139 runtime_resource_overlay {
140 name: "foo_with_defaults",
141 defaults: ["rro_defaults"],
142 }
143
144 runtime_resource_overlay {
145 name: "foo_barebones",
146 }
147 `)
148
149 //
150 // RRO module with defaults
151 //
152 m := ctx.ModuleForTests("foo_with_defaults", "android_common")
153
154 // Check AAPT2 link flags.
155 aapt2Flags := strings.Split(m.Output("package-res.apk").Args["flags"], " ")
156 expectedFlags := []string{"--keep-raw-values", "--no-resource-deduping", "--no-resource-removal"}
157 absentFlags := android.RemoveListFromList(expectedFlags, aapt2Flags)
158 if len(absentFlags) > 0 {
159 t.Errorf("expected values, %q are missing in aapt2 link flags, %q", absentFlags, aapt2Flags)
160 }
161
162 // Check device location.
Colin Crossaa255532020-07-03 13:18:24 -0700163 path := android.AndroidMkEntriesForTest(t, ctx, m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
Lukacs T. Berki7690c092021-02-26 14:27:36 +0100164 expectedPath := []string{shared.JoinPath(buildDir, "../target/product/test_device/product/overlay/default_theme")}
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800165 if !reflect.DeepEqual(path, expectedPath) {
166 t.Errorf("Unexpected LOCAL_MODULE_PATH value: %q, expected: %q", path, expectedPath)
167 }
168
169 //
170 // RRO module without defaults
171 //
172 m = ctx.ModuleForTests("foo_barebones", "android_common")
173
174 // Check AAPT2 link flags.
175 aapt2Flags = strings.Split(m.Output("package-res.apk").Args["flags"], " ")
176 unexpectedFlags := "--keep-raw-values"
177 if inList(unexpectedFlags, aapt2Flags) {
178 t.Errorf("unexpected value, %q is present in aapt2 link flags, %q", unexpectedFlags, aapt2Flags)
179 }
180
181 // Check device location.
Colin Crossaa255532020-07-03 13:18:24 -0700182 path = android.AndroidMkEntriesForTest(t, ctx, m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
Lukacs T. Berki7690c092021-02-26 14:27:36 +0100183 expectedPath = []string{shared.JoinPath(buildDir, "../target/product/test_device/system/overlay")}
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800184 if !reflect.DeepEqual(path, expectedPath) {
185 t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath)
186 }
187}
188
189func TestOverrideRuntimeResourceOverlay(t *testing.T) {
190 ctx, _ := testJava(t, `
191 runtime_resource_overlay {
192 name: "foo_overlay",
193 certificate: "platform",
194 product_specific: true,
195 sdk_version: "current",
196 }
197
198 override_runtime_resource_overlay {
199 name: "bar_overlay",
200 base: "foo_overlay",
201 package_name: "com.android.bar.overlay",
202 target_package_name: "com.android.bar",
203 }
204 `)
205
206 expectedVariants := []struct {
207 moduleName string
208 variantName string
209 apkPath string
210 overrides []string
211 targetVariant string
212 packageFlag string
213 targetPackageFlag string
214 }{
215 {
216 variantName: "android_common",
217 apkPath: "/target/product/test_device/product/overlay/foo_overlay.apk",
218 overrides: nil,
219 targetVariant: "android_common",
220 packageFlag: "",
221 targetPackageFlag: "",
222 },
223 {
224 variantName: "android_common_bar_overlay",
225 apkPath: "/target/product/test_device/product/overlay/bar_overlay.apk",
226 overrides: []string{"foo_overlay"},
227 targetVariant: "android_common_bar",
228 packageFlag: "com.android.bar.overlay",
229 targetPackageFlag: "com.android.bar",
230 },
231 }
232 for _, expected := range expectedVariants {
233 variant := ctx.ModuleForTests("foo_overlay", expected.variantName)
234
235 // Check the final apk name
236 outputs := variant.AllOutputs()
237 expectedApkPath := buildDir + expected.apkPath
238 found := false
239 for _, o := range outputs {
240 if o == expectedApkPath {
241 found = true
242 break
243 }
244 }
245 if !found {
246 t.Errorf("Can't find %q in output files.\nAll outputs:%v", expectedApkPath, outputs)
247 }
248
249 // Check if the overrides field values are correctly aggregated.
250 mod := variant.Module().(*RuntimeResourceOverlay)
251 if !reflect.DeepEqual(expected.overrides, mod.properties.Overrides) {
252 t.Errorf("Incorrect overrides property value, expected: %q, got: %q",
253 expected.overrides, mod.properties.Overrides)
254 }
255
256 // Check aapt2 flags.
257 res := variant.Output("package-res.apk")
258 aapt2Flags := res.Args["flags"]
259 checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
260 checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", "")
261 checkAapt2LinkFlag(t, aapt2Flags, "rename-overlay-target-package", expected.targetPackageFlag)
262 }
263}
264
265func TestEnforceRRO_propagatesToDependencies(t *testing.T) {
266 testCases := []struct {
Jeongik Chacee5ba92021-02-19 12:11:51 +0900267 name string
268 enforceRROTargets []string
269 rroDirs map[string][]string
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800270 }{
271 {
Jeongik Chacee5ba92021-02-19 12:11:51 +0900272 name: "no RRO",
273 enforceRROTargets: nil,
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800274 rroDirs: map[string][]string{
275 "foo": nil,
276 "bar": nil,
277 },
278 },
279 {
Jeongik Chacee5ba92021-02-19 12:11:51 +0900280 name: "enforce RRO on all",
281 enforceRROTargets: []string{"*"},
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800282 rroDirs: map[string][]string{
283 "foo": {"product/vendor/blah/overlay/lib2/res"},
284 "bar": {"product/vendor/blah/overlay/lib2/res"},
285 },
286 },
287 {
Jeongik Chacee5ba92021-02-19 12:11:51 +0900288 name: "enforce RRO on foo",
289 enforceRROTargets: []string{"foo"},
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800290 rroDirs: map[string][]string{
291 "foo": {"product/vendor/blah/overlay/lib2/res"},
292 "bar": {"product/vendor/blah/overlay/lib2/res"},
293 },
294 },
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800295 }
296
297 productResourceOverlays := []string{
298 "product/vendor/blah/overlay",
299 }
300
301 fs := map[string][]byte{
302 "lib2/res/values/strings.xml": nil,
303 "product/vendor/blah/overlay/lib2/res/values/strings.xml": nil,
304 }
305
306 bp := `
307 android_app {
308 name: "foo",
309 sdk_version: "current",
310 resource_dirs: [],
311 static_libs: ["lib"],
312 }
313
314 android_app {
315 name: "bar",
316 sdk_version: "current",
317 resource_dirs: [],
318 static_libs: ["lib"],
319 }
320
321 android_library {
322 name: "lib",
323 sdk_version: "current",
324 resource_dirs: [],
325 static_libs: ["lib2"],
326 }
327
328 android_library {
329 name: "lib2",
330 sdk_version: "current",
331 resource_dirs: ["lib2/res"],
332 }
333 `
334
335 for _, testCase := range testCases {
336 t.Run(testCase.name, func(t *testing.T) {
337 config := testAppConfig(nil, bp, fs)
338 config.TestProductVariables.ProductResourceOverlays = productResourceOverlays
339 if testCase.enforceRROTargets != nil {
340 config.TestProductVariables.EnforceRROTargets = testCase.enforceRROTargets
341 }
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800342
343 ctx := testContext(config)
344 run(t, ctx, config)
345
346 modules := []string{"foo", "bar"}
347 for _, moduleName := range modules {
348 module := ctx.ModuleForTests(moduleName, "android_common")
Colin Crossaa255532020-07-03 13:18:24 -0700349 mkEntries := android.AndroidMkEntriesForTest(t, ctx, module.Module())[0]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800350 actualRRODirs := mkEntries.EntryMap["LOCAL_SOONG_PRODUCT_RRO_DIRS"]
351 if !reflect.DeepEqual(actualRRODirs, testCase.rroDirs[moduleName]) {
352 t.Errorf("exected %s LOCAL_SOONG_PRODUCT_RRO_DIRS entry: %v\ngot:%q",
353 moduleName, testCase.rroDirs[moduleName], actualRRODirs)
354 }
355 }
356 })
357 }
358}