blob: d52d93717cbf02b7c534e2fa247eae0787ad6c0b [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) {
Jiakai Zhangcf61e3c2023-05-08 16:28:38 +000028 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
Colin Cross9bb9bfb2022-03-17 11:12:32 -070029 android_app {
30 name: "app",
31 srcs: ["foo.java"],
32 libs: ["lib"],
33 static_libs: ["static_lib"],
34 platform_apis: true,
35 }
36
Jared Duke40d731a2022-09-20 15:32:14 -070037 android_app {
38 name: "stable_app",
39 srcs: ["foo.java"],
40 sdk_version: "current",
41 min_sdk_version: "31",
42 }
43
44 android_app {
45 name: "core_platform_app",
46 srcs: ["foo.java"],
47 sdk_version: "core_platform",
Spandan Dasc404cc72023-02-23 18:05:05 +000048 min_sdk_version: "31",
Jared Duke40d731a2022-09-20 15:32:14 -070049 }
50
Colin Cross9bb9bfb2022-03-17 11:12:32 -070051 java_library {
52 name: "lib",
53 srcs: ["foo.java"],
54 }
55
56 java_library {
57 name: "static_lib",
58 srcs: ["foo.java"],
59 }
60 `)
61
62 app := result.ModuleForTests("app", "android_common")
Jared Duke40d731a2022-09-20 15:32:14 -070063 stableApp := result.ModuleForTests("stable_app", "android_common")
64 corePlatformApp := result.ModuleForTests("core_platform_app", "android_common")
Colin Cross9bb9bfb2022-03-17 11:12:32 -070065 lib := result.ModuleForTests("lib", "android_common")
66 staticLib := result.ModuleForTests("static_lib", "android_common")
67
68 appJavac := app.Rule("javac")
69 appR8 := app.Rule("r8")
Jared Duke40d731a2022-09-20 15:32:14 -070070 stableAppR8 := stableApp.Rule("r8")
71 corePlatformAppR8 := corePlatformApp.Rule("r8")
Colin Cross9bb9bfb2022-03-17 11:12:32 -070072 libHeader := lib.Output("turbine-combined/lib.jar").Output
73 staticLibHeader := staticLib.Output("turbine-combined/static_lib.jar").Output
74
75 android.AssertStringDoesContain(t, "expected lib header jar in app javac classpath",
76 appJavac.Args["classpath"], libHeader.String())
77 android.AssertStringDoesContain(t, "expected static_lib header jar in app javac classpath",
78 appJavac.Args["classpath"], staticLibHeader.String())
79
80 android.AssertStringDoesContain(t, "expected lib header jar in app r8 classpath",
81 appR8.Args["r8Flags"], libHeader.String())
Sam Delmerico9f9c0a22022-11-29 11:19:37 -050082 android.AssertStringDoesNotContain(t, "expected no static_lib header jar in app r8 classpath",
Colin Cross9bb9bfb2022-03-17 11:12:32 -070083 appR8.Args["r8Flags"], staticLibHeader.String())
Remi NGUYEN VANbdad3142022-08-04 13:19:03 +090084 android.AssertStringDoesContain(t, "expected -ignorewarnings in app r8 flags",
85 appR8.Args["r8Flags"], "-ignorewarnings")
Jared Duke40d731a2022-09-20 15:32:14 -070086 android.AssertStringDoesContain(t, "expected --android-platform-build in app r8 flags",
87 appR8.Args["r8Flags"], "--android-platform-build")
88 android.AssertStringDoesNotContain(t, "expected no --android-platform-build in stable_app r8 flags",
89 stableAppR8.Args["r8Flags"], "--android-platform-build")
90 android.AssertStringDoesContain(t, "expected --android-platform-build in core_platform_app r8 flags",
91 corePlatformAppR8.Args["r8Flags"], "--android-platform-build")
Remi NGUYEN VANbdad3142022-08-04 13:19:03 +090092}
93
Sam Delmerico9f9c0a22022-11-29 11:19:37 -050094func TestR8TransitiveDeps(t *testing.T) {
95 bp := `
96 override_android_app {
97 name: "override_app",
98 base: "app",
99 }
100
101 android_app {
102 name: "app",
103 srcs: ["foo.java"],
104 libs: [
105 "lib",
106 "uses_libs_dep_import",
107 ],
108 static_libs: [
109 "static_lib",
110 "repeated_dep",
111 ],
112 platform_apis: true,
113 }
114
115 java_library {
116 name: "static_lib",
117 srcs: ["foo.java"],
118 }
119
120 java_library {
121 name: "lib",
122 libs: [
123 "transitive_lib",
124 "repeated_dep",
125 "prebuilt_lib",
126 ],
127 static_libs: ["transitive_static_lib"],
128 srcs: ["foo.java"],
129 }
130
131 java_library {
132 name: "repeated_dep",
133 srcs: ["foo.java"],
134 }
135
136 java_library {
137 name: "transitive_static_lib",
138 srcs: ["foo.java"],
139 }
140
141 java_library {
142 name: "transitive_lib",
143 srcs: ["foo.java"],
144 libs: ["transitive_lib_2"],
145 }
146
147 java_library {
148 name: "transitive_lib_2",
149 srcs: ["foo.java"],
150 }
151
152 java_import {
153 name: "lib",
154 jars: ["lib.jar"],
155 }
156
157 java_library {
158 name: "uses_lib",
159 srcs: ["foo.java"],
160 }
161
162 java_library {
163 name: "optional_uses_lib",
164 srcs: ["foo.java"],
165 }
166
167 android_library {
168 name: "uses_libs_dep",
169 uses_libs: ["uses_lib"],
170 optional_uses_libs: ["optional_uses_lib"],
171 }
172
173 android_library_import {
174 name: "uses_libs_dep_import",
175 aars: ["aar.aar"],
176 static_libs: ["uses_libs_dep"],
177 }
178 `
179
180 testcases := []struct {
181 name string
182 unbundled bool
183 }{
184 {
185 name: "non-unbundled build",
186 unbundled: false,
187 },
188 {
189 name: "unbundled build",
190 unbundled: true,
191 },
192 }
193
194 for _, tc := range testcases {
195 t.Run(tc.name, func(t *testing.T) {
Jiakai Zhangcf61e3c2023-05-08 16:28:38 +0000196 fixturePreparer := PrepareForTestWithJavaDefaultModules
Sam Delmerico9f9c0a22022-11-29 11:19:37 -0500197 if tc.unbundled {
198 fixturePreparer = android.GroupFixturePreparers(
199 fixturePreparer,
200 android.FixtureModifyProductVariables(
201 func(variables android.FixtureProductVariables) {
202 variables.Unbundled_build = proptools.BoolPtr(true)
203 },
204 ),
205 )
206 }
207 result := fixturePreparer.RunTestWithBp(t, bp)
208
209 getHeaderJar := func(name string) android.Path {
210 mod := result.ModuleForTests(name, "android_common")
211 return mod.Output("turbine-combined/" + name + ".jar").Output
212 }
213
214 appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
215 overrideAppR8 := result.ModuleForTests("app", "android_common_override_app").Rule("r8")
216 appHeader := getHeaderJar("app")
217 overrideAppHeader := result.ModuleForTests("app", "android_common_override_app").Output("turbine-combined/app.jar").Output
218 libHeader := getHeaderJar("lib")
219 transitiveLibHeader := getHeaderJar("transitive_lib")
220 transitiveLib2Header := getHeaderJar("transitive_lib_2")
221 staticLibHeader := getHeaderJar("static_lib")
222 transitiveStaticLibHeader := getHeaderJar("transitive_static_lib")
223 repeatedDepHeader := getHeaderJar("repeated_dep")
224 usesLibHeader := getHeaderJar("uses_lib")
225 optionalUsesLibHeader := getHeaderJar("optional_uses_lib")
226 prebuiltLibHeader := result.ModuleForTests("prebuilt_lib", "android_common").Output("combined/lib.jar").Output
227
228 for _, rule := range []android.TestingBuildParams{appR8, overrideAppR8} {
229 android.AssertStringDoesNotContain(t, "expected no app header jar in app r8 classpath",
230 rule.Args["r8Flags"], appHeader.String())
231 android.AssertStringDoesNotContain(t, "expected no override_app header jar in app r8 classpath",
232 rule.Args["r8Flags"], overrideAppHeader.String())
233 android.AssertStringDoesContain(t, "expected transitive lib header jar in app r8 classpath",
234 rule.Args["r8Flags"], transitiveLibHeader.String())
235 android.AssertStringDoesContain(t, "expected transitive lib ^2 header jar in app r8 classpath",
236 rule.Args["r8Flags"], transitiveLib2Header.String())
237 android.AssertStringDoesContain(t, "expected lib header jar in app r8 classpath",
238 rule.Args["r8Flags"], libHeader.String())
239 android.AssertStringDoesContain(t, "expected uses_lib header jar in app r8 classpath",
240 rule.Args["r8Flags"], usesLibHeader.String())
241 android.AssertStringDoesContain(t, "expected optional_uses_lib header jar in app r8 classpath",
242 rule.Args["r8Flags"], optionalUsesLibHeader.String())
243 android.AssertStringDoesNotContain(t, "expected no static_lib header jar in app r8 classpath",
244 rule.Args["r8Flags"], staticLibHeader.String())
245 android.AssertStringDoesNotContain(t, "expected no transitive static_lib header jar in app r8 classpath",
246 rule.Args["r8Flags"], transitiveStaticLibHeader.String())
247 // we shouldn't list this dep because it is already included as static_libs in the app
248 android.AssertStringDoesNotContain(t, "expected no repeated_dep header jar in app r8 classpath",
249 rule.Args["r8Flags"], repeatedDepHeader.String())
250 // skip a prebuilt transitive dep if the source is also a transitive dep
251 android.AssertStringDoesNotContain(t, "expected no prebuilt header jar in app r8 classpath",
252 rule.Args["r8Flags"], prebuiltLibHeader.String())
253 android.AssertStringDoesContain(t, "expected -ignorewarnings in app r8 flags",
254 rule.Args["r8Flags"], "-ignorewarnings")
255 android.AssertStringDoesContain(t, "expected --android-platform-build in app r8 flags",
256 rule.Args["r8Flags"], "--android-platform-build")
257 }
258 })
259 }
260}
261
Remi NGUYEN VANbdad3142022-08-04 13:19:03 +0900262func TestR8Flags(t *testing.T) {
Jiakai Zhangcf61e3c2023-05-08 16:28:38 +0000263 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
Remi NGUYEN VANbdad3142022-08-04 13:19:03 +0900264 android_app {
265 name: "app",
266 srcs: ["foo.java"],
267 platform_apis: true,
268 optimize: {
269 shrink: false,
270 optimize: false,
271 obfuscate: false,
272 ignore_warnings: false,
273 },
274 }
275 `)
276
277 app := result.ModuleForTests("app", "android_common")
278 appR8 := app.Rule("r8")
279 android.AssertStringDoesContain(t, "expected -dontshrink in app r8 flags",
280 appR8.Args["r8Flags"], "-dontshrink")
281 android.AssertStringDoesContain(t, "expected -dontoptimize in app r8 flags",
282 appR8.Args["r8Flags"], "-dontoptimize")
283 android.AssertStringDoesContain(t, "expected -dontobfuscate in app r8 flags",
284 appR8.Args["r8Flags"], "-dontobfuscate")
285 android.AssertStringDoesNotContain(t, "expected no -ignorewarnings in app r8 flags",
286 appR8.Args["r8Flags"], "-ignorewarnings")
Jared Duke40d731a2022-09-20 15:32:14 -0700287 android.AssertStringDoesContain(t, "expected --android-platform-build in app r8 flags",
288 appR8.Args["r8Flags"], "--android-platform-build")
Colin Cross9bb9bfb2022-03-17 11:12:32 -0700289}
290
291func TestD8(t *testing.T) {
Jiakai Zhangcf61e3c2023-05-08 16:28:38 +0000292 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
Colin Cross9bb9bfb2022-03-17 11:12:32 -0700293 java_library {
294 name: "foo",
295 srcs: ["foo.java"],
296 libs: ["lib"],
297 static_libs: ["static_lib"],
298 installable: true,
299 }
300
301 java_library {
302 name: "lib",
303 srcs: ["foo.java"],
304 }
305
306 java_library {
307 name: "static_lib",
308 srcs: ["foo.java"],
309 }
Jared Duke70b85422025-01-28 19:13:39 +0000310
311 android_app {
312 name: "app",
313 srcs: ["foo.java"],
314 platform_apis: true,
315 optimize: {
316 enabled: false,
317 },
318 }
Colin Cross9bb9bfb2022-03-17 11:12:32 -0700319 `)
320
321 foo := result.ModuleForTests("foo", "android_common")
322 lib := result.ModuleForTests("lib", "android_common")
Jared Duke70b85422025-01-28 19:13:39 +0000323 app := result.ModuleForTests("app", "android_common")
Colin Cross9bb9bfb2022-03-17 11:12:32 -0700324 staticLib := result.ModuleForTests("static_lib", "android_common")
325
326 fooJavac := foo.Rule("javac")
327 fooD8 := foo.Rule("d8")
Jared Duke70b85422025-01-28 19:13:39 +0000328 appD8 := app.Rule("d8")
Colin Cross9bb9bfb2022-03-17 11:12:32 -0700329 libHeader := lib.Output("turbine-combined/lib.jar").Output
330 staticLibHeader := staticLib.Output("turbine-combined/static_lib.jar").Output
331
332 android.AssertStringDoesContain(t, "expected lib header jar in foo javac classpath",
333 fooJavac.Args["classpath"], libHeader.String())
334 android.AssertStringDoesContain(t, "expected static_lib header jar in foo javac classpath",
335 fooJavac.Args["classpath"], staticLibHeader.String())
336
337 android.AssertStringDoesContain(t, "expected lib header jar in foo d8 classpath",
338 fooD8.Args["d8Flags"], libHeader.String())
339 android.AssertStringDoesNotContain(t, "expected no static_lib header jar in foo javac classpath",
340 fooD8.Args["d8Flags"], staticLibHeader.String())
Jared Duke70b85422025-01-28 19:13:39 +0000341
342 // A --release flag is added only for targets that opt out of default R8 behavior (e.g., apps).
343 // For library targets that don't use R8 by default, no --debug or --release flag should be
344 // added, instead relying on default D8 behavior (--debug).
345 android.AssertStringDoesContain(t, "expected --release in app d8 flags",
346 appD8.Args["d8Flags"], "--release")
347 android.AssertStringDoesNotContain(t, "expected no --release flag in lib d8 flags",
348 fooD8.Args["d8Flags"], "--release")
349 android.AssertStringDoesNotContain(t, "expected no --debug flag in lib d8 flags",
350 fooD8.Args["d8Flags"], "--debug")
Colin Cross9bb9bfb2022-03-17 11:12:32 -0700351}
Jared Duke5979b302022-12-19 21:08:39 +0000352
Sam Delmerico95d70942023-08-02 18:00:35 -0400353func TestProguardFlagsInheritanceStatic(t *testing.T) {
Jiakai Zhangcf61e3c2023-05-08 16:28:38 +0000354 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
Jared Duke5979b302022-12-19 21:08:39 +0000355 android_app {
356 name: "app",
357 static_libs: [
358 "primary_android_lib",
359 "primary_lib",
360 ],
361 platform_apis: true,
362 }
363
364 java_library {
365 name: "primary_lib",
366 optimize: {
367 proguard_flags_files: ["primary.flags"],
368 },
369 }
370
371 android_library {
372 name: "primary_android_lib",
373 static_libs: ["secondary_lib"],
374 optimize: {
375 proguard_flags_files: ["primary_android.flags"],
376 },
377 }
378
379 java_library {
380 name: "secondary_lib",
381 static_libs: ["tertiary_lib"],
382 optimize: {
383 proguard_flags_files: ["secondary.flags"],
384 },
385 }
386
387 java_library {
388 name: "tertiary_lib",
389 optimize: {
390 proguard_flags_files: ["tertiary.flags"],
391 },
392 }
393 `)
394
395 app := result.ModuleForTests("app", "android_common")
396 appR8 := app.Rule("r8")
397 android.AssertStringDoesContain(t, "expected primary_lib's proguard flags from direct dep",
398 appR8.Args["r8Flags"], "primary.flags")
399 android.AssertStringDoesContain(t, "expected primary_android_lib's proguard flags from direct dep",
400 appR8.Args["r8Flags"], "primary_android.flags")
401 android.AssertStringDoesContain(t, "expected secondary_lib's proguard flags from inherited dep",
402 appR8.Args["r8Flags"], "secondary.flags")
403 android.AssertStringDoesContain(t, "expected tertiary_lib's proguard flags from inherited dep",
404 appR8.Args["r8Flags"], "tertiary.flags")
405}
Sam Delmerico95d70942023-08-02 18:00:35 -0400406
407func TestProguardFlagsInheritance(t *testing.T) {
408 directDepFlagsFileName := "direct_dep.flags"
409 transitiveDepFlagsFileName := "transitive_dep.flags"
Sam Delmerico95d70942023-08-02 18:00:35 -0400410
Sam Delmericoc8e040c2023-10-31 17:27:02 +0000411 topLevelModules := []struct {
412 name string
413 definition string
414 }{
415 {
416 name: "android_app",
417 definition: `
418 android_app {
419 name: "app",
420 static_libs: ["androidlib"], // this must be static_libs to initate dexing
421 platform_apis: true,
422 }
423 `,
424 },
425 {
426 name: "android_library",
427 definition: `
428 android_library {
429 name: "app",
430 static_libs: ["androidlib"], // this must be static_libs to initate dexing
431 installable: true,
432 optimize: {
433 enabled: true,
434 shrink: true,
435 },
436 }
437 `,
438 },
439 {
440 name: "java_library",
441 definition: `
442 java_library {
443 name: "app",
444 static_libs: ["androidlib"], // this must be static_libs to initate dexing
445 srcs: ["Foo.java"],
446 installable: true,
447 optimize: {
448 enabled: true,
449 shrink: true,
450 },
451 }
452 `,
453 },
454 }
455
456 bp := `
Sam Delmerico95d70942023-08-02 18:00:35 -0400457 android_library {
458 name: "androidlib",
459 static_libs: ["app_dep"],
460 }
461
462 java_library {
463 name: "app_dep",
464 %s: ["dep"],
465 }
466
467 java_library {
468 name: "dep",
469 %s: ["transitive_dep"],
470 optimize: {
471 proguard_flags_files: ["direct_dep.flags"],
472 export_proguard_flags_files: %v,
473 },
474 }
475
476 java_library {
477 name: "transitive_dep",
478 optimize: {
479 proguard_flags_files: ["transitive_dep.flags"],
480 export_proguard_flags_files: %v,
481 },
482 }
483 `
484
485 testcases := []struct {
486 name string
487 depType string
488 depExportsFlagsFiles bool
489 transitiveDepType string
490 transitiveDepExportsFlagsFiles bool
491 expectedFlagsFiles []string
492 }{
493 {
494 name: "libs_export_libs_export",
495 depType: "libs",
496 depExportsFlagsFiles: true,
497 transitiveDepType: "libs",
498 transitiveDepExportsFlagsFiles: true,
499 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
500 },
501 {
502 name: "static_export_libs_export",
503 depType: "static_libs",
504 depExportsFlagsFiles: true,
505 transitiveDepType: "libs",
506 transitiveDepExportsFlagsFiles: true,
507 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
508 },
509 {
510 name: "libs_no-export_static_export",
511 depType: "libs",
512 depExportsFlagsFiles: false,
513 transitiveDepType: "static_libs",
514 transitiveDepExportsFlagsFiles: true,
515 expectedFlagsFiles: []string{transitiveDepFlagsFileName},
516 },
517 {
518 name: "static_no-export_static_export",
519 depType: "static_libs",
520 depExportsFlagsFiles: false,
521 transitiveDepType: "static_libs",
522 transitiveDepExportsFlagsFiles: true,
523 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
524 },
525 {
526 name: "libs_export_libs_no-export",
527 depType: "libs",
528 depExportsFlagsFiles: true,
529 transitiveDepType: "libs",
530 transitiveDepExportsFlagsFiles: false,
531 expectedFlagsFiles: []string{directDepFlagsFileName},
532 },
533 {
534 name: "static_export_libs_no-export",
535 depType: "static_libs",
536 depExportsFlagsFiles: true,
537 transitiveDepType: "libs",
538 transitiveDepExportsFlagsFiles: false,
539 expectedFlagsFiles: []string{directDepFlagsFileName},
540 },
541 {
542 name: "libs_no-export_static_no-export",
543 depType: "libs",
544 depExportsFlagsFiles: false,
545 transitiveDepType: "static_libs",
546 transitiveDepExportsFlagsFiles: false,
547 expectedFlagsFiles: []string{},
548 },
549 {
550 name: "static_no-export_static_no-export",
551 depType: "static_libs",
552 depExportsFlagsFiles: false,
553 transitiveDepType: "static_libs",
554 transitiveDepExportsFlagsFiles: false,
555 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
556 },
557 {
558 name: "libs_no-export_libs_export",
559 depType: "libs",
560 depExportsFlagsFiles: false,
561 transitiveDepType: "libs",
562 transitiveDepExportsFlagsFiles: true,
563 expectedFlagsFiles: []string{transitiveDepFlagsFileName},
564 },
565 {
566 name: "static_no-export_libs_export",
567 depType: "static_libs",
568 depExportsFlagsFiles: false,
569 transitiveDepType: "libs",
570 transitiveDepExportsFlagsFiles: true,
571 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
572 },
573 {
574 name: "libs_export_static_export",
575 depType: "libs",
576 depExportsFlagsFiles: true,
577 transitiveDepType: "static_libs",
578 transitiveDepExportsFlagsFiles: true,
579 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
580 },
581 {
582 name: "static_export_static_export",
583 depType: "static_libs",
584 depExportsFlagsFiles: true,
585 transitiveDepType: "static_libs",
586 transitiveDepExportsFlagsFiles: true,
587 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
588 },
589 {
590 name: "libs_no-export_libs_no-export",
591 depType: "libs",
592 depExportsFlagsFiles: false,
593 transitiveDepType: "libs",
594 transitiveDepExportsFlagsFiles: false,
595 expectedFlagsFiles: []string{},
596 },
597 {
598 name: "static_no-export_libs_no-export",
599 depType: "static_libs",
600 depExportsFlagsFiles: false,
601 transitiveDepType: "libs",
602 transitiveDepExportsFlagsFiles: false,
603 expectedFlagsFiles: []string{directDepFlagsFileName},
604 },
605 {
606 name: "libs_export_static_no-export",
607 depType: "libs",
608 depExportsFlagsFiles: true,
609 transitiveDepType: "static_libs",
610 transitiveDepExportsFlagsFiles: false,
611 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
612 },
613 {
614 name: "static_export_static_no-export",
615 depType: "static_libs",
616 depExportsFlagsFiles: true,
617 transitiveDepType: "static_libs",
618 transitiveDepExportsFlagsFiles: false,
619 expectedFlagsFiles: []string{directDepFlagsFileName, transitiveDepFlagsFileName},
620 },
621 }
622
Sam Delmericoc8e040c2023-10-31 17:27:02 +0000623 for _, topLevelModuleDef := range topLevelModules {
624 for _, tc := range testcases {
625 t.Run(topLevelModuleDef.name+"-"+tc.name, func(t *testing.T) {
626 result := android.GroupFixturePreparers(
627 PrepareForTestWithJavaDefaultModules,
628 android.FixtureMergeMockFs(android.MockFS{
629 directDepFlagsFileName: nil,
630 transitiveDepFlagsFileName: nil,
631 }),
632 ).RunTestWithBp(t,
633 topLevelModuleDef.definition+
634 fmt.Sprintf(
635 bp,
636 tc.depType,
637 tc.transitiveDepType,
638 tc.depExportsFlagsFiles,
639 tc.transitiveDepExportsFlagsFiles,
640 ),
641 )
642 appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
Sam Delmerico95d70942023-08-02 18:00:35 -0400643
Sam Delmericoc8e040c2023-10-31 17:27:02 +0000644 shouldHaveDepFlags := android.InList(directDepFlagsFileName, tc.expectedFlagsFiles)
645 if shouldHaveDepFlags {
646 android.AssertStringDoesContain(t, "expected deps's proguard flags",
647 appR8.Args["r8Flags"], directDepFlagsFileName)
648 } else {
649 android.AssertStringDoesNotContain(t, "app did not expect deps's proguard flags",
650 appR8.Args["r8Flags"], directDepFlagsFileName)
651 }
Sam Delmerico95d70942023-08-02 18:00:35 -0400652
Sam Delmericoc8e040c2023-10-31 17:27:02 +0000653 shouldHaveTransitiveDepFlags := android.InList(transitiveDepFlagsFileName, tc.expectedFlagsFiles)
654 if shouldHaveTransitiveDepFlags {
655 android.AssertStringDoesContain(t, "expected transitive deps's proguard flags",
656 appR8.Args["r8Flags"], transitiveDepFlagsFileName)
657 } else {
658 android.AssertStringDoesNotContain(t, "app did not expect transitive deps's proguard flags",
659 appR8.Args["r8Flags"], transitiveDepFlagsFileName)
660 }
661 })
662 }
Sam Delmerico95d70942023-08-02 18:00:35 -0400663 }
664}
665
666func TestProguardFlagsInheritanceAppImport(t *testing.T) {
667 bp := `
668 android_app {
669 name: "app",
670 static_libs: ["aarimport"], // this must be static_libs to initate dexing
671 platform_apis: true,
672 }
673
Sam Delmerico95d70942023-08-02 18:00:35 -0400674 android_library_import {
675 name: "aarimport",
676 aars: ["import.aar"],
677 }
678 `
679 result := android.GroupFixturePreparers(
680 PrepareForTestWithJavaDefaultModules,
681 ).RunTestWithBp(t, bp)
682
683 appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
684 android.AssertStringDoesContain(t, "expected aarimports's proguard flags",
685 appR8.Args["r8Flags"], "proguard.txt")
686}
Spandan Das3dbda182024-05-20 22:23:10 +0000687
688func TestR8FlagsArtProfile(t *testing.T) {
689 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
690 android_app {
691 name: "app",
692 srcs: ["foo.java"],
693 platform_apis: true,
694 dex_preopt: {
695 profile_guided: true,
696 profile: "profile.txt.prof",
697 enable_profile_rewriting: true,
698 },
699 }
700 `)
701
702 app := result.ModuleForTests("app", "android_common")
703 appR8 := app.Rule("r8")
704 android.AssertStringDoesContain(t, "expected --art-profile in app r8 flags",
705 appR8.Args["r8Flags"], "--art-profile")
706
707 appDexpreopt := app.Rule("dexpreopt")
708 android.AssertStringDoesContain(t,
709 "expected --art-profile output to be used to create .prof binary",
710 appDexpreopt.RuleParams.Command,
711 "--create-profile-from=out/soong/.intermediates/app/android_common/profile.prof.txt --output-profile-type=app",
712 )
713}
Spandan Das15a67112024-05-30 00:07:40 +0000714
715// This test checks that users explicitly set `enable_profile_rewriting` to true when the following are true
716// 1. optimize or obfuscate is enabled AND
717// 2. dex_preopt.profile_guided is enabled
718//
719// The rewritten profile should be used since the dex signatures in the checked-in profile will not match the optimized binary.
720func TestEnableProfileRewritingIsRequiredForOptimizedApps(t *testing.T) {
721 testJavaError(t,
722 "Enable_profile_rewriting must be true when profile_guided dexpreopt and R8 optimization/obfuscation is turned on",
723 `
724android_app {
725 name: "app",
726 srcs: ["foo.java"],
727 platform_apis: true,
728 dex_preopt: {
729 profile_guided: true,
730 profile: "profile.txt.prof",
731 // enable_profile_rewriting is not set, this is an error
732 },
733 optimize: {
734 optimize: true,
735 }
736}`)
737}
Jared Duked32e85f2024-09-25 23:54:30 +0000738
739func TestDebugReleaseFlags(t *testing.T) {
740 bp := `
741 android_app {
742 name: "app",
743 srcs: ["foo.java"],
744 platform_apis: true,
Jared Duke70b85422025-01-28 19:13:39 +0000745 optimize: {
746 enabled: %s,
747 },
Jared Duked32e85f2024-09-25 23:54:30 +0000748 dxflags: ["%s"]
749 }
750 `
751
752 testcases := []struct {
753 name string
754 envVar string
755 isEng bool
Jared Duke70b85422025-01-28 19:13:39 +0000756 useD8 bool
Jared Duked32e85f2024-09-25 23:54:30 +0000757 dxFlags string
758 expectedFlags string
759 }{
760 {
761 name: "app_no_optimize_dx",
762 envVar: "NO_OPTIMIZE_DX",
763 expectedFlags: "--debug",
764 },
765 {
766 name: "app_release_no_optimize_dx",
767 envVar: "NO_OPTIMIZE_DX",
768 dxFlags: "--release",
769 // Global env vars override explicit dxflags.
770 expectedFlags: "--debug",
771 },
772 {
773 name: "app_generate_dex_debug",
774 envVar: "GENERATE_DEX_DEBUG",
775 expectedFlags: "--debug",
776 },
777 {
778 name: "app_release_generate_dex_debug",
779 envVar: "GENERATE_DEX_DEBUG",
780 dxFlags: "--release",
781 // Global env vars override explicit dxflags.
782 expectedFlags: "--debug",
783 },
784 {
785 name: "app_eng",
786 isEng: true,
787 expectedFlags: "--debug",
788 },
789 {
790 name: "app_release_eng",
791 isEng: true,
792 dxFlags: "--release",
793 // Eng mode does *not* override explicit dxflags.
794 expectedFlags: "--release",
795 },
Jared Duke70b85422025-01-28 19:13:39 +0000796 {
797 name: "app_d8",
798 useD8: true,
799 // D8 usage w/ apps should explicitly enable --release mode.
800 expectedFlags: "--release",
801 },
802 {
803 name: "app_d8_debug",
804 useD8: true,
805 dxFlags: "--debug",
806 // D8 usage w/ apps respects overriding dxFlags.
807 expectedFlags: "--debug",
808 },
Jared Duked32e85f2024-09-25 23:54:30 +0000809 }
810
811 for _, tc := range testcases {
812 t.Run(tc.name, func(t *testing.T) {
813 fixturePreparer := PrepareForTestWithJavaDefaultModules
814 fixturePreparer = android.GroupFixturePreparers(
815 fixturePreparer,
816 android.FixtureModifyProductVariables(
817 func(variables android.FixtureProductVariables) {
818 variables.Eng = proptools.BoolPtr(tc.isEng)
819 },
820 ),
821 )
822 if tc.envVar != "" {
823 fixturePreparer = android.GroupFixturePreparers(
824 fixturePreparer,
825 android.FixtureMergeEnv(map[string]string{
826 tc.envVar: "true",
827 }),
828 )
829 }
Jared Duke70b85422025-01-28 19:13:39 +0000830 result := fixturePreparer.RunTestWithBp(t, fmt.Sprintf(bp, strconv.FormatBool(!tc.useD8), tc.dxFlags))
Jared Duked32e85f2024-09-25 23:54:30 +0000831
Jared Duke70b85422025-01-28 19:13:39 +0000832 dexRuleKey := "r8"
833 if tc.useD8 {
834 dexRuleKey = "d8"
835 }
836 dexFlagsKey := dexRuleKey + "Flags"
837 appDex := result.ModuleForTests("app", "android_common").Rule(dexRuleKey)
838 android.AssertStringDoesContain(t, "expected flag in dex flags",
839 appDex.Args[dexFlagsKey], tc.expectedFlags)
Jared Duked32e85f2024-09-25 23:54:30 +0000840
841 var unexpectedFlags string
842 if tc.expectedFlags == "--debug" {
843 unexpectedFlags = "--release"
844 } else if tc.expectedFlags == "--release" {
845 unexpectedFlags = "--debug"
846 }
847 if unexpectedFlags != "" {
Jared Duke70b85422025-01-28 19:13:39 +0000848 android.AssertStringDoesNotContain(t, "unexpected flag in dex flags",
849 appDex.Args[dexFlagsKey], unexpectedFlags)
Jared Duked32e85f2024-09-25 23:54:30 +0000850 }
851 })
852 }
853}