blob: 27abbe4f369f950158b6d1f759cdc0ae223653c2 [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) {
Paul Duffin0342dc92021-03-22 17:31:52 +000027 fs := android.MockFS{
Jaewoong Jungf9b44652020-12-21 12:29:12 -080028 "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 }
Paul Duffin0342dc92021-03-22 17:31:52 +000060 `
Jaewoong Jungf9b44652020-12-21 12:29:12 -080061
Paul Duffin0342dc92021-03-22 17:31:52 +000062 result := android.GroupFixturePreparers(
63 PrepareForTestWithJavaDefaultModules,
64 PrepareForTestWithOverlayBuildComponents,
65 fs.AddToFixture(),
66 ).RunTestWithBp(t, bp)
67
68 m := result.ModuleForTests("foo", "android_common")
Jaewoong Jungf9b44652020-12-21 12:29:12 -080069
70 // Check AAPT2 link flags.
Paul Duffina71a67a2021-03-29 00:42:57 +010071 aapt2Flags := m.Output("package-res.apk").Args["flags"]
Jaewoong Jungf9b44652020-12-21 12:29:12 -080072 expectedFlags := []string{"--keep-raw-values", "--no-resource-deduping", "--no-resource-removal"}
73 absentFlags := android.RemoveListFromList(expectedFlags, strings.Split(aapt2Flags, " "))
74 if len(absentFlags) > 0 {
75 t.Errorf("expected values, %q are missing in aapt2 link flags, %q", absentFlags, aapt2Flags)
76 }
77
78 // Check overlay.list output for static_libs dependency.
Paul Duffin0342dc92021-03-22 17:31:52 +000079 overlayList := android.PathsRelativeToTop(m.Output("aapt2/overlay.list").Inputs)
80 staticLibPackage := "out/soong/.intermediates/bar/android_common/package-res.apk"
Jaewoong Jungf9b44652020-12-21 12:29:12 -080081 if !inList(staticLibPackage, overlayList) {
82 t.Errorf("Stactic lib res package %q missing in overlay list: %q", staticLibPackage, overlayList)
83 }
84
85 // Check AAPT2 link flags for resource_libs dependency.
Paul Duffin0342dc92021-03-22 17:31:52 +000086 resourceLibFlag := "-I " + "out/soong/.intermediates/baz/android_common/package-res.apk"
Jaewoong Jungf9b44652020-12-21 12:29:12 -080087 if !strings.Contains(aapt2Flags, resourceLibFlag) {
88 t.Errorf("Resource lib flag %q missing in aapt2 link flags: %q", resourceLibFlag, aapt2Flags)
89 }
90
91 // Check cert signing flag.
92 signedApk := m.Output("signed/foo.apk")
93 lineageFlag := signedApk.Args["flags"]
94 expectedLineageFlag := "--lineage lineage.bin"
95 if expectedLineageFlag != lineageFlag {
96 t.Errorf("Incorrect signing lineage flags, expected: %q, got: %q", expectedLineageFlag, lineageFlag)
97 }
98 signingFlag := signedApk.Args["certificates"]
99 expected := "build/make/target/product/security/platform.x509.pem build/make/target/product/security/platform.pk8"
100 if expected != signingFlag {
101 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
102 }
Paul Duffin0342dc92021-03-22 17:31:52 +0000103 androidMkEntries := android.AndroidMkEntriesForTest(t, result.TestContext, m.Module())[0]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800104 path := androidMkEntries.EntryMap["LOCAL_CERTIFICATE"]
105 expectedPath := []string{"build/make/target/product/security/platform.x509.pem"}
106 if !reflect.DeepEqual(path, expectedPath) {
107 t.Errorf("Unexpected LOCAL_CERTIFICATE value: %v, expected: %v", path, expectedPath)
108 }
109
110 // Check device location.
111 path = androidMkEntries.EntryMap["LOCAL_MODULE_PATH"]
Paul Duffin0342dc92021-03-22 17:31:52 +0000112 expectedPath = []string{shared.JoinPath("out/target/product/test_device/product/overlay")}
113 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", result.Config, expectedPath, path)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800114
115 // A themed module has a different device location
Paul Duffin0342dc92021-03-22 17:31:52 +0000116 m = result.ModuleForTests("foo_themed", "android_common")
117 androidMkEntries = android.AndroidMkEntriesForTest(t, result.TestContext, m.Module())[0]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800118 path = androidMkEntries.EntryMap["LOCAL_MODULE_PATH"]
Paul Duffin0342dc92021-03-22 17:31:52 +0000119 expectedPath = []string{shared.JoinPath("out/target/product/test_device/product/overlay/faza")}
120 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", result.Config, expectedPath, path)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800121
122 overrides := androidMkEntries.EntryMap["LOCAL_OVERRIDES_PACKAGES"]
123 expectedOverrides := []string{"foo"}
124 if !reflect.DeepEqual(overrides, expectedOverrides) {
125 t.Errorf("Unexpected LOCAL_OVERRIDES_PACKAGES value: %v, expected: %v", overrides, expectedOverrides)
126 }
127}
128
129func TestRuntimeResourceOverlay_JavaDefaults(t *testing.T) {
Paul Duffin0342dc92021-03-22 17:31:52 +0000130 ctx, config := testJava(t, `
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800131 java_defaults {
132 name: "rro_defaults",
133 theme: "default_theme",
134 product_specific: true,
135 aaptflags: ["--keep-raw-values"],
136 }
137
138 runtime_resource_overlay {
139 name: "foo_with_defaults",
140 defaults: ["rro_defaults"],
141 }
142
143 runtime_resource_overlay {
144 name: "foo_barebones",
145 }
146 `)
147
148 //
149 // RRO module with defaults
150 //
151 m := ctx.ModuleForTests("foo_with_defaults", "android_common")
152
153 // Check AAPT2 link flags.
154 aapt2Flags := strings.Split(m.Output("package-res.apk").Args["flags"], " ")
155 expectedFlags := []string{"--keep-raw-values", "--no-resource-deduping", "--no-resource-removal"}
156 absentFlags := android.RemoveListFromList(expectedFlags, aapt2Flags)
157 if len(absentFlags) > 0 {
158 t.Errorf("expected values, %q are missing in aapt2 link flags, %q", absentFlags, aapt2Flags)
159 }
160
161 // Check device location.
Colin Crossaa255532020-07-03 13:18:24 -0700162 path := android.AndroidMkEntriesForTest(t, ctx, m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
Paul Duffin0342dc92021-03-22 17:31:52 +0000163 expectedPath := []string{shared.JoinPath("out/target/product/test_device/product/overlay/default_theme")}
164 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", config, expectedPath, path)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800165
166 //
167 // RRO module without defaults
168 //
169 m = ctx.ModuleForTests("foo_barebones", "android_common")
170
171 // Check AAPT2 link flags.
172 aapt2Flags = strings.Split(m.Output("package-res.apk").Args["flags"], " ")
173 unexpectedFlags := "--keep-raw-values"
174 if inList(unexpectedFlags, aapt2Flags) {
175 t.Errorf("unexpected value, %q is present in aapt2 link flags, %q", unexpectedFlags, aapt2Flags)
176 }
177
178 // Check device location.
Colin Crossaa255532020-07-03 13:18:24 -0700179 path = android.AndroidMkEntriesForTest(t, ctx, m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
Spandan Das5d1b9292021-06-03 19:36:41 +0000180 expectedPath = []string{shared.JoinPath("out/target/product/test_device/product/overlay")}
Paul Duffin0342dc92021-03-22 17:31:52 +0000181 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", config, expectedPath, path)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800182}
183
184func TestOverrideRuntimeResourceOverlay(t *testing.T) {
185 ctx, _ := testJava(t, `
186 runtime_resource_overlay {
187 name: "foo_overlay",
188 certificate: "platform",
189 product_specific: true,
190 sdk_version: "current",
191 }
192
193 override_runtime_resource_overlay {
194 name: "bar_overlay",
195 base: "foo_overlay",
196 package_name: "com.android.bar.overlay",
197 target_package_name: "com.android.bar",
198 }
199 `)
200
201 expectedVariants := []struct {
202 moduleName string
203 variantName string
204 apkPath string
205 overrides []string
206 targetVariant string
207 packageFlag string
208 targetPackageFlag string
209 }{
210 {
211 variantName: "android_common",
Paul Duffin0342dc92021-03-22 17:31:52 +0000212 apkPath: "out/soong/target/product/test_device/product/overlay/foo_overlay.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800213 overrides: nil,
214 targetVariant: "android_common",
215 packageFlag: "",
216 targetPackageFlag: "",
217 },
218 {
219 variantName: "android_common_bar_overlay",
Paul Duffin0342dc92021-03-22 17:31:52 +0000220 apkPath: "out/soong/target/product/test_device/product/overlay/bar_overlay.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800221 overrides: []string{"foo_overlay"},
222 targetVariant: "android_common_bar",
223 packageFlag: "com.android.bar.overlay",
224 targetPackageFlag: "com.android.bar",
225 },
226 }
227 for _, expected := range expectedVariants {
228 variant := ctx.ModuleForTests("foo_overlay", expected.variantName)
229
230 // Check the final apk name
Paul Duffin0342dc92021-03-22 17:31:52 +0000231 variant.Output(expected.apkPath)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800232
233 // Check if the overrides field values are correctly aggregated.
234 mod := variant.Module().(*RuntimeResourceOverlay)
235 if !reflect.DeepEqual(expected.overrides, mod.properties.Overrides) {
236 t.Errorf("Incorrect overrides property value, expected: %q, got: %q",
237 expected.overrides, mod.properties.Overrides)
238 }
239
240 // Check aapt2 flags.
241 res := variant.Output("package-res.apk")
242 aapt2Flags := res.Args["flags"]
243 checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
244 checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", "")
245 checkAapt2LinkFlag(t, aapt2Flags, "rename-overlay-target-package", expected.targetPackageFlag)
246 }
247}
248
249func TestEnforceRRO_propagatesToDependencies(t *testing.T) {
250 testCases := []struct {
Jeongik Chacee5ba92021-02-19 12:11:51 +0900251 name string
252 enforceRROTargets []string
253 rroDirs map[string][]string
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800254 }{
255 {
Jeongik Chacee5ba92021-02-19 12:11:51 +0900256 name: "no RRO",
257 enforceRROTargets: nil,
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800258 rroDirs: map[string][]string{
259 "foo": nil,
260 "bar": nil,
261 },
262 },
263 {
Jeongik Chacee5ba92021-02-19 12:11:51 +0900264 name: "enforce RRO on all",
265 enforceRROTargets: []string{"*"},
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800266 rroDirs: map[string][]string{
267 "foo": {"product/vendor/blah/overlay/lib2/res"},
268 "bar": {"product/vendor/blah/overlay/lib2/res"},
269 },
270 },
271 {
Jeongik Chacee5ba92021-02-19 12:11:51 +0900272 name: "enforce RRO on foo",
273 enforceRROTargets: []string{"foo"},
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800274 rroDirs: map[string][]string{
275 "foo": {"product/vendor/blah/overlay/lib2/res"},
276 "bar": {"product/vendor/blah/overlay/lib2/res"},
277 },
278 },
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800279 }
280
281 productResourceOverlays := []string{
282 "product/vendor/blah/overlay",
283 }
284
Paul Duffin0342dc92021-03-22 17:31:52 +0000285 fs := android.MockFS{
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800286 "lib2/res/values/strings.xml": nil,
287 "product/vendor/blah/overlay/lib2/res/values/strings.xml": nil,
288 }
289
290 bp := `
291 android_app {
292 name: "foo",
293 sdk_version: "current",
294 resource_dirs: [],
295 static_libs: ["lib"],
296 }
297
298 android_app {
299 name: "bar",
300 sdk_version: "current",
301 resource_dirs: [],
302 static_libs: ["lib"],
303 }
304
305 android_library {
306 name: "lib",
307 sdk_version: "current",
308 resource_dirs: [],
309 static_libs: ["lib2"],
310 }
311
312 android_library {
313 name: "lib2",
314 sdk_version: "current",
315 resource_dirs: ["lib2/res"],
316 }
317 `
318
319 for _, testCase := range testCases {
320 t.Run(testCase.name, func(t *testing.T) {
Paul Duffin0342dc92021-03-22 17:31:52 +0000321 result := android.GroupFixturePreparers(
322 PrepareForTestWithJavaDefaultModules,
323 PrepareForTestWithOverlayBuildComponents,
324 fs.AddToFixture(),
325 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
326 variables.ProductResourceOverlays = productResourceOverlays
327 if testCase.enforceRROTargets != nil {
328 variables.EnforceRROTargets = testCase.enforceRROTargets
329 }
330 }),
331 ).RunTestWithBp(t, bp)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800332
333 modules := []string{"foo", "bar"}
334 for _, moduleName := range modules {
Paul Duffin0342dc92021-03-22 17:31:52 +0000335 module := result.ModuleForTests(moduleName, "android_common")
336 mkEntries := android.AndroidMkEntriesForTest(t, result.TestContext, module.Module())[0]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800337 actualRRODirs := mkEntries.EntryMap["LOCAL_SOONG_PRODUCT_RRO_DIRS"]
338 if !reflect.DeepEqual(actualRRODirs, testCase.rroDirs[moduleName]) {
339 t.Errorf("exected %s LOCAL_SOONG_PRODUCT_RRO_DIRS entry: %v\ngot:%q",
340 moduleName, testCase.rroDirs[moduleName], actualRRODirs)
341 }
342 }
343 })
344 }
345}
Spandan Das5d1b9292021-06-03 19:36:41 +0000346
347func TestRuntimeResourceOverlayPartition(t *testing.T) {
348 bp := `
349 runtime_resource_overlay {
350 name: "device_specific",
351 device_specific: true,
352 }
353 runtime_resource_overlay {
354 name: "soc_specific",
355 soc_specific: true,
356 }
357 runtime_resource_overlay {
358 name: "system_ext_specific",
359 system_ext_specific: true,
360 }
361 runtime_resource_overlay {
362 name: "product_specific",
363 product_specific: true,
364 }
365 runtime_resource_overlay {
366 name: "default"
367 }
368 `
369 testCases := []struct {
370 name string
371 expectedPath string
372 }{
373 {
374 name: "device_specific",
375 expectedPath: "out/soong/target/product/test_device/odm/overlay",
376 },
377 {
378 name: "soc_specific",
379 expectedPath: "out/soong/target/product/test_device/vendor/overlay",
380 },
381 {
382 name: "system_ext_specific",
383 expectedPath: "out/soong/target/product/test_device/system_ext/overlay",
384 },
385 {
386 name: "product_specific",
387 expectedPath: "out/soong/target/product/test_device/product/overlay",
388 },
389 {
390 name: "default",
391 expectedPath: "out/soong/target/product/test_device/product/overlay",
392 },
393 }
394 for _, testCase := range testCases {
395 ctx, _ := testJava(t, bp)
396 mod := ctx.ModuleForTests(testCase.name, "android_common").Module().(*RuntimeResourceOverlay)
397 android.AssertPathRelativeToTopEquals(t, "Install dir is not correct for "+testCase.name, testCase.expectedPath, mod.installDir)
398 }
399}