blob: afe3236dc6e022587063bafde3b4f993801c2e36 [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 }
Colin Crossaa255532020-07-03 13:18:24 -070099 androidMkEntries := android.AndroidMkEntriesForTest(t, ctx, m.Module())[0]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800100 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")
Colin Crossaa255532020-07-03 13:18:24 -0700115 androidMkEntries = android.AndroidMkEntriesForTest(t, ctx, m.Module())[0]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800116 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) {
Colin Crossaa255532020-07-03 13:18:24 -0700130 ctx, _ := 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"]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800163 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.
Colin Crossaa255532020-07-03 13:18:24 -0700181 path = android.AndroidMkEntriesForTest(t, ctx, m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800182 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 {
266 name string
267 enforceRROTargets []string
268 enforceRROExemptTargets []string
269 rroDirs map[string][]string
270 }{
271 {
272 name: "no RRO",
273 enforceRROTargets: nil,
274 enforceRROExemptTargets: nil,
275 rroDirs: map[string][]string{
276 "foo": nil,
277 "bar": nil,
278 },
279 },
280 {
281 name: "enforce RRO on all",
282 enforceRROTargets: []string{"*"},
283 enforceRROExemptTargets: nil,
284 rroDirs: map[string][]string{
285 "foo": {"product/vendor/blah/overlay/lib2/res"},
286 "bar": {"product/vendor/blah/overlay/lib2/res"},
287 },
288 },
289 {
290 name: "enforce RRO on foo",
291 enforceRROTargets: []string{"foo"},
292 enforceRROExemptTargets: nil,
293 rroDirs: map[string][]string{
294 "foo": {"product/vendor/blah/overlay/lib2/res"},
295 "bar": {"product/vendor/blah/overlay/lib2/res"},
296 },
297 },
298 {
299 name: "enforce RRO on foo, bar exempted",
300 enforceRROTargets: []string{"foo"},
301 enforceRROExemptTargets: []string{"bar"},
302 rroDirs: map[string][]string{
303 "foo": {"product/vendor/blah/overlay/lib2/res"},
304 "bar": nil,
305 },
306 },
307 }
308
309 productResourceOverlays := []string{
310 "product/vendor/blah/overlay",
311 }
312
313 fs := map[string][]byte{
314 "lib2/res/values/strings.xml": nil,
315 "product/vendor/blah/overlay/lib2/res/values/strings.xml": nil,
316 }
317
318 bp := `
319 android_app {
320 name: "foo",
321 sdk_version: "current",
322 resource_dirs: [],
323 static_libs: ["lib"],
324 }
325
326 android_app {
327 name: "bar",
328 sdk_version: "current",
329 resource_dirs: [],
330 static_libs: ["lib"],
331 }
332
333 android_library {
334 name: "lib",
335 sdk_version: "current",
336 resource_dirs: [],
337 static_libs: ["lib2"],
338 }
339
340 android_library {
341 name: "lib2",
342 sdk_version: "current",
343 resource_dirs: ["lib2/res"],
344 }
345 `
346
347 for _, testCase := range testCases {
348 t.Run(testCase.name, func(t *testing.T) {
349 config := testAppConfig(nil, bp, fs)
350 config.TestProductVariables.ProductResourceOverlays = productResourceOverlays
351 if testCase.enforceRROTargets != nil {
352 config.TestProductVariables.EnforceRROTargets = testCase.enforceRROTargets
353 }
354 if testCase.enforceRROExemptTargets != nil {
355 config.TestProductVariables.EnforceRROExemptedTargets = testCase.enforceRROExemptTargets
356 }
357
358 ctx := testContext(config)
359 run(t, ctx, config)
360
361 modules := []string{"foo", "bar"}
362 for _, moduleName := range modules {
363 module := ctx.ModuleForTests(moduleName, "android_common")
Colin Crossaa255532020-07-03 13:18:24 -0700364 mkEntries := android.AndroidMkEntriesForTest(t, ctx, module.Module())[0]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800365 actualRRODirs := mkEntries.EntryMap["LOCAL_SOONG_PRODUCT_RRO_DIRS"]
366 if !reflect.DeepEqual(actualRRODirs, testCase.rroDirs[moduleName]) {
367 t.Errorf("exected %s LOCAL_SOONG_PRODUCT_RRO_DIRS entry: %v\ngot:%q",
368 moduleName, testCase.rroDirs[moduleName], actualRRODirs)
369 }
370 }
371 })
372 }
373}