blob: 8067a47035557fb913998604fc7375144e68abc3 [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,
65 PrepareForTestWithOverlayBuildComponents,
Colin Crossc68db4b2021-11-11 18:59:15 -080066 android.FixtureModifyConfig(android.SetKatiEnabledForTests),
Paul Duffin0342dc92021-03-22 17:31:52 +000067 fs.AddToFixture(),
68 ).RunTestWithBp(t, bp)
69
70 m := result.ModuleForTests("foo", "android_common")
Jaewoong Jungf9b44652020-12-21 12:29:12 -080071
72 // Check AAPT2 link flags.
Paul Duffina71a67a2021-03-29 00:42:57 +010073 aapt2Flags := m.Output("package-res.apk").Args["flags"]
Jaewoong Jungf9b44652020-12-21 12:29:12 -080074 expectedFlags := []string{"--keep-raw-values", "--no-resource-deduping", "--no-resource-removal"}
75 absentFlags := android.RemoveListFromList(expectedFlags, strings.Split(aapt2Flags, " "))
76 if len(absentFlags) > 0 {
77 t.Errorf("expected values, %q are missing in aapt2 link flags, %q", absentFlags, aapt2Flags)
78 }
79
80 // Check overlay.list output for static_libs dependency.
Paul Duffin0342dc92021-03-22 17:31:52 +000081 overlayList := android.PathsRelativeToTop(m.Output("aapt2/overlay.list").Inputs)
82 staticLibPackage := "out/soong/.intermediates/bar/android_common/package-res.apk"
Jaewoong Jungf9b44652020-12-21 12:29:12 -080083 if !inList(staticLibPackage, overlayList) {
84 t.Errorf("Stactic lib res package %q missing in overlay list: %q", staticLibPackage, overlayList)
85 }
86
87 // Check AAPT2 link flags for resource_libs dependency.
Paul Duffin0342dc92021-03-22 17:31:52 +000088 resourceLibFlag := "-I " + "out/soong/.intermediates/baz/android_common/package-res.apk"
Jaewoong Jungf9b44652020-12-21 12:29:12 -080089 if !strings.Contains(aapt2Flags, resourceLibFlag) {
90 t.Errorf("Resource lib flag %q missing in aapt2 link flags: %q", resourceLibFlag, aapt2Flags)
91 }
92
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -040093 // Check cert signing flags.
Jaewoong Jungf9b44652020-12-21 12:29:12 -080094 signedApk := m.Output("signed/foo.apk")
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -040095 actualCertSigningFlags := signedApk.Args["flags"]
96 expectedCertSigningFlags := "--lineage lineage.bin --rotation-min-sdk-version 32"
97 if expectedCertSigningFlags != actualCertSigningFlags {
98 t.Errorf("Incorrect cert signing flags, expected: %q, got: %q", expectedCertSigningFlags, actualCertSigningFlags)
Jaewoong Jungf9b44652020-12-21 12:29:12 -080099 }
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -0400100
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800101 signingFlag := signedApk.Args["certificates"]
102 expected := "build/make/target/product/security/platform.x509.pem build/make/target/product/security/platform.pk8"
103 if expected != signingFlag {
104 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
105 }
Paul Duffin0342dc92021-03-22 17:31:52 +0000106 androidMkEntries := android.AndroidMkEntriesForTest(t, result.TestContext, m.Module())[0]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800107 path := androidMkEntries.EntryMap["LOCAL_CERTIFICATE"]
108 expectedPath := []string{"build/make/target/product/security/platform.x509.pem"}
109 if !reflect.DeepEqual(path, expectedPath) {
110 t.Errorf("Unexpected LOCAL_CERTIFICATE value: %v, expected: %v", path, expectedPath)
111 }
112
113 // Check device location.
114 path = androidMkEntries.EntryMap["LOCAL_MODULE_PATH"]
Paul Duffin0342dc92021-03-22 17:31:52 +0000115 expectedPath = []string{shared.JoinPath("out/target/product/test_device/product/overlay")}
116 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", result.Config, expectedPath, path)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800117
118 // A themed module has a different device location
Paul Duffin0342dc92021-03-22 17:31:52 +0000119 m = result.ModuleForTests("foo_themed", "android_common")
120 androidMkEntries = android.AndroidMkEntriesForTest(t, result.TestContext, m.Module())[0]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800121 path = androidMkEntries.EntryMap["LOCAL_MODULE_PATH"]
Paul Duffin0342dc92021-03-22 17:31:52 +0000122 expectedPath = []string{shared.JoinPath("out/target/product/test_device/product/overlay/faza")}
123 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", result.Config, expectedPath, path)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800124
125 overrides := androidMkEntries.EntryMap["LOCAL_OVERRIDES_PACKAGES"]
126 expectedOverrides := []string{"foo"}
127 if !reflect.DeepEqual(overrides, expectedOverrides) {
128 t.Errorf("Unexpected LOCAL_OVERRIDES_PACKAGES value: %v, expected: %v", overrides, expectedOverrides)
129 }
130}
131
132func TestRuntimeResourceOverlay_JavaDefaults(t *testing.T) {
Colin Crossc68db4b2021-11-11 18:59:15 -0800133 result := android.GroupFixturePreparers(
134 PrepareForTestWithJavaDefaultModules,
135 android.FixtureModifyConfig(android.SetKatiEnabledForTests),
136 ).RunTestWithBp(t, `
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800137 java_defaults {
138 name: "rro_defaults",
139 theme: "default_theme",
140 product_specific: true,
141 aaptflags: ["--keep-raw-values"],
142 }
143
144 runtime_resource_overlay {
145 name: "foo_with_defaults",
146 defaults: ["rro_defaults"],
147 }
148
149 runtime_resource_overlay {
150 name: "foo_barebones",
151 }
152 `)
153
154 //
155 // RRO module with defaults
156 //
Colin Crossc68db4b2021-11-11 18:59:15 -0800157 m := result.ModuleForTests("foo_with_defaults", "android_common")
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800158
159 // Check AAPT2 link flags.
160 aapt2Flags := strings.Split(m.Output("package-res.apk").Args["flags"], " ")
161 expectedFlags := []string{"--keep-raw-values", "--no-resource-deduping", "--no-resource-removal"}
162 absentFlags := android.RemoveListFromList(expectedFlags, aapt2Flags)
163 if len(absentFlags) > 0 {
164 t.Errorf("expected values, %q are missing in aapt2 link flags, %q", absentFlags, aapt2Flags)
165 }
166
167 // Check device location.
Colin Crossc68db4b2021-11-11 18:59:15 -0800168 path := android.AndroidMkEntriesForTest(t, result.TestContext, m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
Paul Duffin0342dc92021-03-22 17:31:52 +0000169 expectedPath := []string{shared.JoinPath("out/target/product/test_device/product/overlay/default_theme")}
Colin Crossc68db4b2021-11-11 18:59:15 -0800170 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", result.Config, expectedPath, path)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800171
172 //
173 // RRO module without defaults
174 //
Colin Crossc68db4b2021-11-11 18:59:15 -0800175 m = result.ModuleForTests("foo_barebones", "android_common")
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800176
177 // Check AAPT2 link flags.
178 aapt2Flags = strings.Split(m.Output("package-res.apk").Args["flags"], " ")
179 unexpectedFlags := "--keep-raw-values"
180 if inList(unexpectedFlags, aapt2Flags) {
181 t.Errorf("unexpected value, %q is present in aapt2 link flags, %q", unexpectedFlags, aapt2Flags)
182 }
183
184 // Check device location.
Colin Crossc68db4b2021-11-11 18:59:15 -0800185 path = android.AndroidMkEntriesForTest(t, result.TestContext, m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
Spandan Das5d1b9292021-06-03 19:36:41 +0000186 expectedPath = []string{shared.JoinPath("out/target/product/test_device/product/overlay")}
Colin Crossc68db4b2021-11-11 18:59:15 -0800187 android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", result.Config, expectedPath, path)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800188}
189
190func TestOverrideRuntimeResourceOverlay(t *testing.T) {
191 ctx, _ := testJava(t, `
192 runtime_resource_overlay {
193 name: "foo_overlay",
194 certificate: "platform",
195 product_specific: true,
196 sdk_version: "current",
197 }
198
199 override_runtime_resource_overlay {
200 name: "bar_overlay",
201 base: "foo_overlay",
202 package_name: "com.android.bar.overlay",
203 target_package_name: "com.android.bar",
Jeremy Meyer7e671292022-10-07 18:21:34 +0000204 category: "mycategory",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800205 }
206 `)
207
208 expectedVariants := []struct {
209 moduleName string
210 variantName string
211 apkPath string
212 overrides []string
213 targetVariant string
214 packageFlag string
215 targetPackageFlag string
Jeremy Meyer7e671292022-10-07 18:21:34 +0000216 categoryFlag string
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800217 }{
218 {
219 variantName: "android_common",
Paul Duffin0342dc92021-03-22 17:31:52 +0000220 apkPath: "out/soong/target/product/test_device/product/overlay/foo_overlay.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800221 overrides: nil,
222 targetVariant: "android_common",
223 packageFlag: "",
224 targetPackageFlag: "",
225 },
226 {
227 variantName: "android_common_bar_overlay",
Paul Duffin0342dc92021-03-22 17:31:52 +0000228 apkPath: "out/soong/target/product/test_device/product/overlay/bar_overlay.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800229 overrides: []string{"foo_overlay"},
230 targetVariant: "android_common_bar",
231 packageFlag: "com.android.bar.overlay",
232 targetPackageFlag: "com.android.bar",
Jeremy Meyer7e671292022-10-07 18:21:34 +0000233 categoryFlag: "mycategory",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800234 },
235 }
236 for _, expected := range expectedVariants {
237 variant := ctx.ModuleForTests("foo_overlay", expected.variantName)
238
239 // Check the final apk name
Paul Duffin0342dc92021-03-22 17:31:52 +0000240 variant.Output(expected.apkPath)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800241
242 // Check if the overrides field values are correctly aggregated.
243 mod := variant.Module().(*RuntimeResourceOverlay)
244 if !reflect.DeepEqual(expected.overrides, mod.properties.Overrides) {
245 t.Errorf("Incorrect overrides property value, expected: %q, got: %q",
246 expected.overrides, mod.properties.Overrides)
247 }
248
249 // Check aapt2 flags.
250 res := variant.Output("package-res.apk")
251 aapt2Flags := res.Args["flags"]
252 checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
253 checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", "")
254 checkAapt2LinkFlag(t, aapt2Flags, "rename-overlay-target-package", expected.targetPackageFlag)
Jeremy Meyer7e671292022-10-07 18:21:34 +0000255 checkAapt2LinkFlag(t, aapt2Flags, "rename-overlay-category", expected.categoryFlag)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800256 }
257}
258
259func TestEnforceRRO_propagatesToDependencies(t *testing.T) {
260 testCases := []struct {
Jeongik Chacee5ba92021-02-19 12:11:51 +0900261 name string
262 enforceRROTargets []string
263 rroDirs map[string][]string
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800264 }{
265 {
Jeongik Chacee5ba92021-02-19 12:11:51 +0900266 name: "no RRO",
267 enforceRROTargets: nil,
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800268 rroDirs: map[string][]string{
269 "foo": nil,
270 "bar": nil,
271 },
272 },
273 {
Jeongik Chacee5ba92021-02-19 12:11:51 +0900274 name: "enforce RRO on all",
275 enforceRROTargets: []string{"*"},
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800276 rroDirs: map[string][]string{
277 "foo": {"product/vendor/blah/overlay/lib2/res"},
278 "bar": {"product/vendor/blah/overlay/lib2/res"},
279 },
280 },
281 {
Jeongik Chacee5ba92021-02-19 12:11:51 +0900282 name: "enforce RRO on foo",
283 enforceRROTargets: []string{"foo"},
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800284 rroDirs: map[string][]string{
285 "foo": {"product/vendor/blah/overlay/lib2/res"},
286 "bar": {"product/vendor/blah/overlay/lib2/res"},
287 },
288 },
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800289 }
290
291 productResourceOverlays := []string{
292 "product/vendor/blah/overlay",
293 }
294
Paul Duffin0342dc92021-03-22 17:31:52 +0000295 fs := android.MockFS{
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800296 "lib2/res/values/strings.xml": nil,
297 "product/vendor/blah/overlay/lib2/res/values/strings.xml": nil,
298 }
299
300 bp := `
301 android_app {
302 name: "foo",
303 sdk_version: "current",
304 resource_dirs: [],
305 static_libs: ["lib"],
306 }
307
308 android_app {
309 name: "bar",
310 sdk_version: "current",
311 resource_dirs: [],
312 static_libs: ["lib"],
313 }
314
315 android_library {
316 name: "lib",
317 sdk_version: "current",
318 resource_dirs: [],
319 static_libs: ["lib2"],
320 }
321
322 android_library {
323 name: "lib2",
324 sdk_version: "current",
325 resource_dirs: ["lib2/res"],
326 }
327 `
328
329 for _, testCase := range testCases {
330 t.Run(testCase.name, func(t *testing.T) {
Paul Duffin0342dc92021-03-22 17:31:52 +0000331 result := android.GroupFixturePreparers(
332 PrepareForTestWithJavaDefaultModules,
333 PrepareForTestWithOverlayBuildComponents,
334 fs.AddToFixture(),
335 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
336 variables.ProductResourceOverlays = productResourceOverlays
337 if testCase.enforceRROTargets != nil {
338 variables.EnforceRROTargets = testCase.enforceRROTargets
339 }
340 }),
341 ).RunTestWithBp(t, bp)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800342
343 modules := []string{"foo", "bar"}
344 for _, moduleName := range modules {
Paul Duffin0342dc92021-03-22 17:31:52 +0000345 module := result.ModuleForTests(moduleName, "android_common")
346 mkEntries := android.AndroidMkEntriesForTest(t, result.TestContext, module.Module())[0]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800347 actualRRODirs := mkEntries.EntryMap["LOCAL_SOONG_PRODUCT_RRO_DIRS"]
348 if !reflect.DeepEqual(actualRRODirs, testCase.rroDirs[moduleName]) {
349 t.Errorf("exected %s LOCAL_SOONG_PRODUCT_RRO_DIRS entry: %v\ngot:%q",
350 moduleName, testCase.rroDirs[moduleName], actualRRODirs)
351 }
352 }
353 })
354 }
355}
Spandan Das5d1b9292021-06-03 19:36:41 +0000356
357func TestRuntimeResourceOverlayPartition(t *testing.T) {
358 bp := `
359 runtime_resource_overlay {
360 name: "device_specific",
361 device_specific: true,
362 }
363 runtime_resource_overlay {
364 name: "soc_specific",
365 soc_specific: true,
366 }
367 runtime_resource_overlay {
368 name: "system_ext_specific",
369 system_ext_specific: true,
370 }
371 runtime_resource_overlay {
372 name: "product_specific",
373 product_specific: true,
374 }
375 runtime_resource_overlay {
376 name: "default"
377 }
378 `
379 testCases := []struct {
380 name string
381 expectedPath string
382 }{
383 {
384 name: "device_specific",
385 expectedPath: "out/soong/target/product/test_device/odm/overlay",
386 },
387 {
388 name: "soc_specific",
389 expectedPath: "out/soong/target/product/test_device/vendor/overlay",
390 },
391 {
392 name: "system_ext_specific",
393 expectedPath: "out/soong/target/product/test_device/system_ext/overlay",
394 },
395 {
396 name: "product_specific",
397 expectedPath: "out/soong/target/product/test_device/product/overlay",
398 },
399 {
400 name: "default",
401 expectedPath: "out/soong/target/product/test_device/product/overlay",
402 },
403 }
404 for _, testCase := range testCases {
405 ctx, _ := testJava(t, bp)
406 mod := ctx.ModuleForTests(testCase.name, "android_common").Module().(*RuntimeResourceOverlay)
407 android.AssertPathRelativeToTopEquals(t, "Install dir is not correct for "+testCase.name, testCase.expectedPath, mod.installDir)
408 }
409}