blob: be0d7ba47b0a9c8db826dfcc0667aa7ab6bb6dae [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,
Colin Crossc68db4b2021-11-11 18:59:15 -080065 android.FixtureModifyConfig(android.SetKatiEnabledForTests),
Paul Duffin0342dc92021-03-22 17:31:52 +000066 fs.AddToFixture(),
67 ).RunTestWithBp(t, bp)
68
69 m := result.ModuleForTests("foo", "android_common")
Jaewoong Jungf9b44652020-12-21 12:29:12 -080070
71 // Check AAPT2 link flags.
Paul Duffina71a67a2021-03-29 00:42:57 +010072 aapt2Flags := m.Output("package-res.apk").Args["flags"]
Jaewoong Jungf9b44652020-12-21 12:29:12 -080073 expectedFlags := []string{"--keep-raw-values", "--no-resource-deduping", "--no-resource-removal"}
74 absentFlags := android.RemoveListFromList(expectedFlags, strings.Split(aapt2Flags, " "))
75 if len(absentFlags) > 0 {
76 t.Errorf("expected values, %q are missing in aapt2 link flags, %q", absentFlags, aapt2Flags)
77 }
78
79 // Check overlay.list output for static_libs dependency.
Paul Duffin0342dc92021-03-22 17:31:52 +000080 overlayList := android.PathsRelativeToTop(m.Output("aapt2/overlay.list").Inputs)
81 staticLibPackage := "out/soong/.intermediates/bar/android_common/package-res.apk"
Jaewoong Jungf9b44652020-12-21 12:29:12 -080082 if !inList(staticLibPackage, overlayList) {
83 t.Errorf("Stactic lib res package %q missing in overlay list: %q", staticLibPackage, overlayList)
84 }
85
86 // Check AAPT2 link flags for resource_libs dependency.
Paul Duffin0342dc92021-03-22 17:31:52 +000087 resourceLibFlag := "-I " + "out/soong/.intermediates/baz/android_common/package-res.apk"
Jaewoong Jungf9b44652020-12-21 12:29:12 -080088 if !strings.Contains(aapt2Flags, resourceLibFlag) {
89 t.Errorf("Resource lib flag %q missing in aapt2 link flags: %q", resourceLibFlag, aapt2Flags)
90 }
91
92 // Check cert signing flag.
93 signedApk := m.Output("signed/foo.apk")
94 lineageFlag := signedApk.Args["flags"]
95 expectedLineageFlag := "--lineage lineage.bin"
96 if expectedLineageFlag != lineageFlag {
97 t.Errorf("Incorrect signing lineage flags, expected: %q, got: %q", expectedLineageFlag, lineageFlag)
98 }
99 signingFlag := signedApk.Args["certificates"]
100 expected := "build/make/target/product/security/platform.x509.pem build/make/target/product/security/platform.pk8"
101 if expected != signingFlag {
102 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
103 }
Paul Duffin0342dc92021-03-22 17:31:52 +0000104 androidMkEntries := android.AndroidMkEntriesForTest(t, result.TestContext, m.Module())[0]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800105 path := androidMkEntries.EntryMap["LOCAL_CERTIFICATE"]
106 expectedPath := []string{"build/make/target/product/security/platform.x509.pem"}
107 if !reflect.DeepEqual(path, expectedPath) {
108 t.Errorf("Unexpected LOCAL_CERTIFICATE value: %v, expected: %v", path, expectedPath)
109 }
110
111 // Check device location.
112 path = androidMkEntries.EntryMap["LOCAL_MODULE_PATH"]
Paul Duffin0342dc92021-03-22 17:31:52 +0000113 expectedPath = []string{shared.JoinPath("out/target/product/test_device/product/overlay")}
114 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", result.Config, expectedPath, path)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800115
116 // A themed module has a different device location
Paul Duffin0342dc92021-03-22 17:31:52 +0000117 m = result.ModuleForTests("foo_themed", "android_common")
118 androidMkEntries = android.AndroidMkEntriesForTest(t, result.TestContext, m.Module())[0]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800119 path = androidMkEntries.EntryMap["LOCAL_MODULE_PATH"]
Paul Duffin0342dc92021-03-22 17:31:52 +0000120 expectedPath = []string{shared.JoinPath("out/target/product/test_device/product/overlay/faza")}
121 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", result.Config, expectedPath, path)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800122
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 Crossc68db4b2021-11-11 18:59:15 -0800131 result := android.GroupFixturePreparers(
132 PrepareForTestWithJavaDefaultModules,
133 android.FixtureModifyConfig(android.SetKatiEnabledForTests),
134 ).RunTestWithBp(t, `
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800135 java_defaults {
136 name: "rro_defaults",
137 theme: "default_theme",
138 product_specific: true,
139 aaptflags: ["--keep-raw-values"],
140 }
141
142 runtime_resource_overlay {
143 name: "foo_with_defaults",
144 defaults: ["rro_defaults"],
145 }
146
147 runtime_resource_overlay {
148 name: "foo_barebones",
149 }
150 `)
151
152 //
153 // RRO module with defaults
154 //
Colin Crossc68db4b2021-11-11 18:59:15 -0800155 m := result.ModuleForTests("foo_with_defaults", "android_common")
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800156
157 // Check AAPT2 link flags.
158 aapt2Flags := strings.Split(m.Output("package-res.apk").Args["flags"], " ")
159 expectedFlags := []string{"--keep-raw-values", "--no-resource-deduping", "--no-resource-removal"}
160 absentFlags := android.RemoveListFromList(expectedFlags, aapt2Flags)
161 if len(absentFlags) > 0 {
162 t.Errorf("expected values, %q are missing in aapt2 link flags, %q", absentFlags, aapt2Flags)
163 }
164
165 // Check device location.
Colin Crossc68db4b2021-11-11 18:59:15 -0800166 path := android.AndroidMkEntriesForTest(t, result.TestContext, m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
Paul Duffin0342dc92021-03-22 17:31:52 +0000167 expectedPath := []string{shared.JoinPath("out/target/product/test_device/product/overlay/default_theme")}
Colin Crossc68db4b2021-11-11 18:59:15 -0800168 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", result.Config, expectedPath, path)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800169
170 //
171 // RRO module without defaults
172 //
Colin Crossc68db4b2021-11-11 18:59:15 -0800173 m = result.ModuleForTests("foo_barebones", "android_common")
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800174
175 // Check AAPT2 link flags.
176 aapt2Flags = strings.Split(m.Output("package-res.apk").Args["flags"], " ")
177 unexpectedFlags := "--keep-raw-values"
178 if inList(unexpectedFlags, aapt2Flags) {
179 t.Errorf("unexpected value, %q is present in aapt2 link flags, %q", unexpectedFlags, aapt2Flags)
180 }
181
182 // Check device location.
Colin Crossc68db4b2021-11-11 18:59:15 -0800183 path = android.AndroidMkEntriesForTest(t, result.TestContext, m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
Spandan Das5d1b9292021-06-03 19:36:41 +0000184 expectedPath = []string{shared.JoinPath("out/target/product/test_device/product/overlay")}
Colin Crossc68db4b2021-11-11 18:59:15 -0800185 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", result.Config, expectedPath, path)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800186}
187
188func TestOverrideRuntimeResourceOverlay(t *testing.T) {
189 ctx, _ := testJava(t, `
190 runtime_resource_overlay {
191 name: "foo_overlay",
192 certificate: "platform",
193 product_specific: true,
194 sdk_version: "current",
195 }
196
197 override_runtime_resource_overlay {
198 name: "bar_overlay",
199 base: "foo_overlay",
200 package_name: "com.android.bar.overlay",
201 target_package_name: "com.android.bar",
202 }
203 `)
204
205 expectedVariants := []struct {
206 moduleName string
207 variantName string
208 apkPath string
209 overrides []string
210 targetVariant string
211 packageFlag string
212 targetPackageFlag string
213 }{
214 {
215 variantName: "android_common",
Paul Duffin0342dc92021-03-22 17:31:52 +0000216 apkPath: "out/soong/target/product/test_device/product/overlay/foo_overlay.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800217 overrides: nil,
218 targetVariant: "android_common",
219 packageFlag: "",
220 targetPackageFlag: "",
221 },
222 {
223 variantName: "android_common_bar_overlay",
Paul Duffin0342dc92021-03-22 17:31:52 +0000224 apkPath: "out/soong/target/product/test_device/product/overlay/bar_overlay.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800225 overrides: []string{"foo_overlay"},
226 targetVariant: "android_common_bar",
227 packageFlag: "com.android.bar.overlay",
228 targetPackageFlag: "com.android.bar",
229 },
230 }
231 for _, expected := range expectedVariants {
232 variant := ctx.ModuleForTests("foo_overlay", expected.variantName)
233
234 // Check the final apk name
Paul Duffin0342dc92021-03-22 17:31:52 +0000235 variant.Output(expected.apkPath)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800236
237 // Check if the overrides field values are correctly aggregated.
238 mod := variant.Module().(*RuntimeResourceOverlay)
239 if !reflect.DeepEqual(expected.overrides, mod.properties.Overrides) {
240 t.Errorf("Incorrect overrides property value, expected: %q, got: %q",
241 expected.overrides, mod.properties.Overrides)
242 }
243
244 // Check aapt2 flags.
245 res := variant.Output("package-res.apk")
246 aapt2Flags := res.Args["flags"]
247 checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
248 checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", "")
249 checkAapt2LinkFlag(t, aapt2Flags, "rename-overlay-target-package", expected.targetPackageFlag)
250 }
251}
252
253func TestEnforceRRO_propagatesToDependencies(t *testing.T) {
254 testCases := []struct {
Jeongik Chacee5ba92021-02-19 12:11:51 +0900255 name string
256 enforceRROTargets []string
257 rroDirs map[string][]string
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800258 }{
259 {
Jeongik Chacee5ba92021-02-19 12:11:51 +0900260 name: "no RRO",
261 enforceRROTargets: nil,
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800262 rroDirs: map[string][]string{
263 "foo": nil,
264 "bar": nil,
265 },
266 },
267 {
Jeongik Chacee5ba92021-02-19 12:11:51 +0900268 name: "enforce RRO on all",
269 enforceRROTargets: []string{"*"},
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800270 rroDirs: map[string][]string{
271 "foo": {"product/vendor/blah/overlay/lib2/res"},
272 "bar": {"product/vendor/blah/overlay/lib2/res"},
273 },
274 },
275 {
Jeongik Chacee5ba92021-02-19 12:11:51 +0900276 name: "enforce RRO on foo",
277 enforceRROTargets: []string{"foo"},
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800278 rroDirs: map[string][]string{
279 "foo": {"product/vendor/blah/overlay/lib2/res"},
280 "bar": {"product/vendor/blah/overlay/lib2/res"},
281 },
282 },
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800283 }
284
285 productResourceOverlays := []string{
286 "product/vendor/blah/overlay",
287 }
288
Paul Duffin0342dc92021-03-22 17:31:52 +0000289 fs := android.MockFS{
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800290 "lib2/res/values/strings.xml": nil,
291 "product/vendor/blah/overlay/lib2/res/values/strings.xml": nil,
292 }
293
294 bp := `
295 android_app {
296 name: "foo",
297 sdk_version: "current",
298 resource_dirs: [],
299 static_libs: ["lib"],
300 }
301
302 android_app {
303 name: "bar",
304 sdk_version: "current",
305 resource_dirs: [],
306 static_libs: ["lib"],
307 }
308
309 android_library {
310 name: "lib",
311 sdk_version: "current",
312 resource_dirs: [],
313 static_libs: ["lib2"],
314 }
315
316 android_library {
317 name: "lib2",
318 sdk_version: "current",
319 resource_dirs: ["lib2/res"],
320 }
321 `
322
323 for _, testCase := range testCases {
324 t.Run(testCase.name, func(t *testing.T) {
Paul Duffin0342dc92021-03-22 17:31:52 +0000325 result := android.GroupFixturePreparers(
326 PrepareForTestWithJavaDefaultModules,
327 PrepareForTestWithOverlayBuildComponents,
328 fs.AddToFixture(),
329 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
330 variables.ProductResourceOverlays = productResourceOverlays
331 if testCase.enforceRROTargets != nil {
332 variables.EnforceRROTargets = testCase.enforceRROTargets
333 }
334 }),
335 ).RunTestWithBp(t, bp)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800336
337 modules := []string{"foo", "bar"}
338 for _, moduleName := range modules {
Paul Duffin0342dc92021-03-22 17:31:52 +0000339 module := result.ModuleForTests(moduleName, "android_common")
340 mkEntries := android.AndroidMkEntriesForTest(t, result.TestContext, module.Module())[0]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800341 actualRRODirs := mkEntries.EntryMap["LOCAL_SOONG_PRODUCT_RRO_DIRS"]
342 if !reflect.DeepEqual(actualRRODirs, testCase.rroDirs[moduleName]) {
343 t.Errorf("exected %s LOCAL_SOONG_PRODUCT_RRO_DIRS entry: %v\ngot:%q",
344 moduleName, testCase.rroDirs[moduleName], actualRRODirs)
345 }
346 }
347 })
348 }
349}
Spandan Das5d1b9292021-06-03 19:36:41 +0000350
351func TestRuntimeResourceOverlayPartition(t *testing.T) {
352 bp := `
353 runtime_resource_overlay {
354 name: "device_specific",
355 device_specific: true,
356 }
357 runtime_resource_overlay {
358 name: "soc_specific",
359 soc_specific: true,
360 }
361 runtime_resource_overlay {
362 name: "system_ext_specific",
363 system_ext_specific: true,
364 }
365 runtime_resource_overlay {
366 name: "product_specific",
367 product_specific: true,
368 }
369 runtime_resource_overlay {
370 name: "default"
371 }
372 `
373 testCases := []struct {
374 name string
375 expectedPath string
376 }{
377 {
378 name: "device_specific",
379 expectedPath: "out/soong/target/product/test_device/odm/overlay",
380 },
381 {
382 name: "soc_specific",
383 expectedPath: "out/soong/target/product/test_device/vendor/overlay",
384 },
385 {
386 name: "system_ext_specific",
387 expectedPath: "out/soong/target/product/test_device/system_ext/overlay",
388 },
389 {
390 name: "product_specific",
391 expectedPath: "out/soong/target/product/test_device/product/overlay",
392 },
393 {
394 name: "default",
395 expectedPath: "out/soong/target/product/test_device/product/overlay",
396 },
397 }
398 for _, testCase := range testCases {
399 ctx, _ := testJava(t, bp)
400 mod := ctx.ModuleForTests(testCase.name, "android_common").Module().(*RuntimeResourceOverlay)
401 android.AssertPathRelativeToTopEquals(t, "Install dir is not correct for "+testCase.name, testCase.expectedPath, mod.installDir)
402 }
403}