blob: 742c8398269010f0cd5b3cf4eb02bcfb0426e456 [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",
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -040036 rotationMinSdkVersion: "32",
Jaewoong Jungf9b44652020-12-21 12:29:12 -080037 product_specific: true,
38 static_libs: ["bar"],
39 resource_libs: ["baz"],
40 aaptflags: ["--keep-raw-values"],
41 }
42
43 runtime_resource_overlay {
44 name: "foo_themed",
45 certificate: "platform",
46 product_specific: true,
47 theme: "faza",
48 overrides: ["foo"],
49 }
50
51 android_library {
52 name: "bar",
53 resource_dirs: ["bar/res"],
54 }
55
56 android_app {
57 name: "baz",
58 sdk_version: "current",
59 resource_dirs: ["baz/res"],
60 }
Paul Duffin0342dc92021-03-22 17:31:52 +000061 `
Jaewoong Jungf9b44652020-12-21 12:29:12 -080062
Paul Duffin0342dc92021-03-22 17:31:52 +000063 result := android.GroupFixturePreparers(
64 PrepareForTestWithJavaDefaultModules,
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
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -040092 // Check cert signing flags.
Jaewoong Jungf9b44652020-12-21 12:29:12 -080093 signedApk := m.Output("signed/foo.apk")
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -040094 actualCertSigningFlags := signedApk.Args["flags"]
95 expectedCertSigningFlags := "--lineage lineage.bin --rotation-min-sdk-version 32"
96 if expectedCertSigningFlags != actualCertSigningFlags {
97 t.Errorf("Incorrect cert signing flags, expected: %q, got: %q", expectedCertSigningFlags, actualCertSigningFlags)
Jaewoong Jungf9b44652020-12-21 12:29:12 -080098 }
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -040099
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800100 signingFlag := signedApk.Args["certificates"]
101 expected := "build/make/target/product/security/platform.x509.pem build/make/target/product/security/platform.pk8"
102 if expected != signingFlag {
103 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
104 }
Paul Duffin0342dc92021-03-22 17:31:52 +0000105 androidMkEntries := android.AndroidMkEntriesForTest(t, result.TestContext, m.Module())[0]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800106 path := androidMkEntries.EntryMap["LOCAL_CERTIFICATE"]
107 expectedPath := []string{"build/make/target/product/security/platform.x509.pem"}
108 if !reflect.DeepEqual(path, expectedPath) {
109 t.Errorf("Unexpected LOCAL_CERTIFICATE value: %v, expected: %v", path, expectedPath)
110 }
111
112 // Check device location.
113 path = androidMkEntries.EntryMap["LOCAL_MODULE_PATH"]
Paul Duffin0342dc92021-03-22 17:31:52 +0000114 expectedPath = []string{shared.JoinPath("out/target/product/test_device/product/overlay")}
115 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", result.Config, expectedPath, path)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800116
117 // A themed module has a different device location
Paul Duffin0342dc92021-03-22 17:31:52 +0000118 m = result.ModuleForTests("foo_themed", "android_common")
119 androidMkEntries = android.AndroidMkEntriesForTest(t, result.TestContext, m.Module())[0]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800120 path = androidMkEntries.EntryMap["LOCAL_MODULE_PATH"]
Paul Duffin0342dc92021-03-22 17:31:52 +0000121 expectedPath = []string{shared.JoinPath("out/target/product/test_device/product/overlay/faza")}
122 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", result.Config, expectedPath, path)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800123
124 overrides := androidMkEntries.EntryMap["LOCAL_OVERRIDES_PACKAGES"]
125 expectedOverrides := []string{"foo"}
126 if !reflect.DeepEqual(overrides, expectedOverrides) {
127 t.Errorf("Unexpected LOCAL_OVERRIDES_PACKAGES value: %v, expected: %v", overrides, expectedOverrides)
128 }
129}
130
131func TestRuntimeResourceOverlay_JavaDefaults(t *testing.T) {
Colin Crossc68db4b2021-11-11 18:59:15 -0800132 result := android.GroupFixturePreparers(
133 PrepareForTestWithJavaDefaultModules,
134 android.FixtureModifyConfig(android.SetKatiEnabledForTests),
135 ).RunTestWithBp(t, `
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800136 java_defaults {
137 name: "rro_defaults",
138 theme: "default_theme",
139 product_specific: true,
140 aaptflags: ["--keep-raw-values"],
141 }
142
143 runtime_resource_overlay {
144 name: "foo_with_defaults",
145 defaults: ["rro_defaults"],
146 }
147
148 runtime_resource_overlay {
149 name: "foo_barebones",
150 }
151 `)
152
153 //
154 // RRO module with defaults
155 //
Colin Crossc68db4b2021-11-11 18:59:15 -0800156 m := result.ModuleForTests("foo_with_defaults", "android_common")
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800157
158 // Check AAPT2 link flags.
159 aapt2Flags := strings.Split(m.Output("package-res.apk").Args["flags"], " ")
160 expectedFlags := []string{"--keep-raw-values", "--no-resource-deduping", "--no-resource-removal"}
161 absentFlags := android.RemoveListFromList(expectedFlags, aapt2Flags)
162 if len(absentFlags) > 0 {
163 t.Errorf("expected values, %q are missing in aapt2 link flags, %q", absentFlags, aapt2Flags)
164 }
165
166 // Check device location.
Colin Crossc68db4b2021-11-11 18:59:15 -0800167 path := android.AndroidMkEntriesForTest(t, result.TestContext, m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
Paul Duffin0342dc92021-03-22 17:31:52 +0000168 expectedPath := []string{shared.JoinPath("out/target/product/test_device/product/overlay/default_theme")}
Colin Crossc68db4b2021-11-11 18:59:15 -0800169 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", result.Config, expectedPath, path)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800170
171 //
172 // RRO module without defaults
173 //
Colin Crossc68db4b2021-11-11 18:59:15 -0800174 m = result.ModuleForTests("foo_barebones", "android_common")
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800175
176 // Check AAPT2 link flags.
177 aapt2Flags = strings.Split(m.Output("package-res.apk").Args["flags"], " ")
178 unexpectedFlags := "--keep-raw-values"
179 if inList(unexpectedFlags, aapt2Flags) {
180 t.Errorf("unexpected value, %q is present in aapt2 link flags, %q", unexpectedFlags, aapt2Flags)
181 }
182
183 // Check device location.
Colin Crossc68db4b2021-11-11 18:59:15 -0800184 path = android.AndroidMkEntriesForTest(t, result.TestContext, m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
Spandan Das5d1b9292021-06-03 19:36:41 +0000185 expectedPath = []string{shared.JoinPath("out/target/product/test_device/product/overlay")}
Colin Crossc68db4b2021-11-11 18:59:15 -0800186 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", result.Config, expectedPath, path)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800187}
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",
Jeremy Meyer7e671292022-10-07 18:21:34 +0000203 category: "mycategory",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800204 }
205 `)
206
207 expectedVariants := []struct {
208 moduleName string
209 variantName string
210 apkPath string
211 overrides []string
212 targetVariant string
213 packageFlag string
214 targetPackageFlag string
Jeremy Meyer7e671292022-10-07 18:21:34 +0000215 categoryFlag string
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800216 }{
217 {
218 variantName: "android_common",
Paul Duffin0342dc92021-03-22 17:31:52 +0000219 apkPath: "out/soong/target/product/test_device/product/overlay/foo_overlay.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800220 overrides: nil,
221 targetVariant: "android_common",
222 packageFlag: "",
223 targetPackageFlag: "",
224 },
225 {
226 variantName: "android_common_bar_overlay",
Paul Duffin0342dc92021-03-22 17:31:52 +0000227 apkPath: "out/soong/target/product/test_device/product/overlay/bar_overlay.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800228 overrides: []string{"foo_overlay"},
229 targetVariant: "android_common_bar",
230 packageFlag: "com.android.bar.overlay",
231 targetPackageFlag: "com.android.bar",
Jeremy Meyer7e671292022-10-07 18:21:34 +0000232 categoryFlag: "mycategory",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800233 },
234 }
235 for _, expected := range expectedVariants {
236 variant := ctx.ModuleForTests("foo_overlay", expected.variantName)
237
238 // Check the final apk name
Paul Duffin0342dc92021-03-22 17:31:52 +0000239 variant.Output(expected.apkPath)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800240
241 // Check if the overrides field values are correctly aggregated.
242 mod := variant.Module().(*RuntimeResourceOverlay)
243 if !reflect.DeepEqual(expected.overrides, mod.properties.Overrides) {
244 t.Errorf("Incorrect overrides property value, expected: %q, got: %q",
245 expected.overrides, mod.properties.Overrides)
246 }
247
248 // Check aapt2 flags.
249 res := variant.Output("package-res.apk")
250 aapt2Flags := res.Args["flags"]
251 checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
252 checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", "")
253 checkAapt2LinkFlag(t, aapt2Flags, "rename-overlay-target-package", expected.targetPackageFlag)
Jeremy Meyer7e671292022-10-07 18:21:34 +0000254 checkAapt2LinkFlag(t, aapt2Flags, "rename-overlay-category", expected.categoryFlag)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800255 }
256}
257
258func TestEnforceRRO_propagatesToDependencies(t *testing.T) {
259 testCases := []struct {
Jeongik Chacee5ba92021-02-19 12:11:51 +0900260 name string
261 enforceRROTargets []string
262 rroDirs map[string][]string
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800263 }{
264 {
Jeongik Chacee5ba92021-02-19 12:11:51 +0900265 name: "no RRO",
266 enforceRROTargets: nil,
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800267 rroDirs: map[string][]string{
268 "foo": nil,
269 "bar": nil,
270 },
271 },
272 {
Jeongik Chacee5ba92021-02-19 12:11:51 +0900273 name: "enforce RRO on all",
274 enforceRROTargets: []string{"*"},
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800275 rroDirs: map[string][]string{
276 "foo": {"product/vendor/blah/overlay/lib2/res"},
277 "bar": {"product/vendor/blah/overlay/lib2/res"},
278 },
279 },
280 {
Jeongik Chacee5ba92021-02-19 12:11:51 +0900281 name: "enforce RRO on foo",
282 enforceRROTargets: []string{"foo"},
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800283 rroDirs: map[string][]string{
284 "foo": {"product/vendor/blah/overlay/lib2/res"},
285 "bar": {"product/vendor/blah/overlay/lib2/res"},
286 },
287 },
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800288 }
289
290 productResourceOverlays := []string{
291 "product/vendor/blah/overlay",
292 }
293
Paul Duffin0342dc92021-03-22 17:31:52 +0000294 fs := android.MockFS{
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800295 "lib2/res/values/strings.xml": nil,
296 "product/vendor/blah/overlay/lib2/res/values/strings.xml": nil,
297 }
298
299 bp := `
300 android_app {
301 name: "foo",
302 sdk_version: "current",
303 resource_dirs: [],
304 static_libs: ["lib"],
305 }
306
307 android_app {
308 name: "bar",
309 sdk_version: "current",
310 resource_dirs: [],
311 static_libs: ["lib"],
312 }
313
314 android_library {
315 name: "lib",
316 sdk_version: "current",
317 resource_dirs: [],
318 static_libs: ["lib2"],
319 }
320
321 android_library {
322 name: "lib2",
323 sdk_version: "current",
324 resource_dirs: ["lib2/res"],
325 }
326 `
327
328 for _, testCase := range testCases {
329 t.Run(testCase.name, func(t *testing.T) {
Paul Duffin0342dc92021-03-22 17:31:52 +0000330 result := android.GroupFixturePreparers(
331 PrepareForTestWithJavaDefaultModules,
Paul Duffin0342dc92021-03-22 17:31:52 +0000332 fs.AddToFixture(),
333 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
334 variables.ProductResourceOverlays = productResourceOverlays
335 if testCase.enforceRROTargets != nil {
336 variables.EnforceRROTargets = testCase.enforceRROTargets
337 }
338 }),
339 ).RunTestWithBp(t, bp)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800340
341 modules := []string{"foo", "bar"}
342 for _, moduleName := range modules {
Paul Duffin0342dc92021-03-22 17:31:52 +0000343 module := result.ModuleForTests(moduleName, "android_common")
344 mkEntries := android.AndroidMkEntriesForTest(t, result.TestContext, module.Module())[0]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800345 actualRRODirs := mkEntries.EntryMap["LOCAL_SOONG_PRODUCT_RRO_DIRS"]
346 if !reflect.DeepEqual(actualRRODirs, testCase.rroDirs[moduleName]) {
347 t.Errorf("exected %s LOCAL_SOONG_PRODUCT_RRO_DIRS entry: %v\ngot:%q",
348 moduleName, testCase.rroDirs[moduleName], actualRRODirs)
349 }
350 }
351 })
352 }
353}
Spandan Das5d1b9292021-06-03 19:36:41 +0000354
355func TestRuntimeResourceOverlayPartition(t *testing.T) {
356 bp := `
357 runtime_resource_overlay {
358 name: "device_specific",
359 device_specific: true,
360 }
361 runtime_resource_overlay {
362 name: "soc_specific",
363 soc_specific: true,
364 }
365 runtime_resource_overlay {
366 name: "system_ext_specific",
367 system_ext_specific: true,
368 }
369 runtime_resource_overlay {
370 name: "product_specific",
371 product_specific: true,
372 }
373 runtime_resource_overlay {
374 name: "default"
375 }
376 `
377 testCases := []struct {
378 name string
379 expectedPath string
380 }{
381 {
382 name: "device_specific",
383 expectedPath: "out/soong/target/product/test_device/odm/overlay",
384 },
385 {
386 name: "soc_specific",
387 expectedPath: "out/soong/target/product/test_device/vendor/overlay",
388 },
389 {
390 name: "system_ext_specific",
391 expectedPath: "out/soong/target/product/test_device/system_ext/overlay",
392 },
393 {
394 name: "product_specific",
395 expectedPath: "out/soong/target/product/test_device/product/overlay",
396 },
397 {
398 name: "default",
399 expectedPath: "out/soong/target/product/test_device/product/overlay",
400 },
401 }
402 for _, testCase := range testCases {
403 ctx, _ := testJava(t, bp)
404 mod := ctx.ModuleForTests(testCase.name, "android_common").Module().(*RuntimeResourceOverlay)
405 android.AssertPathRelativeToTopEquals(t, "Install dir is not correct for "+testCase.name, testCase.expectedPath, mod.installDir)
406 }
407}
Jihoon Kang9f442dc2024-03-20 22:09:04 +0000408
409func TestRuntimeResourceOverlayFlagsPackages(t *testing.T) {
410 result := android.GroupFixturePreparers(
411 prepareForJavaTest,
412 ).RunTestWithBp(t, `
413 runtime_resource_overlay {
414 name: "foo",
415 sdk_version: "current",
416 flags_packages: [
417 "bar",
418 "baz",
419 ],
420 }
421 aconfig_declarations {
422 name: "bar",
423 package: "com.example.package.bar",
Yu Liue916a2c2024-03-20 19:47:28 +0000424 container: "com.android.foo",
Jihoon Kang9f442dc2024-03-20 22:09:04 +0000425 srcs: [
426 "bar.aconfig",
427 ],
428 }
429 aconfig_declarations {
430 name: "baz",
431 package: "com.example.package.baz",
Yu Liue916a2c2024-03-20 19:47:28 +0000432 container: "com.android.foo",
Jihoon Kang9f442dc2024-03-20 22:09:04 +0000433 srcs: [
434 "baz.aconfig",
435 ],
436 }
437 `)
438
439 foo := result.ModuleForTests("foo", "android_common")
440
441 // runtime_resource_overlay module depends on aconfig_declarations listed in flags_packages
442 android.AssertBoolEquals(t, "foo expected to depend on bar", true,
443 CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "bar"))
444
445 android.AssertBoolEquals(t, "foo expected to depend on baz", true,
446 CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "baz"))
447
448 aapt2LinkRule := foo.Rule("android/soong/java.aapt2Link")
449 linkInFlags := aapt2LinkRule.Args["inFlags"]
450 android.AssertStringDoesContain(t,
451 "aapt2 link command expected to pass feature flags arguments",
452 linkInFlags,
453 "--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt",
454 )
455}