blob: 66d801dccc35da7463f4cf7a6b9e54d73e7b6ff6 [file] [log] [blame]
Colin Cross9bb9bfb2022-03-17 11:12:32 -07001// Copyright 2022 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 (
Sam Delmerico95d70942023-08-02 18:00:35 -040018 "fmt"
Jared Duke70b85422025-01-28 19:13:39 +000019 "strconv"
Colin Cross9bb9bfb2022-03-17 11:12:32 -070020 "testing"
21
22 "android/soong/android"
Sam Delmerico9f9c0a22022-11-29 11:19:37 -050023
24 "github.com/google/blueprint/proptools"
Colin Cross9bb9bfb2022-03-17 11:12:32 -070025)
26
27func TestR8(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -080028 t.Parallel()
Jiakai Zhangcf61e3c2023-05-08 16:28:38 +000029 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
Colin Cross9bb9bfb2022-03-17 11:12:32 -070030 android_app {
31 name: "app",
32 srcs: ["foo.java"],
33 libs: ["lib"],
34 static_libs: ["static_lib"],
35 platform_apis: true,
36 }
37
Jared Duke40d731a2022-09-20 15:32:14 -070038 android_app {
39 name: "stable_app",
40 srcs: ["foo.java"],
41 sdk_version: "current",
42 min_sdk_version: "31",
43 }
44
45 android_app {
46 name: "core_platform_app",
47 srcs: ["foo.java"],
48 sdk_version: "core_platform",
Spandan Dasc404cc72023-02-23 18:05:05 +000049 min_sdk_version: "31",
Jared Duke40d731a2022-09-20 15:32:14 -070050 }
51
Colin Cross9bb9bfb2022-03-17 11:12:32 -070052 java_library {
53 name: "lib",
54 srcs: ["foo.java"],
55 }
56
57 java_library {
58 name: "static_lib",
59 srcs: ["foo.java"],
60 }
61 `)
62
Colin Cross90607e92025-02-11 14:58:07 -080063 app := result.ModuleForTests(t, "app", "android_common")
64 stableApp := result.ModuleForTests(t, "stable_app", "android_common")
65 corePlatformApp := result.ModuleForTests(t, "core_platform_app", "android_common")
66 lib := result.ModuleForTests(t, "lib", "android_common")
67 staticLib := result.ModuleForTests(t, "static_lib", "android_common")
Colin Cross9bb9bfb2022-03-17 11:12:32 -070068
69 appJavac := app.Rule("javac")
70 appR8 := app.Rule("r8")
Jared Duke40d731a2022-09-20 15:32:14 -070071 stableAppR8 := stableApp.Rule("r8")
72 corePlatformAppR8 := corePlatformApp.Rule("r8")
Colin Cross8ff4af32025-02-19 15:17:02 -080073 libHeader := lib.Output("turbine/lib.jar").Output
74 libCombinedHeader := lib.Output("turbine-combined/lib.jar").Output
75 staticLibHeader := staticLib.Output("turbine/static_lib.jar").Output
Colin Cross9bb9bfb2022-03-17 11:12:32 -070076
77 android.AssertStringDoesContain(t, "expected lib header jar in app javac classpath",
78 appJavac.Args["classpath"], libHeader.String())
79 android.AssertStringDoesContain(t, "expected static_lib header jar in app javac classpath",
80 appJavac.Args["classpath"], staticLibHeader.String())
81
Colin Cross8ff4af32025-02-19 15:17:02 -080082 android.AssertStringDoesContain(t, "expected lib combined header jar in app r8 classpath",
83 appR8.Args["r8Flags"], libCombinedHeader.String())
Sam Delmerico9f9c0a22022-11-29 11:19:37 -050084 android.AssertStringDoesNotContain(t, "expected no static_lib header jar in app r8 classpath",
Colin Cross9bb9bfb2022-03-17 11:12:32 -070085 appR8.Args["r8Flags"], staticLibHeader.String())
Remi NGUYEN VANbdad3142022-08-04 13:19:03 +090086 android.AssertStringDoesContain(t, "expected -ignorewarnings in app r8 flags",
87 appR8.Args["r8Flags"], "-ignorewarnings")
Jared Duke40d731a2022-09-20 15:32:14 -070088 android.AssertStringDoesContain(t, "expected --android-platform-build in app r8 flags",
89 appR8.Args["r8Flags"], "--android-platform-build")
90 android.AssertStringDoesNotContain(t, "expected no --android-platform-build in stable_app r8 flags",
91 stableAppR8.Args["r8Flags"], "--android-platform-build")
92 android.AssertStringDoesContain(t, "expected --android-platform-build in core_platform_app r8 flags",
93 corePlatformAppR8.Args["r8Flags"], "--android-platform-build")
Remi NGUYEN VANbdad3142022-08-04 13:19:03 +090094}
95
Sam Delmerico9f9c0a22022-11-29 11:19:37 -050096func TestR8TransitiveDeps(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -080097 t.Parallel()
Sam Delmerico9f9c0a22022-11-29 11:19:37 -050098 bp := `
99 override_android_app {
100 name: "override_app",
101 base: "app",
102 }
103
104 android_app {
105 name: "app",
106 srcs: ["foo.java"],
107 libs: [
108 "lib",
109 "uses_libs_dep_import",
110 ],
111 static_libs: [
112 "static_lib",
113 "repeated_dep",
114 ],
115 platform_apis: true,
116 }
117
118 java_library {
119 name: "static_lib",
120 srcs: ["foo.java"],
121 }
122
123 java_library {
124 name: "lib",
125 libs: [
126 "transitive_lib",
127 "repeated_dep",
128 "prebuilt_lib",
129 ],
130 static_libs: ["transitive_static_lib"],
131 srcs: ["foo.java"],
132 }
133
134 java_library {
135 name: "repeated_dep",
136 srcs: ["foo.java"],
137 }
138
139 java_library {
140 name: "transitive_static_lib",
141 srcs: ["foo.java"],
142 }
143
144 java_library {
145 name: "transitive_lib",
146 srcs: ["foo.java"],
147 libs: ["transitive_lib_2"],
148 }
149
150 java_library {
151 name: "transitive_lib_2",
152 srcs: ["foo.java"],
153 }
154
155 java_import {
156 name: "lib",
157 jars: ["lib.jar"],
158 }
159
160 java_library {
161 name: "uses_lib",
162 srcs: ["foo.java"],
163 }
164
165 java_library {
166 name: "optional_uses_lib",
167 srcs: ["foo.java"],
168 }
169
170 android_library {
171 name: "uses_libs_dep",
172 uses_libs: ["uses_lib"],
173 optional_uses_libs: ["optional_uses_lib"],
174 }
175
176 android_library_import {
177 name: "uses_libs_dep_import",
178 aars: ["aar.aar"],
179 static_libs: ["uses_libs_dep"],
180 }
181 `
182
183 testcases := []struct {
184 name string
185 unbundled bool
186 }{
187 {
188 name: "non-unbundled build",
189 unbundled: false,
190 },
191 {
192 name: "unbundled build",
193 unbundled: true,
194 },
195 }
196
197 for _, tc := range testcases {
198 t.Run(tc.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800199 t.Parallel()
Jiakai Zhangcf61e3c2023-05-08 16:28:38 +0000200 fixturePreparer := PrepareForTestWithJavaDefaultModules
Sam Delmerico9f9c0a22022-11-29 11:19:37 -0500201 if tc.unbundled {
202 fixturePreparer = android.GroupFixturePreparers(
203 fixturePreparer,
204 android.FixtureModifyProductVariables(
205 func(variables android.FixtureProductVariables) {
206 variables.Unbundled_build = proptools.BoolPtr(true)
207 },
208 ),
209 )
210 }
211 result := fixturePreparer.RunTestWithBp(t, bp)
212
213 getHeaderJar := func(name string) android.Path {
Colin Cross90607e92025-02-11 14:58:07 -0800214 mod := result.ModuleForTests(t, name, "android_common")
Sam Delmerico9f9c0a22022-11-29 11:19:37 -0500215 return mod.Output("turbine-combined/" + name + ".jar").Output
216 }
217
Colin Cross90607e92025-02-11 14:58:07 -0800218 appR8 := result.ModuleForTests(t, "app", "android_common").Rule("r8")
219 overrideAppR8 := result.ModuleForTests(t, "app", "android_common_override_app").Rule("r8")
Sam Delmerico9f9c0a22022-11-29 11:19:37 -0500220 appHeader := getHeaderJar("app")
Colin Cross90607e92025-02-11 14:58:07 -0800221 overrideAppHeader := result.ModuleForTests(t, "app", "android_common_override_app").Output("turbine-combined/app.jar").Output
Sam Delmerico9f9c0a22022-11-29 11:19:37 -0500222 libHeader := getHeaderJar("lib")
223 transitiveLibHeader := getHeaderJar("transitive_lib")
224 transitiveLib2Header := getHeaderJar("transitive_lib_2")
225 staticLibHeader := getHeaderJar("static_lib")
226 transitiveStaticLibHeader := getHeaderJar("transitive_static_lib")
227 repeatedDepHeader := getHeaderJar("repeated_dep")
228 usesLibHeader := getHeaderJar("uses_lib")
229 optionalUsesLibHeader := getHeaderJar("optional_uses_lib")
Colin Cross90607e92025-02-11 14:58:07 -0800230 prebuiltLibHeader := result.ModuleForTests(t, "prebuilt_lib", "android_common").Output("combined/lib.jar").Output
Sam Delmerico9f9c0a22022-11-29 11:19:37 -0500231
232 for _, rule := range []android.TestingBuildParams{appR8, overrideAppR8} {
233 android.AssertStringDoesNotContain(t, "expected no app header jar in app r8 classpath",
234 rule.Args["r8Flags"], appHeader.String())
235 android.AssertStringDoesNotContain(t, "expected no override_app header jar in app r8 classpath",
236 rule.Args["r8Flags"], overrideAppHeader.String())
237 android.AssertStringDoesContain(t, "expected transitive lib header jar in app r8 classpath",
238 rule.Args["r8Flags"], transitiveLibHeader.String())
239 android.AssertStringDoesContain(t, "expected transitive lib ^2 header jar in app r8 classpath",
240 rule.Args["r8Flags"], transitiveLib2Header.String())
241 android.AssertStringDoesContain(t, "expected lib header jar in app r8 classpath",
242 rule.Args["r8Flags"], libHeader.String())
243 android.AssertStringDoesContain(t, "expected uses_lib header jar in app r8 classpath",
244 rule.Args["r8Flags"], usesLibHeader.String())
245 android.AssertStringDoesContain(t, "expected optional_uses_lib header jar in app r8 classpath",
246 rule.Args["r8Flags"], optionalUsesLibHeader.String())
247 android.AssertStringDoesNotContain(t, "expected no static_lib header jar in app r8 classpath",
248 rule.Args["r8Flags"], staticLibHeader.String())
249 android.AssertStringDoesNotContain(t, "expected no transitive static_lib header jar in app r8 classpath",
250 rule.Args["r8Flags"], transitiveStaticLibHeader.String())
251 // we shouldn't list this dep because it is already included as static_libs in the app
252 android.AssertStringDoesNotContain(t, "expected no repeated_dep header jar in app r8 classpath",
253 rule.Args["r8Flags"], repeatedDepHeader.String())
254 // skip a prebuilt transitive dep if the source is also a transitive dep
255 android.AssertStringDoesNotContain(t, "expected no prebuilt header jar in app r8 classpath",
256 rule.Args["r8Flags"], prebuiltLibHeader.String())
257 android.AssertStringDoesContain(t, "expected -ignorewarnings in app r8 flags",
258 rule.Args["r8Flags"], "-ignorewarnings")
259 android.AssertStringDoesContain(t, "expected --android-platform-build in app r8 flags",
260 rule.Args["r8Flags"], "--android-platform-build")
261 }
262 })
263 }
264}
265
Remi NGUYEN VANbdad3142022-08-04 13:19:03 +0900266func TestR8Flags(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800267 t.Parallel()
Jiakai Zhangcf61e3c2023-05-08 16:28:38 +0000268 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
Remi NGUYEN VANbdad3142022-08-04 13:19:03 +0900269 android_app {
270 name: "app",
271 srcs: ["foo.java"],
272 platform_apis: true,
273 optimize: {
274 shrink: false,
275 optimize: false,
276 obfuscate: false,
277 ignore_warnings: false,
278 },
279 }
280 `)
281
Colin Cross90607e92025-02-11 14:58:07 -0800282 app := result.ModuleForTests(t, "app", "android_common")
Remi NGUYEN VANbdad3142022-08-04 13:19:03 +0900283 appR8 := app.Rule("r8")
284 android.AssertStringDoesContain(t, "expected -dontshrink in app r8 flags",
285 appR8.Args["r8Flags"], "-dontshrink")
286 android.AssertStringDoesContain(t, "expected -dontoptimize in app r8 flags",
287 appR8.Args["r8Flags"], "-dontoptimize")
288 android.AssertStringDoesContain(t, "expected -dontobfuscate in app r8 flags",
289 appR8.Args["r8Flags"], "-dontobfuscate")
290 android.AssertStringDoesNotContain(t, "expected no -ignorewarnings in app r8 flags",
291 appR8.Args["r8Flags"], "-ignorewarnings")
Jared Duke40d731a2022-09-20 15:32:14 -0700292 android.AssertStringDoesContain(t, "expected --android-platform-build in app r8 flags",
293 appR8.Args["r8Flags"], "--android-platform-build")
Colin Cross9bb9bfb2022-03-17 11:12:32 -0700294}
295
296func TestD8(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800297 t.Parallel()
Jiakai Zhangcf61e3c2023-05-08 16:28:38 +0000298 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
Colin Cross9bb9bfb2022-03-17 11:12:32 -0700299 java_library {
300 name: "foo",
301 srcs: ["foo.java"],
302 libs: ["lib"],
303 static_libs: ["static_lib"],
304 installable: true,
305 }
306
307 java_library {
308 name: "lib",
309 srcs: ["foo.java"],
310 }
311
312 java_library {
313 name: "static_lib",
314 srcs: ["foo.java"],
315 }
Jared Duke70b85422025-01-28 19:13:39 +0000316
317 android_app {
318 name: "app",
319 srcs: ["foo.java"],
320 platform_apis: true,
321 optimize: {
322 enabled: false,
323 },
324 }
Colin Cross9bb9bfb2022-03-17 11:12:32 -0700325 `)
326
Colin Cross90607e92025-02-11 14:58:07 -0800327 foo := result.ModuleForTests(t, "foo", "android_common")
328 lib := result.ModuleForTests(t, "lib", "android_common")
329 app := result.ModuleForTests(t, "app", "android_common")
330 staticLib := result.ModuleForTests(t, "static_lib", "android_common")
Colin Cross9bb9bfb2022-03-17 11:12:32 -0700331
332 fooJavac := foo.Rule("javac")
333 fooD8 := foo.Rule("d8")
Jared Duke70b85422025-01-28 19:13:39 +0000334 appD8 := app.Rule("d8")
Colin Cross8ff4af32025-02-19 15:17:02 -0800335 libHeader := lib.Output("turbine/lib.jar").Output
336 libCombinedHeader := lib.Output("turbine-combined/lib.jar").Output
337 staticLibHeader := staticLib.Output("turbine/static_lib.jar").Output
Colin Cross9bb9bfb2022-03-17 11:12:32 -0700338
339 android.AssertStringDoesContain(t, "expected lib header jar in foo javac classpath",
340 fooJavac.Args["classpath"], libHeader.String())
341 android.AssertStringDoesContain(t, "expected static_lib header jar in foo javac classpath",
342 fooJavac.Args["classpath"], staticLibHeader.String())
343
Colin Cross8ff4af32025-02-19 15:17:02 -0800344 android.AssertStringDoesContain(t, "expected lib combined header jar in foo d8 classpath",
345 fooD8.Args["d8Flags"], libCombinedHeader.String())
Colin Cross9bb9bfb2022-03-17 11:12:32 -0700346 android.AssertStringDoesNotContain(t, "expected no static_lib header jar in foo javac classpath",
347 fooD8.Args["d8Flags"], staticLibHeader.String())
Jared Duke70b85422025-01-28 19:13:39 +0000348
349 // A --release flag is added only for targets that opt out of default R8 behavior (e.g., apps).
350 // For library targets that don't use R8 by default, no --debug or --release flag should be
351 // added, instead relying on default D8 behavior (--debug).
352 android.AssertStringDoesContain(t, "expected --release in app d8 flags",
353 appD8.Args["d8Flags"], "--release")
354 android.AssertStringDoesNotContain(t, "expected no --release flag in lib d8 flags",
355 fooD8.Args["d8Flags"], "--release")
356 android.AssertStringDoesNotContain(t, "expected no --debug flag in lib d8 flags",
357 fooD8.Args["d8Flags"], "--debug")
Colin Cross9bb9bfb2022-03-17 11:12:32 -0700358}
Jared Duke5979b302022-12-19 21:08:39 +0000359
Sam Delmerico95d70942023-08-02 18:00:35 -0400360func TestProguardFlagsInheritanceStatic(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800361 t.Parallel()
Jiakai Zhangcf61e3c2023-05-08 16:28:38 +0000362 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
Jared Duke5979b302022-12-19 21:08:39 +0000363 android_app {
364 name: "app",
365 static_libs: [
366 "primary_android_lib",
367 "primary_lib",
368 ],
369 platform_apis: true,
370 }
371
372 java_library {
373 name: "primary_lib",
374 optimize: {
375 proguard_flags_files: ["primary.flags"],
376 },
377 }
378
379 android_library {
380 name: "primary_android_lib",
381 static_libs: ["secondary_lib"],
382 optimize: {
383 proguard_flags_files: ["primary_android.flags"],
384 },
385 }
386
387 java_library {
388 name: "secondary_lib",
389 static_libs: ["tertiary_lib"],
390 optimize: {
391 proguard_flags_files: ["secondary.flags"],
392 },
393 }
394
395 java_library {
396 name: "tertiary_lib",
397 optimize: {
398 proguard_flags_files: ["tertiary.flags"],
399 },
400 }
401 `)
402
Colin Cross90607e92025-02-11 14:58:07 -0800403 app := result.ModuleForTests(t, "app", "android_common")
Jared Duke5979b302022-12-19 21:08:39 +0000404 appR8 := app.Rule("r8")
405 android.AssertStringDoesContain(t, "expected primary_lib's proguard flags from direct dep",
406 appR8.Args["r8Flags"], "primary.flags")
407 android.AssertStringDoesContain(t, "expected primary_android_lib's proguard flags from direct dep",
408 appR8.Args["r8Flags"], "primary_android.flags")
409 android.AssertStringDoesContain(t, "expected secondary_lib's proguard flags from inherited dep",
410 appR8.Args["r8Flags"], "secondary.flags")
411 android.AssertStringDoesContain(t, "expected tertiary_lib's proguard flags from inherited dep",
412 appR8.Args["r8Flags"], "tertiary.flags")
413}
Sam Delmerico95d70942023-08-02 18:00:35 -0400414
415func TestProguardFlagsInheritance(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800416 t.Parallel()
Sam Delmerico95d70942023-08-02 18:00:35 -0400417 directDepFlagsFileName := "direct_dep.flags"
418 transitiveDepFlagsFileName := "transitive_dep.flags"
Sam Delmerico95d70942023-08-02 18:00:35 -0400419
Sam Delmericoc8e040c2023-10-31 17:27:02 +0000420 topLevelModules := []struct {
421 name string
422 definition string
423 }{
424 {
425 name: "android_app",
426 definition: `
427 android_app {
428 name: "app",
429 static_libs: ["androidlib"], // this must be static_libs to initate dexing
430 platform_apis: true,
431 }
432 `,
433 },
434 {
435 name: "android_library",
436 definition: `
437 android_library {
438 name: "app",
439 static_libs: ["androidlib"], // this must be static_libs to initate dexing
440 installable: true,
441 optimize: {
442 enabled: true,
443 shrink: true,
444 },
445 }
446 `,
447 },
448 {
449 name: "java_library",
450 definition: `
451 java_library {
452 name: "app",
453 static_libs: ["androidlib"], // this must be static_libs to initate dexing
454 srcs: ["Foo.java"],
455 installable: true,
456 optimize: {
457 enabled: true,
458 shrink: true,
459 },
460 }
461 `,
462 },
463 }
464
465 bp := `
Sam Delmerico95d70942023-08-02 18:00:35 -0400466 android_library {
467 name: "androidlib",
468 static_libs: ["app_dep"],
469 }
470
471 java_library {
472 name: "app_dep",
473 %s: ["dep"],
474 }
475
476 java_library {
477 name: "dep",
478 %s: ["transitive_dep"],
479 optimize: {
480 proguard_flags_files: ["direct_dep.flags"],
481 export_proguard_flags_files: %v,
482 },
483 }
484
485 java_library {
486 name: "transitive_dep",
487 optimize: {
488 proguard_flags_files: ["transitive_dep.flags"],
489 export_proguard_flags_files: %v,
490 },
491 }
492 `
493
494 testcases := []struct {
495 name string
496 depType string
497 depExportsFlagsFiles bool
498 transitiveDepType string
499 transitiveDepExportsFlagsFiles bool
500 expectedFlagsFiles []string
501 }{
502 {
503 name: "libs_export_libs_export",
504 depType: "libs",
505 depExportsFlagsFiles: true,
506 transitiveDepType: "libs",
507 transitiveDepExportsFlagsFiles: true,
508 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
509 },
510 {
511 name: "static_export_libs_export",
512 depType: "static_libs",
513 depExportsFlagsFiles: true,
514 transitiveDepType: "libs",
515 transitiveDepExportsFlagsFiles: true,
516 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
517 },
518 {
519 name: "libs_no-export_static_export",
520 depType: "libs",
521 depExportsFlagsFiles: false,
522 transitiveDepType: "static_libs",
523 transitiveDepExportsFlagsFiles: true,
524 expectedFlagsFiles: []string{transitiveDepFlagsFileName},
525 },
526 {
527 name: "static_no-export_static_export",
528 depType: "static_libs",
529 depExportsFlagsFiles: false,
530 transitiveDepType: "static_libs",
531 transitiveDepExportsFlagsFiles: true,
532 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
533 },
534 {
535 name: "libs_export_libs_no-export",
536 depType: "libs",
537 depExportsFlagsFiles: true,
538 transitiveDepType: "libs",
539 transitiveDepExportsFlagsFiles: false,
540 expectedFlagsFiles: []string{directDepFlagsFileName},
541 },
542 {
543 name: "static_export_libs_no-export",
544 depType: "static_libs",
545 depExportsFlagsFiles: true,
546 transitiveDepType: "libs",
547 transitiveDepExportsFlagsFiles: false,
548 expectedFlagsFiles: []string{directDepFlagsFileName},
549 },
550 {
551 name: "libs_no-export_static_no-export",
552 depType: "libs",
553 depExportsFlagsFiles: false,
554 transitiveDepType: "static_libs",
555 transitiveDepExportsFlagsFiles: false,
556 expectedFlagsFiles: []string{},
557 },
558 {
559 name: "static_no-export_static_no-export",
560 depType: "static_libs",
561 depExportsFlagsFiles: false,
562 transitiveDepType: "static_libs",
563 transitiveDepExportsFlagsFiles: false,
564 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
565 },
566 {
567 name: "libs_no-export_libs_export",
568 depType: "libs",
569 depExportsFlagsFiles: false,
570 transitiveDepType: "libs",
571 transitiveDepExportsFlagsFiles: true,
572 expectedFlagsFiles: []string{transitiveDepFlagsFileName},
573 },
574 {
575 name: "static_no-export_libs_export",
576 depType: "static_libs",
577 depExportsFlagsFiles: false,
578 transitiveDepType: "libs",
579 transitiveDepExportsFlagsFiles: true,
580 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
581 },
582 {
583 name: "libs_export_static_export",
584 depType: "libs",
585 depExportsFlagsFiles: true,
586 transitiveDepType: "static_libs",
587 transitiveDepExportsFlagsFiles: true,
588 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
589 },
590 {
591 name: "static_export_static_export",
592 depType: "static_libs",
593 depExportsFlagsFiles: true,
594 transitiveDepType: "static_libs",
595 transitiveDepExportsFlagsFiles: true,
596 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
597 },
598 {
599 name: "libs_no-export_libs_no-export",
600 depType: "libs",
601 depExportsFlagsFiles: false,
602 transitiveDepType: "libs",
603 transitiveDepExportsFlagsFiles: false,
604 expectedFlagsFiles: []string{},
605 },
606 {
607 name: "static_no-export_libs_no-export",
608 depType: "static_libs",
609 depExportsFlagsFiles: false,
610 transitiveDepType: "libs",
611 transitiveDepExportsFlagsFiles: false,
612 expectedFlagsFiles: []string{directDepFlagsFileName},
613 },
614 {
615 name: "libs_export_static_no-export",
616 depType: "libs",
617 depExportsFlagsFiles: true,
618 transitiveDepType: "static_libs",
619 transitiveDepExportsFlagsFiles: false,
620 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
621 },
622 {
623 name: "static_export_static_no-export",
624 depType: "static_libs",
625 depExportsFlagsFiles: true,
626 transitiveDepType: "static_libs",
627 transitiveDepExportsFlagsFiles: false,
628 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
629 },
630 }
631
Sam Delmericoc8e040c2023-10-31 17:27:02 +0000632 for _, topLevelModuleDef := range topLevelModules {
633 for _, tc := range testcases {
634 t.Run(topLevelModuleDef.name+"-"+tc.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800635 t.Parallel()
Sam Delmericoc8e040c2023-10-31 17:27:02 +0000636 result := android.GroupFixturePreparers(
637 PrepareForTestWithJavaDefaultModules,
638 android.FixtureMergeMockFs(android.MockFS{
639 directDepFlagsFileName: nil,
640 transitiveDepFlagsFileName: nil,
641 }),
642 ).RunTestWithBp(t,
643 topLevelModuleDef.definition+
644 fmt.Sprintf(
645 bp,
646 tc.depType,
647 tc.transitiveDepType,
648 tc.depExportsFlagsFiles,
649 tc.transitiveDepExportsFlagsFiles,
650 ),
651 )
Colin Cross90607e92025-02-11 14:58:07 -0800652 appR8 := result.ModuleForTests(t, "app", "android_common").Rule("r8")
Sam Delmerico95d70942023-08-02 18:00:35 -0400653
Sam Delmericoc8e040c2023-10-31 17:27:02 +0000654 shouldHaveDepFlags := android.InList(directDepFlagsFileName, tc.expectedFlagsFiles)
655 if shouldHaveDepFlags {
656 android.AssertStringDoesContain(t, "expected deps's proguard flags",
657 appR8.Args["r8Flags"], directDepFlagsFileName)
658 } else {
659 android.AssertStringDoesNotContain(t, "app did not expect deps's proguard flags",
660 appR8.Args["r8Flags"], directDepFlagsFileName)
661 }
Sam Delmerico95d70942023-08-02 18:00:35 -0400662
Sam Delmericoc8e040c2023-10-31 17:27:02 +0000663 shouldHaveTransitiveDepFlags := android.InList(transitiveDepFlagsFileName, tc.expectedFlagsFiles)
664 if shouldHaveTransitiveDepFlags {
665 android.AssertStringDoesContain(t, "expected transitive deps's proguard flags",
666 appR8.Args["r8Flags"], transitiveDepFlagsFileName)
667 } else {
668 android.AssertStringDoesNotContain(t, "app did not expect transitive deps's proguard flags",
669 appR8.Args["r8Flags"], transitiveDepFlagsFileName)
670 }
671 })
672 }
Sam Delmerico95d70942023-08-02 18:00:35 -0400673 }
674}
675
676func TestProguardFlagsInheritanceAppImport(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800677 t.Parallel()
Sam Delmerico95d70942023-08-02 18:00:35 -0400678 bp := `
679 android_app {
680 name: "app",
681 static_libs: ["aarimport"], // this must be static_libs to initate dexing
682 platform_apis: true,
683 }
684
Sam Delmerico95d70942023-08-02 18:00:35 -0400685 android_library_import {
686 name: "aarimport",
687 aars: ["import.aar"],
688 }
689 `
690 result := android.GroupFixturePreparers(
691 PrepareForTestWithJavaDefaultModules,
692 ).RunTestWithBp(t, bp)
693
Colin Cross90607e92025-02-11 14:58:07 -0800694 appR8 := result.ModuleForTests(t, "app", "android_common").Rule("r8")
Sam Delmerico95d70942023-08-02 18:00:35 -0400695 android.AssertStringDoesContain(t, "expected aarimports's proguard flags",
696 appR8.Args["r8Flags"], "proguard.txt")
697}
Spandan Das3dbda182024-05-20 22:23:10 +0000698
699func TestR8FlagsArtProfile(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800700 t.Parallel()
Spandan Das3dbda182024-05-20 22:23:10 +0000701 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
702 android_app {
703 name: "app",
704 srcs: ["foo.java"],
705 platform_apis: true,
706 dex_preopt: {
707 profile_guided: true,
708 profile: "profile.txt.prof",
709 enable_profile_rewriting: true,
710 },
711 }
712 `)
713
Colin Cross90607e92025-02-11 14:58:07 -0800714 app := result.ModuleForTests(t, "app", "android_common")
Spandan Das3dbda182024-05-20 22:23:10 +0000715 appR8 := app.Rule("r8")
716 android.AssertStringDoesContain(t, "expected --art-profile in app r8 flags",
717 appR8.Args["r8Flags"], "--art-profile")
718
719 appDexpreopt := app.Rule("dexpreopt")
720 android.AssertStringDoesContain(t,
721 "expected --art-profile output to be used to create .prof binary",
722 appDexpreopt.RuleParams.Command,
723 "--create-profile-from=out/soong/.intermediates/app/android_common/profile.prof.txt --output-profile-type=app",
724 )
725}
Spandan Das15a67112024-05-30 00:07:40 +0000726
727// This test checks that users explicitly set `enable_profile_rewriting` to true when the following are true
728// 1. optimize or obfuscate is enabled AND
729// 2. dex_preopt.profile_guided is enabled
730//
731// The rewritten profile should be used since the dex signatures in the checked-in profile will not match the optimized binary.
732func TestEnableProfileRewritingIsRequiredForOptimizedApps(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800733 t.Parallel()
Spandan Das15a67112024-05-30 00:07:40 +0000734 testJavaError(t,
735 "Enable_profile_rewriting must be true when profile_guided dexpreopt and R8 optimization/obfuscation is turned on",
736 `
737android_app {
738 name: "app",
739 srcs: ["foo.java"],
740 platform_apis: true,
741 dex_preopt: {
742 profile_guided: true,
743 profile: "profile.txt.prof",
744 // enable_profile_rewriting is not set, this is an error
745 },
746 optimize: {
747 optimize: true,
748 }
749}`)
750}
Jared Duked32e85f2024-09-25 23:54:30 +0000751
752func TestDebugReleaseFlags(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800753 t.Parallel()
Jared Duked32e85f2024-09-25 23:54:30 +0000754 bp := `
755 android_app {
756 name: "app",
757 srcs: ["foo.java"],
758 platform_apis: true,
Jared Duke70b85422025-01-28 19:13:39 +0000759 optimize: {
760 enabled: %s,
761 },
Jared Duked32e85f2024-09-25 23:54:30 +0000762 dxflags: ["%s"]
763 }
764 `
765
766 testcases := []struct {
767 name string
768 envVar string
769 isEng bool
Jared Duke70b85422025-01-28 19:13:39 +0000770 useD8 bool
Jared Duked32e85f2024-09-25 23:54:30 +0000771 dxFlags string
772 expectedFlags string
773 }{
774 {
775 name: "app_no_optimize_dx",
776 envVar: "NO_OPTIMIZE_DX",
777 expectedFlags: "--debug",
778 },
779 {
780 name: "app_release_no_optimize_dx",
781 envVar: "NO_OPTIMIZE_DX",
782 dxFlags: "--release",
783 // Global env vars override explicit dxflags.
784 expectedFlags: "--debug",
785 },
786 {
787 name: "app_generate_dex_debug",
788 envVar: "GENERATE_DEX_DEBUG",
789 expectedFlags: "--debug",
790 },
791 {
792 name: "app_release_generate_dex_debug",
793 envVar: "GENERATE_DEX_DEBUG",
794 dxFlags: "--release",
795 // Global env vars override explicit dxflags.
796 expectedFlags: "--debug",
797 },
798 {
799 name: "app_eng",
800 isEng: true,
801 expectedFlags: "--debug",
802 },
803 {
804 name: "app_release_eng",
805 isEng: true,
806 dxFlags: "--release",
807 // Eng mode does *not* override explicit dxflags.
808 expectedFlags: "--release",
809 },
Jared Duke70b85422025-01-28 19:13:39 +0000810 {
811 name: "app_d8",
812 useD8: true,
813 // D8 usage w/ apps should explicitly enable --release mode.
814 expectedFlags: "--release",
815 },
816 {
817 name: "app_d8_debug",
818 useD8: true,
819 dxFlags: "--debug",
820 // D8 usage w/ apps respects overriding dxFlags.
821 expectedFlags: "--debug",
822 },
Jared Duked32e85f2024-09-25 23:54:30 +0000823 }
824
825 for _, tc := range testcases {
826 t.Run(tc.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800827 t.Parallel()
Jared Duked32e85f2024-09-25 23:54:30 +0000828 fixturePreparer := PrepareForTestWithJavaDefaultModules
829 fixturePreparer = android.GroupFixturePreparers(
830 fixturePreparer,
831 android.FixtureModifyProductVariables(
832 func(variables android.FixtureProductVariables) {
833 variables.Eng = proptools.BoolPtr(tc.isEng)
834 },
835 ),
836 )
837 if tc.envVar != "" {
838 fixturePreparer = android.GroupFixturePreparers(
839 fixturePreparer,
840 android.FixtureMergeEnv(map[string]string{
841 tc.envVar: "true",
842 }),
843 )
844 }
Jared Duke70b85422025-01-28 19:13:39 +0000845 result := fixturePreparer.RunTestWithBp(t, fmt.Sprintf(bp, strconv.FormatBool(!tc.useD8), tc.dxFlags))
Jared Duked32e85f2024-09-25 23:54:30 +0000846
Jared Duke70b85422025-01-28 19:13:39 +0000847 dexRuleKey := "r8"
848 if tc.useD8 {
849 dexRuleKey = "d8"
850 }
851 dexFlagsKey := dexRuleKey + "Flags"
Colin Cross90607e92025-02-11 14:58:07 -0800852 appDex := result.ModuleForTests(t, "app", "android_common").Rule(dexRuleKey)
Jared Duke70b85422025-01-28 19:13:39 +0000853 android.AssertStringDoesContain(t, "expected flag in dex flags",
854 appDex.Args[dexFlagsKey], tc.expectedFlags)
Jared Duked32e85f2024-09-25 23:54:30 +0000855
856 var unexpectedFlags string
857 if tc.expectedFlags == "--debug" {
858 unexpectedFlags = "--release"
859 } else if tc.expectedFlags == "--release" {
860 unexpectedFlags = "--debug"
861 }
862 if unexpectedFlags != "" {
Jared Duke70b85422025-01-28 19:13:39 +0000863 android.AssertStringDoesNotContain(t, "unexpected flag in dex flags",
864 appDex.Args[dexFlagsKey], unexpectedFlags)
Jared Duked32e85f2024-09-25 23:54:30 +0000865 }
866 })
867 }
868}