blob: 0a2f8481f82a0a0e2d70e48b0625a503c8cd7c2c [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"
23)
24
25func TestRuntimeResourceOverlay(t *testing.T) {
26 fs := map[string][]byte{
27 "baz/res/res/values/strings.xml": nil,
28 "bar/res/res/values/strings.xml": nil,
29 }
30 bp := `
31 runtime_resource_overlay {
32 name: "foo",
33 certificate: "platform",
34 lineage: "lineage.bin",
35 product_specific: true,
36 static_libs: ["bar"],
37 resource_libs: ["baz"],
38 aaptflags: ["--keep-raw-values"],
39 }
40
41 runtime_resource_overlay {
42 name: "foo_themed",
43 certificate: "platform",
44 product_specific: true,
45 theme: "faza",
46 overrides: ["foo"],
47 }
48
49 android_library {
50 name: "bar",
51 resource_dirs: ["bar/res"],
52 }
53
54 android_app {
55 name: "baz",
56 sdk_version: "current",
57 resource_dirs: ["baz/res"],
58 }
59 `
60 config := testAppConfig(nil, bp, fs)
61 ctx := testContext(config)
62 run(t, ctx, config)
63
64 m := ctx.ModuleForTests("foo", "android_common")
65
66 // Check AAPT2 link flags.
67 aapt2Flags := m.Output("package-res.apk").Args["flags"]
68 expectedFlags := []string{"--keep-raw-values", "--no-resource-deduping", "--no-resource-removal"}
69 absentFlags := android.RemoveListFromList(expectedFlags, strings.Split(aapt2Flags, " "))
70 if len(absentFlags) > 0 {
71 t.Errorf("expected values, %q are missing in aapt2 link flags, %q", absentFlags, aapt2Flags)
72 }
73
74 // Check overlay.list output for static_libs dependency.
75 overlayList := m.Output("aapt2/overlay.list").Inputs.Strings()
76 staticLibPackage := buildDir + "/.intermediates/bar/android_common/package-res.apk"
77 if !inList(staticLibPackage, overlayList) {
78 t.Errorf("Stactic lib res package %q missing in overlay list: %q", staticLibPackage, overlayList)
79 }
80
81 // Check AAPT2 link flags for resource_libs dependency.
82 resourceLibFlag := "-I " + buildDir + "/.intermediates/baz/android_common/package-res.apk"
83 if !strings.Contains(aapt2Flags, resourceLibFlag) {
84 t.Errorf("Resource lib flag %q missing in aapt2 link flags: %q", resourceLibFlag, aapt2Flags)
85 }
86
87 // Check cert signing flag.
88 signedApk := m.Output("signed/foo.apk")
89 lineageFlag := signedApk.Args["flags"]
90 expectedLineageFlag := "--lineage lineage.bin"
91 if expectedLineageFlag != lineageFlag {
92 t.Errorf("Incorrect signing lineage flags, expected: %q, got: %q", expectedLineageFlag, lineageFlag)
93 }
94 signingFlag := signedApk.Args["certificates"]
95 expected := "build/make/target/product/security/platform.x509.pem build/make/target/product/security/platform.pk8"
96 if expected != signingFlag {
97 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
98 }
99 androidMkEntries := android.AndroidMkEntriesForTest(t, config, "", m.Module())[0]
100 path := androidMkEntries.EntryMap["LOCAL_CERTIFICATE"]
101 expectedPath := []string{"build/make/target/product/security/platform.x509.pem"}
102 if !reflect.DeepEqual(path, expectedPath) {
103 t.Errorf("Unexpected LOCAL_CERTIFICATE value: %v, expected: %v", path, expectedPath)
104 }
105
106 // Check device location.
107 path = androidMkEntries.EntryMap["LOCAL_MODULE_PATH"]
108 expectedPath = []string{"/tmp/target/product/test_device/product/overlay"}
109 if !reflect.DeepEqual(path, expectedPath) {
110 t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath)
111 }
112
113 // A themed module has a different device location
114 m = ctx.ModuleForTests("foo_themed", "android_common")
115 androidMkEntries = android.AndroidMkEntriesForTest(t, config, "", m.Module())[0]
116 path = androidMkEntries.EntryMap["LOCAL_MODULE_PATH"]
117 expectedPath = []string{"/tmp/target/product/test_device/product/overlay/faza"}
118 if !reflect.DeepEqual(path, expectedPath) {
119 t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath)
120 }
121
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) {
130 ctx, config := testJava(t, `
131 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.
162 path := android.AndroidMkEntriesForTest(t, config, "", m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
163 expectedPath := []string{"/tmp/target/product/test_device/product/overlay/default_theme"}
164 if !reflect.DeepEqual(path, expectedPath) {
165 t.Errorf("Unexpected LOCAL_MODULE_PATH value: %q, expected: %q", path, expectedPath)
166 }
167
168 //
169 // RRO module without defaults
170 //
171 m = ctx.ModuleForTests("foo_barebones", "android_common")
172
173 // Check AAPT2 link flags.
174 aapt2Flags = strings.Split(m.Output("package-res.apk").Args["flags"], " ")
175 unexpectedFlags := "--keep-raw-values"
176 if inList(unexpectedFlags, aapt2Flags) {
177 t.Errorf("unexpected value, %q is present in aapt2 link flags, %q", unexpectedFlags, aapt2Flags)
178 }
179
180 // Check device location.
181 path = android.AndroidMkEntriesForTest(t, config, "", m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
182 expectedPath = []string{"/tmp/target/product/test_device/system/overlay"}
183 if !reflect.DeepEqual(path, expectedPath) {
184 t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath)
185 }
186}
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",
216 apkPath: "/target/product/test_device/product/overlay/foo_overlay.apk",
217 overrides: nil,
218 targetVariant: "android_common",
219 packageFlag: "",
220 targetPackageFlag: "",
221 },
222 {
223 variantName: "android_common_bar_overlay",
224 apkPath: "/target/product/test_device/product/overlay/bar_overlay.apk",
225 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
235 outputs := variant.AllOutputs()
236 expectedApkPath := buildDir + expected.apkPath
237 found := false
238 for _, o := range outputs {
239 if o == expectedApkPath {
240 found = true
241 break
242 }
243 }
244 if !found {
245 t.Errorf("Can't find %q in output files.\nAll outputs:%v", expectedApkPath, outputs)
246 }
247
248 // Check if the overrides field values are correctly aggregated.
249 mod := variant.Module().(*RuntimeResourceOverlay)
250 if !reflect.DeepEqual(expected.overrides, mod.properties.Overrides) {
251 t.Errorf("Incorrect overrides property value, expected: %q, got: %q",
252 expected.overrides, mod.properties.Overrides)
253 }
254
255 // Check aapt2 flags.
256 res := variant.Output("package-res.apk")
257 aapt2Flags := res.Args["flags"]
258 checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
259 checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", "")
260 checkAapt2LinkFlag(t, aapt2Flags, "rename-overlay-target-package", expected.targetPackageFlag)
261 }
262}
263
264func TestEnforceRRO_propagatesToDependencies(t *testing.T) {
265 testCases := []struct {
Jeongik Chacee5ba92021-02-19 12:11:51 +0900266 name string
267 enforceRROTargets []string
268 rroDirs map[string][]string
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800269 }{
270 {
Jeongik Chacee5ba92021-02-19 12:11:51 +0900271 name: "no RRO",
272 enforceRROTargets: nil,
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800273 rroDirs: map[string][]string{
274 "foo": nil,
275 "bar": nil,
276 },
277 },
278 {
Jeongik Chacee5ba92021-02-19 12:11:51 +0900279 name: "enforce RRO on all",
280 enforceRROTargets: []string{"*"},
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800281 rroDirs: map[string][]string{
282 "foo": {"product/vendor/blah/overlay/lib2/res"},
283 "bar": {"product/vendor/blah/overlay/lib2/res"},
284 },
285 },
286 {
Jeongik Chacee5ba92021-02-19 12:11:51 +0900287 name: "enforce RRO on foo",
288 enforceRROTargets: []string{"foo"},
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800289 rroDirs: map[string][]string{
290 "foo": {"product/vendor/blah/overlay/lib2/res"},
291 "bar": {"product/vendor/blah/overlay/lib2/res"},
292 },
293 },
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800294 }
295
296 productResourceOverlays := []string{
297 "product/vendor/blah/overlay",
298 }
299
300 fs := map[string][]byte{
301 "lib2/res/values/strings.xml": nil,
302 "product/vendor/blah/overlay/lib2/res/values/strings.xml": nil,
303 }
304
305 bp := `
306 android_app {
307 name: "foo",
308 sdk_version: "current",
309 resource_dirs: [],
310 static_libs: ["lib"],
311 }
312
313 android_app {
314 name: "bar",
315 sdk_version: "current",
316 resource_dirs: [],
317 static_libs: ["lib"],
318 }
319
320 android_library {
321 name: "lib",
322 sdk_version: "current",
323 resource_dirs: [],
324 static_libs: ["lib2"],
325 }
326
327 android_library {
328 name: "lib2",
329 sdk_version: "current",
330 resource_dirs: ["lib2/res"],
331 }
332 `
333
334 for _, testCase := range testCases {
335 t.Run(testCase.name, func(t *testing.T) {
336 config := testAppConfig(nil, bp, fs)
337 config.TestProductVariables.ProductResourceOverlays = productResourceOverlays
338 if testCase.enforceRROTargets != nil {
339 config.TestProductVariables.EnforceRROTargets = testCase.enforceRROTargets
340 }
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800341
342 ctx := testContext(config)
343 run(t, ctx, config)
344
345 modules := []string{"foo", "bar"}
346 for _, moduleName := range modules {
347 module := ctx.ModuleForTests(moduleName, "android_common")
348 mkEntries := android.AndroidMkEntriesForTest(t, config, "", module.Module())[0]
349 actualRRODirs := mkEntries.EntryMap["LOCAL_SOONG_PRODUCT_RRO_DIRS"]
350 if !reflect.DeepEqual(actualRRODirs, testCase.rroDirs[moduleName]) {
351 t.Errorf("exected %s LOCAL_SOONG_PRODUCT_RRO_DIRS entry: %v\ngot:%q",
352 moduleName, testCase.rroDirs[moduleName], actualRRODirs)
353 }
354 }
355 })
356 }
357}