1// 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 ( 18 "fmt" 19 "strconv" 20 "testing" 21 22 "android/soong/android" 23 24 "github.com/google/blueprint/proptools" 25) 26 27func TestR8(t *testing.T) { 28 t.Parallel() 29 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, ` 30 android_app { 31 name: "app", 32 srcs: ["foo.java"], 33 libs: ["lib"], 34 static_libs: ["static_lib"], 35 platform_apis: true, 36 } 37 38 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", 49 min_sdk_version: "31", 50 } 51 52 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 63 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") 68 69 appJavac := app.Rule("javac") 70 appR8 := app.Rule("r8") 71 stableAppR8 := stableApp.Rule("r8") 72 corePlatformAppR8 := corePlatformApp.Rule("r8") 73 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 76 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 82 android.AssertStringDoesContain(t, "expected lib combined header jar in app r8 classpath", 83 appR8.Args["r8Flags"], libCombinedHeader.String()) 84 android.AssertStringDoesNotContain(t, "expected no static_lib header jar in app r8 classpath", 85 appR8.Args["r8Flags"], staticLibHeader.String()) 86 android.AssertStringDoesContain(t, "expected -ignorewarnings in app r8 flags", 87 appR8.Args["r8Flags"], "-ignorewarnings") 88 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") 94} 95 96func TestR8TransitiveDeps(t *testing.T) { 97 t.Parallel() 98 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) { 199 t.Parallel() 200 fixturePreparer := PrepareForTestWithJavaDefaultModules 201 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 { 214 mod := result.ModuleForTests(t, name, "android_common") 215 return mod.Output("turbine-combined/" + name + ".jar").Output 216 } 217 218 appR8 := result.ModuleForTests(t, "app", "android_common").Rule("r8") 219 overrideAppR8 := result.ModuleForTests(t, "app", "android_common_override_app").Rule("r8") 220 appHeader := getHeaderJar("app") 221 overrideAppHeader := result.ModuleForTests(t, "app", "android_common_override_app").Output("turbine-combined/app.jar").Output 222 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") 230 prebuiltLibHeader := result.ModuleForTests(t, "prebuilt_lib", "android_common").Output("combined/lib.jar").Output 231 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 266func TestR8Flags(t *testing.T) { 267 t.Parallel() 268 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, ` 269 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 282 app := result.ModuleForTests(t, "app", "android_common") 283 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") 292 android.AssertStringDoesContain(t, "expected --android-platform-build in app r8 flags", 293 appR8.Args["r8Flags"], "--android-platform-build") 294} 295 296func TestD8(t *testing.T) { 297 t.Parallel() 298 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, ` 299 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 } 316 317 android_app { 318 name: "app", 319 srcs: ["foo.java"], 320 platform_apis: true, 321 optimize: { 322 enabled: false, 323 }, 324 } 325 `) 326 327 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") 331 332 fooJavac := foo.Rule("javac") 333 fooD8 := foo.Rule("d8") 334 appD8 := app.Rule("d8") 335 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 338 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 344 android.AssertStringDoesContain(t, "expected lib combined header jar in foo d8 classpath", 345 fooD8.Args["d8Flags"], libCombinedHeader.String()) 346 android.AssertStringDoesNotContain(t, "expected no static_lib header jar in foo javac classpath", 347 fooD8.Args["d8Flags"], staticLibHeader.String()) 348 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") 358} 359 360func TestProguardFlagsInheritanceStatic(t *testing.T) { 361 t.Parallel() 362 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, ` 363 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 403 app := result.ModuleForTests(t, "app", "android_common") 404 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} 414 415func TestProguardFlagsInheritance(t *testing.T) { 416 t.Parallel() 417 directDepFlagsFileName := "direct_dep.flags" 418 transitiveDepFlagsFileName := "transitive_dep.flags" 419 420 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 := ` 466 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 632 for _, topLevelModuleDef := range topLevelModules { 633 for _, tc := range testcases { 634 t.Run(topLevelModuleDef.name+"-"+tc.name, func(t *testing.T) { 635 t.Parallel() 636 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 ) 652 appR8 := result.ModuleForTests(t, "app", "android_common").Rule("r8") 653 654 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 } 662 663 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 } 673 } 674} 675 676func TestProguardFlagsInheritanceAppImport(t *testing.T) { 677 t.Parallel() 678 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 685 android_library_import { 686 name: "aarimport", 687 aars: ["import.aar"], 688 } 689 ` 690 result := android.GroupFixturePreparers( 691 PrepareForTestWithJavaDefaultModules, 692 ).RunTestWithBp(t, bp) 693 694 appR8 := result.ModuleForTests(t, "app", "android_common").Rule("r8") 695 android.AssertStringDoesContain(t, "expected aarimports's proguard flags", 696 appR8.Args["r8Flags"], "proguard.txt") 697} 698 699func TestR8FlagsArtProfile(t *testing.T) { 700 t.Parallel() 701 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 714 app := result.ModuleForTests(t, "app", "android_common") 715 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} 726 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) { 733 t.Parallel() 734 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} 751 752func TestDebugReleaseFlags(t *testing.T) { 753 t.Parallel() 754 bp := ` 755 android_app { 756 name: "app", 757 srcs: ["foo.java"], 758 platform_apis: true, 759 optimize: { 760 enabled: %s, 761 }, 762 dxflags: ["%s"] 763 } 764 ` 765 766 testcases := []struct { 767 name string 768 envVar string 769 isEng bool 770 useD8 bool 771 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 useD8: true, 801 isEng: true, 802 expectedFlags: "--debug", 803 }, 804 { 805 name: "app_release_eng", 806 isEng: true, 807 useD8: true, 808 dxFlags: "--release", 809 // Eng mode does *not* override explicit dxflags. 810 expectedFlags: "--release", 811 }, 812 { 813 name: "app_d8", 814 useD8: true, 815 // D8 usage w/ apps should explicitly enable --release mode. 816 expectedFlags: "--release", 817 }, 818 { 819 name: "app_d8_debug", 820 useD8: true, 821 dxFlags: "--debug", 822 // D8 usage w/ apps respects overriding dxFlags. 823 expectedFlags: "--debug", 824 }, 825 } 826 827 for _, tc := range testcases { 828 t.Run(tc.name, func(t *testing.T) { 829 t.Parallel() 830 fixturePreparer := PrepareForTestWithJavaDefaultModules 831 fixturePreparer = android.GroupFixturePreparers( 832 fixturePreparer, 833 android.FixtureModifyProductVariables( 834 func(variables android.FixtureProductVariables) { 835 variables.Eng = proptools.BoolPtr(tc.isEng) 836 }, 837 ), 838 ) 839 if tc.envVar != "" { 840 fixturePreparer = android.GroupFixturePreparers( 841 fixturePreparer, 842 android.FixtureMergeEnv(map[string]string{ 843 tc.envVar: "true", 844 }), 845 ) 846 } 847 result := fixturePreparer.RunTestWithBp(t, fmt.Sprintf(bp, strconv.FormatBool(!tc.useD8), tc.dxFlags)) 848 849 dexRuleKey := "r8" 850 if tc.useD8 { 851 dexRuleKey = "d8" 852 } 853 dexFlagsKey := dexRuleKey + "Flags" 854 appDex := result.ModuleForTests(t, "app", "android_common").Rule(dexRuleKey) 855 android.AssertStringDoesContain(t, "expected flag in dex flags", 856 appDex.Args[dexFlagsKey], tc.expectedFlags) 857 858 var unexpectedFlags string 859 if tc.expectedFlags == "--debug" { 860 unexpectedFlags = "--release" 861 } else if tc.expectedFlags == "--release" { 862 unexpectedFlags = "--debug" 863 } 864 if unexpectedFlags != "" { 865 android.AssertStringDoesNotContain(t, "unexpected flag in dex flags", 866 appDex.Args[dexFlagsKey], unexpectedFlags) 867 } 868 }) 869 } 870} 871 872func TestTraceReferences(t *testing.T) { 873 t.Parallel() 874 bp := ` 875 android_app { 876 name: "app", 877 libs: ["lib.impl"], 878 srcs: ["foo.java"], 879 platform_apis: true, 880 } 881 882 java_library { 883 name: "lib", 884 optimize: { 885 enabled: true, 886 trace_references_from: ["app"], 887 }, 888 srcs: ["bar.java"], 889 static_libs: ["lib.impl"], 890 installable: true, 891 } 892 893 java_library { 894 name: "lib.impl", 895 srcs: ["baz.java"], 896 } 897 ` 898 result := android.GroupFixturePreparers( 899 PrepareForTestWithJavaDefaultModules, 900 ).RunTestWithBp(t, bp) 901 902 appJar := result.ModuleForTests(t, "app", "android_common").Output("combined/app.jar").Output 903 libJar := result.ModuleForTests(t, "lib", "android_common").Output("combined/lib.jar").Output 904 libTraceRefs := result.ModuleForTests(t, "lib", "android_common").Rule("traceReferences") 905 libR8 := result.ModuleForTests(t, "lib", "android_common").Rule("r8") 906 907 android.AssertStringDoesContain(t, "expected trace reference source from app jar", 908 libTraceRefs.Args["sources"], "--source "+appJar.String()) 909 android.AssertStringEquals(t, "expected trace reference target into lib jar", 910 libJar.String(), libTraceRefs.Input.String()) 911 android.AssertStringDoesContain(t, "expected trace reference proguard flags in lib r8 flags", 912 libR8.Args["r8Flags"], "trace_references.flags") 913} 914