1// Copyright (C) 2021 The Android Open Source Project 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 apex 16 17import ( 18 "fmt" 19 "strings" 20 "testing" 21 22 "android/soong/android" 23 "android/soong/dexpreopt" 24 "android/soong/java" 25 26 "github.com/google/blueprint/proptools" 27) 28 29// Contains tests for platform_bootclasspath logic from java/platform_bootclasspath.go that requires 30// apexes. 31 32var prepareForTestWithPlatformBootclasspath = android.GroupFixturePreparers( 33 java.PrepareForTestWithJavaDefaultModules, 34 PrepareForTestWithApexBuildComponents, 35) 36 37func TestPlatformBootclasspath_Fragments(t *testing.T) { 38 t.Parallel() 39 result := android.GroupFixturePreparers( 40 prepareForTestWithPlatformBootclasspath, 41 prepareForTestWithMyapex, 42 java.PrepareForTestWithJavaSdkLibraryFiles, 43 java.FixtureWithLastReleaseApis("foo"), 44 java.FixtureConfigureApexBootJars("myapex:bar"), 45 android.FixtureWithRootAndroidBp(` 46 platform_bootclasspath { 47 name: "platform-bootclasspath", 48 fragments: [ 49 { 50 apex: "myapex", 51 module:"bar-fragment", 52 }, 53 ], 54 hidden_api: { 55 unsupported: [ 56 "unsupported.txt", 57 ], 58 removed: [ 59 "removed.txt", 60 ], 61 max_target_r_low_priority: [ 62 "max-target-r-low-priority.txt", 63 ], 64 max_target_q: [ 65 "max-target-q.txt", 66 ], 67 max_target_p: [ 68 "max-target-p.txt", 69 ], 70 max_target_o_low_priority: [ 71 "max-target-o-low-priority.txt", 72 ], 73 blocked: [ 74 "blocked.txt", 75 ], 76 unsupported_packages: [ 77 "unsupported-packages.txt", 78 ], 79 }, 80 } 81 82 apex { 83 name: "myapex", 84 key: "myapex.key", 85 bootclasspath_fragments: [ 86 "bar-fragment", 87 ], 88 updatable: false, 89 min_sdk_version: "30", // R 90 } 91 92 apex_key { 93 name: "myapex.key", 94 public_key: "testkey.avbpubkey", 95 private_key: "testkey.pem", 96 } 97 98 bootclasspath_fragment { 99 name: "bar-fragment", 100 contents: ["bar"], 101 apex_available: ["myapex"], 102 api: { 103 stub_libs: ["foo"], 104 }, 105 hidden_api: { 106 unsupported: [ 107 "bar-unsupported.txt", 108 ], 109 removed: [ 110 "bar-removed.txt", 111 ], 112 max_target_r_low_priority: [ 113 "bar-max-target-r-low-priority.txt", 114 ], 115 max_target_q: [ 116 "bar-max-target-q.txt", 117 ], 118 max_target_p: [ 119 "bar-max-target-p.txt", 120 ], 121 max_target_o_low_priority: [ 122 "bar-max-target-o-low-priority.txt", 123 ], 124 blocked: [ 125 "bar-blocked.txt", 126 ], 127 unsupported_packages: [ 128 "bar-unsupported-packages.txt", 129 ], 130 split_packages: ["*"], 131 }, 132 } 133 134 java_library { 135 name: "bar", 136 apex_available: ["myapex"], 137 srcs: ["a.java"], 138 system_modules: "none", 139 sdk_version: "none", 140 compile_dex: true, 141 permitted_packages: ["bar"], 142 min_sdk_version: "30", // R 143 } 144 145 java_sdk_library { 146 name: "foo", 147 srcs: ["a.java"], 148 public: { 149 enabled: true, 150 }, 151 compile_dex: true, 152 } 153 `), 154 ).RunTest(t) 155 156 pbcp := result.Module("platform-bootclasspath", "android_common") 157 info, _ := android.OtherModuleProvider(result, pbcp, java.MonolithicHiddenAPIInfoProvider) 158 159 for _, category := range java.HiddenAPIFlagFileCategories { 160 name := category.PropertyName() 161 message := fmt.Sprintf("category %s", name) 162 filename := strings.ReplaceAll(name, "_", "-") 163 expected := []string{fmt.Sprintf("%s.txt", filename), fmt.Sprintf("bar-%s.txt", filename)} 164 android.AssertPathsRelativeToTopEquals(t, message, expected, info.FlagsFilesByCategory[category]) 165 } 166 167 android.AssertPathsRelativeToTopEquals(t, "annotation flags", []string{"out/soong/.intermediates/bar-fragment/android_common_myapex/modular-hiddenapi/annotation-flags.csv"}, info.AnnotationFlagsPaths) 168 android.AssertPathsRelativeToTopEquals(t, "metadata flags", []string{"out/soong/.intermediates/bar-fragment/android_common_myapex/modular-hiddenapi/metadata.csv"}, info.MetadataPaths) 169 android.AssertPathsRelativeToTopEquals(t, "index flags", []string{"out/soong/.intermediates/bar-fragment/android_common_myapex/modular-hiddenapi/index.csv"}, info.IndexPaths) 170 171 android.AssertArrayString(t, "stub flags", []string{"out/soong/.intermediates/bar-fragment/android_common_myapex/modular-hiddenapi/filtered-stub-flags.csv:out/soong/.intermediates/bar-fragment/android_common_myapex/modular-hiddenapi/signature-patterns.csv"}, info.StubFlagSubsets.RelativeToTop()) 172 android.AssertArrayString(t, "all flags", []string{"out/soong/.intermediates/bar-fragment/android_common_myapex/modular-hiddenapi/filtered-flags.csv:out/soong/.intermediates/bar-fragment/android_common_myapex/modular-hiddenapi/signature-patterns.csv"}, info.FlagSubsets.RelativeToTop()) 173} 174 175// TestPlatformBootclasspath_LegacyPrebuiltFragment verifies that the 176// prebuilt_bootclasspath_fragment falls back to using the complete stub-flags/all-flags if the 177// filtered files are not provided. 178// 179// TODO: Remove once all prebuilts use the filtered_... properties. 180func TestPlatformBootclasspath_LegacyPrebuiltFragment(t *testing.T) { 181 t.Parallel() 182 result := android.GroupFixturePreparers( 183 prepareForTestWithPlatformBootclasspath, 184 java.FixtureConfigureApexBootJars("myapex:foo"), 185 java.PrepareForTestWithJavaSdkLibraryFiles, 186 ).RunTestWithBp(t, ` 187 prebuilt_apex { 188 name: "myapex", 189 src: "myapex.apex", 190 exported_bootclasspath_fragments: ["mybootclasspath-fragment"], 191 } 192 193 // A prebuilt java_sdk_library_import that is not preferred by default but will be preferred 194 // because AlwaysUsePrebuiltSdks() is true. 195 java_sdk_library_import { 196 name: "foo", 197 prefer: false, 198 shared_library: false, 199 permitted_packages: ["foo"], 200 public: { 201 jars: ["sdk_library/public/foo-stubs.jar"], 202 stub_srcs: ["sdk_library/public/foo_stub_sources"], 203 current_api: "sdk_library/public/foo.txt", 204 removed_api: "sdk_library/public/foo-removed.txt", 205 sdk_version: "current", 206 }, 207 apex_available: ["myapex"], 208 } 209 210 prebuilt_bootclasspath_fragment { 211 name: "mybootclasspath-fragment", 212 apex_available: [ 213 "myapex", 214 ], 215 contents: [ 216 "foo", 217 ], 218 hidden_api: { 219 stub_flags: "prebuilt-stub-flags.csv", 220 annotation_flags: "prebuilt-annotation-flags.csv", 221 metadata: "prebuilt-metadata.csv", 222 index: "prebuilt-index.csv", 223 all_flags: "prebuilt-all-flags.csv", 224 }, 225 } 226 227 platform_bootclasspath { 228 name: "myplatform-bootclasspath", 229 fragments: [ 230 { 231 apex: "myapex", 232 module:"mybootclasspath-fragment", 233 }, 234 ], 235 } 236`, 237 ) 238 239 pbcp := result.Module("myplatform-bootclasspath", "android_common") 240 info, _ := android.OtherModuleProvider(result, pbcp, java.MonolithicHiddenAPIInfoProvider) 241 242 android.AssertArrayString(t, "stub flags", []string{"prebuilt-stub-flags.csv:out/soong/.intermediates/mybootclasspath-fragment/android_common_prebuilt_myapex/modular-hiddenapi/signature-patterns.csv"}, info.StubFlagSubsets.RelativeToTop()) 243 android.AssertArrayString(t, "all flags", []string{"prebuilt-all-flags.csv:out/soong/.intermediates/mybootclasspath-fragment/android_common_prebuilt_myapex/modular-hiddenapi/signature-patterns.csv"}, info.FlagSubsets.RelativeToTop()) 244} 245 246func TestPlatformBootclasspathDependencies(t *testing.T) { 247 t.Parallel() 248 result := android.GroupFixturePreparers( 249 prepareForTestWithPlatformBootclasspath, 250 prepareForTestWithArtApex, 251 prepareForTestWithMyapex, 252 // Configure some libraries in the art and framework boot images. 253 java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz", "platform:foo"), 254 java.FixtureConfigureApexBootJars("myapex:bar"), 255 java.PrepareForTestWithJavaSdkLibraryFiles, 256 java.FixtureWithLastReleaseApis("foo"), 257 java.PrepareForTestWithDexpreopt, 258 dexpreopt.FixtureDisableDexpreoptBootImages(false), 259 android.PrepareForTestWithBuildFlag("RELEASE_HIDDEN_API_EXPORTABLE_STUBS", "true"), 260 ).RunTestWithBp(t, ` 261 apex { 262 name: "com.android.art", 263 key: "com.android.art.key", 264 bootclasspath_fragments: [ 265 "art-bootclasspath-fragment", 266 ], 267 updatable: false, 268 } 269 270 apex_key { 271 name: "com.android.art.key", 272 public_key: "com.android.art.avbpubkey", 273 private_key: "com.android.art.pem", 274 } 275 276 bootclasspath_fragment { 277 name: "art-bootclasspath-fragment", 278 image_name: "art", 279 apex_available: [ 280 "com.android.art", 281 ], 282 contents: [ 283 "baz", 284 "quuz", 285 ], 286 hidden_api: { 287 split_packages: ["*"], 288 }, 289 } 290 291 java_library { 292 name: "baz", 293 apex_available: [ 294 "com.android.art", 295 ], 296 srcs: ["b.java"], 297 installable: true, 298 sdk_version: "core_current", 299 } 300 301 // Add a java_import that is not preferred and so won't have an appropriate apex variant created 302 // for it to make sure that the platform_bootclasspath doesn't try and add a dependency onto it. 303 java_import { 304 name: "baz", 305 apex_available: [ 306 "com.android.art", 307 ], 308 jars: ["b.jar"], 309 } 310 311 java_library { 312 name: "quuz", 313 apex_available: [ 314 "com.android.art", 315 ], 316 srcs: ["b.java"], 317 installable: true, 318 } 319 320 apex { 321 name: "myapex", 322 key: "myapex.key", 323 bootclasspath_fragments: [ 324 "my-bootclasspath-fragment", 325 ], 326 updatable: false, 327 } 328 329 bootclasspath_fragment { 330 name: "my-bootclasspath-fragment", 331 contents: ["bar"], 332 apex_available: ["myapex"], 333 hidden_api: { 334 split_packages: ["*"], 335 }, 336 } 337 338 apex_key { 339 name: "myapex.key", 340 public_key: "testkey.avbpubkey", 341 private_key: "testkey.pem", 342 } 343 344 java_sdk_library { 345 name: "foo", 346 srcs: ["b.java"], 347 } 348 349 java_library { 350 name: "bar", 351 srcs: ["b.java"], 352 installable: true, 353 apex_available: ["myapex"], 354 permitted_packages: ["bar"], 355 } 356 357 platform_bootclasspath { 358 name: "myplatform-bootclasspath", 359 360 fragments: [ 361 { 362 apex: "com.android.art", 363 module: "art-bootclasspath-fragment", 364 }, 365 { 366 apex: "myapex", 367 module: "my-bootclasspath-fragment", 368 }, 369 ], 370 } 371`, 372 ) 373 374 java.CheckPlatformBootclasspathModules(t, result, "myplatform-bootclasspath", []string{ 375 // The configured contents of BootJars. 376 "com.android.art:baz", 377 "com.android.art:quuz", 378 "platform:foo", 379 380 // The configured contents of ApexBootJars. 381 "myapex:bar", 382 }) 383 384 java.CheckPlatformBootclasspathFragments(t, result, "myplatform-bootclasspath", []string{ 385 "com.android.art:art-bootclasspath-fragment", 386 "myapex:my-bootclasspath-fragment", 387 }) 388 389 // Make sure that the myplatform-bootclasspath has the correct dependencies. 390 java.CheckPlatformBootclasspathDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{ 391 // source vs prebuilt selection metadata module 392 `platform:all_apex_contributions`, 393 394 // The following are stubs. 395 `platform:android_stubs_current_exportable`, 396 `platform:android_system_stubs_current_exportable`, 397 `platform:android_test_stubs_current_exportable`, 398 `platform:legacy.core.platform.api.stubs.exportable`, 399 400 // Needed for generating the boot image. 401 `platform:dex2oatd`, 402 403 // The configured contents of BootJars, via their apexes if necessary. 404 `platform:com.android.art`, 405 `platform:com.android.art`, 406 `platform:foo`, 407 408 // The configured contents of ApexBootJars, via their apex. 409 `platform:myapex`, 410 411 // The fragments via their apexes. 412 `platform:com.android.art`, 413 `platform:myapex`, 414 415 // Impl lib of sdk_library for transitive srcjar generation 416 `platform:foo.impl`, 417 }) 418} 419 420// TestPlatformBootclasspath_AlwaysUsePrebuiltSdks verifies that the build does not fail when 421// AlwaysUsePrebuiltSdk() returns true. 422func TestPlatformBootclasspath_AlwaysUsePrebuiltSdks(t *testing.T) { 423 t.Parallel() 424 result := android.GroupFixturePreparers( 425 prepareForTestWithPlatformBootclasspath, 426 prepareForTestWithMyapex, 427 // Configure two libraries, the first is a java_sdk_library whose prebuilt will be used because 428 // of AlwaysUsePrebuiltsSdk(). The second is a normal library that is unaffected. The order 429 // matters, so that the dependencies resolved by the platform_bootclasspath matches the 430 // configured list. 431 java.FixtureConfigureApexBootJars("myapex:foo"), 432 java.PrepareForTestWithJavaSdkLibraryFiles, 433 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 434 variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true) 435 }), 436 android.PrepareForTestWithBuildFlag("RELEASE_HIDDEN_API_EXPORTABLE_STUBS", "true"), 437 438 java.FixtureWithPrebuiltApis(map[string][]string{ 439 "current": {}, 440 "30": {"foo"}, 441 }), 442 ).RunTestWithBp(t, ` 443 apex { 444 name: "myapex", 445 key: "myapex.key", 446 bootclasspath_fragments: [ 447 "mybootclasspath-fragment", 448 ], 449 updatable: false, 450 } 451 452 apex_key { 453 name: "myapex.key", 454 public_key: "testkey.avbpubkey", 455 private_key: "testkey.pem", 456 } 457 458 java_library { 459 name: "bar", 460 srcs: ["b.java"], 461 installable: true, 462 apex_available: ["myapex"], 463 permitted_packages: ["bar"], 464 } 465 466 java_sdk_library { 467 name: "foo", 468 srcs: ["b.java"], 469 shared_library: false, 470 public: { 471 enabled: true, 472 }, 473 apex_available: ["myapex"], 474 permitted_packages: ["foo"], 475 } 476 477 prebuilt_apex { 478 name: "myapex", 479 src: "myapex.apex", 480 exported_bootclasspath_fragments: ["mybootclasspath-fragment"], 481 prefer: true, 482 } 483 484 // A prebuilt java_sdk_library_import that is not preferred by default but will be preferred 485 // because AlwaysUsePrebuiltSdks() is true. 486 java_sdk_library_import { 487 name: "foo", 488 prefer: false, 489 shared_library: false, 490 permitted_packages: ["foo"], 491 public: { 492 jars: ["sdk_library/public/foo-stubs.jar"], 493 stub_srcs: ["sdk_library/public/foo_stub_sources"], 494 current_api: "sdk_library/public/foo.txt", 495 removed_api: "sdk_library/public/foo-removed.txt", 496 sdk_version: "current", 497 }, 498 apex_available: ["myapex"], 499 } 500 501 // This always depends on the source foo module, its dependencies are not affected by the 502 // AlwaysUsePrebuiltSdks(). 503 bootclasspath_fragment { 504 name: "mybootclasspath-fragment", 505 apex_available: [ 506 "myapex", 507 ], 508 contents: [ 509 "foo", "bar", 510 ], 511 hidden_api: { 512 split_packages: ["*"], 513 }, 514 } 515 516 prebuilt_bootclasspath_fragment { 517 name: "mybootclasspath-fragment", 518 apex_available: [ 519 "myapex", 520 ], 521 contents: [ 522 "foo", 523 ], 524 hidden_api: { 525 stub_flags: "", 526 annotation_flags: "", 527 metadata: "", 528 index: "", 529 all_flags: "", 530 }, 531 } 532 533 platform_bootclasspath { 534 name: "myplatform-bootclasspath", 535 fragments: [ 536 { 537 apex: "myapex", 538 module:"mybootclasspath-fragment", 539 }, 540 ], 541 } 542`, 543 ) 544 545 java.CheckPlatformBootclasspathModules(t, result, "myplatform-bootclasspath", []string{ 546 // The configured contents of BootJars. 547 "prebuilt_myapex:prebuilt_foo", 548 }) 549 550 // Make sure that the myplatform-bootclasspath has the correct dependencies. 551 java.CheckPlatformBootclasspathDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{ 552 // source vs prebuilt selection metadata module 553 `platform:all_apex_contributions`, 554 555 // The following are stubs. 556 "platform:prebuilt_sdk_public_current_android", 557 "platform:prebuilt_sdk_system_current_android", 558 "platform:prebuilt_sdk_test_current_android", 559 560 // Not a prebuilt as no prebuilt existed when it was added. 561 "platform:legacy.core.platform.api.stubs.exportable", 562 563 // The prebuilt library via the apex. 564 "platform:prebuilt_myapex", 565 566 // The fragments via the apex. 567 "platform:prebuilt_myapex", 568 569 // Impl lib of sdk_library for transitive srcjar generation 570 "platform:foo.impl", 571 }) 572} 573 574// TestPlatformBootclasspath_IncludesRemainingApexJars verifies that any apex boot jar is present in 575// platform_bootclasspath's classpaths.proto config, if the apex does not generate its own config 576// by setting generate_classpaths_proto property to false. 577func TestPlatformBootclasspath_IncludesRemainingApexJars(t *testing.T) { 578 t.Parallel() 579 result := android.GroupFixturePreparers( 580 prepareForTestWithPlatformBootclasspath, 581 prepareForTestWithMyapex, 582 java.FixtureConfigureApexBootJars("myapex:foo"), 583 android.FixtureWithRootAndroidBp(` 584 platform_bootclasspath { 585 name: "platform-bootclasspath", 586 fragments: [ 587 { 588 apex: "myapex", 589 module:"foo-fragment", 590 }, 591 ], 592 } 593 594 apex { 595 name: "myapex", 596 key: "myapex.key", 597 bootclasspath_fragments: ["foo-fragment"], 598 updatable: false, 599 } 600 601 apex_key { 602 name: "myapex.key", 603 public_key: "testkey.avbpubkey", 604 private_key: "testkey.pem", 605 } 606 607 bootclasspath_fragment { 608 name: "foo-fragment", 609 generate_classpaths_proto: false, 610 contents: ["foo"], 611 apex_available: ["myapex"], 612 hidden_api: { 613 split_packages: ["*"], 614 }, 615 } 616 617 java_library { 618 name: "foo", 619 srcs: ["a.java"], 620 system_modules: "none", 621 sdk_version: "none", 622 compile_dex: true, 623 apex_available: ["myapex"], 624 permitted_packages: ["foo"], 625 } 626 `), 627 ).RunTest(t) 628 629 java.CheckClasspathFragmentProtoContentInfoProvider(t, result, 630 true, // proto should be generated 631 "myapex:foo", // apex doesn't generate its own config, so must be in platform_bootclasspath 632 "bootclasspath.pb", 633 "out/target/product/test_device/system/etc/classpaths", 634 ) 635} 636 637func TestBootJarNotInApex(t *testing.T) { 638 t.Parallel() 639 android.GroupFixturePreparers( 640 prepareForTestWithPlatformBootclasspath, 641 PrepareForTestWithApexBuildComponents, 642 prepareForTestWithMyapex, 643 java.FixtureConfigureApexBootJars("myapex:foo"), 644 ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( 645 `module "myplatform-bootclasspath" variant ".*": failed to find module "foo" in apex "myapex"`)). 646 RunTestWithBp(t, ` 647 apex { 648 name: "myapex", 649 key: "myapex.key", 650 updatable: false, 651 } 652 653 apex_key { 654 name: "myapex.key", 655 public_key: "testkey.avbpubkey", 656 private_key: "testkey.pem", 657 } 658 659 java_library { 660 name: "foo", 661 srcs: ["b.java"], 662 installable: true, 663 apex_available: [ 664 "myapex", 665 ], 666 } 667 668 bootclasspath_fragment { 669 name: "not-in-apex-fragment", 670 contents: [ 671 "foo", 672 ], 673 hidden_api: { 674 split_packages: ["*"], 675 }, 676 } 677 678 platform_bootclasspath { 679 name: "myplatform-bootclasspath", 680 } 681 `) 682} 683 684func TestBootFragmentNotInApex(t *testing.T) { 685 t.Parallel() 686 android.GroupFixturePreparers( 687 prepareForTestWithPlatformBootclasspath, 688 PrepareForTestWithApexBuildComponents, 689 prepareForTestWithMyapex, 690 java.FixtureConfigureApexBootJars("myapex:foo"), 691 ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( 692 `library foo.*have no corresponding fragment.*`)).RunTestWithBp(t, ` 693 apex { 694 name: "myapex", 695 key: "myapex.key", 696 java_libs: ["foo"], 697 updatable: false, 698 } 699 700 apex_key { 701 name: "myapex.key", 702 public_key: "testkey.avbpubkey", 703 private_key: "testkey.pem", 704 } 705 706 java_library { 707 name: "foo", 708 srcs: ["b.java"], 709 installable: true, 710 apex_available: ["myapex"], 711 permitted_packages: ["foo"], 712 } 713 714 bootclasspath_fragment { 715 name: "not-in-apex-fragment", 716 contents: ["foo"], 717 hidden_api: { 718 split_packages: ["*"], 719 }, 720 } 721 722 platform_bootclasspath { 723 name: "myplatform-bootclasspath", 724 } 725 `) 726} 727 728func TestNonBootJarInFragment(t *testing.T) { 729 t.Parallel() 730 android.GroupFixturePreparers( 731 prepareForTestWithPlatformBootclasspath, 732 PrepareForTestWithApexBuildComponents, 733 prepareForTestWithMyapex, 734 java.FixtureConfigureApexBootJars("myapex:foo"), 735 ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( 736 `in contents must also be declared in PRODUCT_APEX_BOOT_JARS`)). 737 RunTestWithBp(t, ` 738 apex { 739 name: "myapex", 740 key: "myapex.key", 741 bootclasspath_fragments: ["apex-fragment"], 742 updatable: false, 743 } 744 745 apex_key { 746 name: "myapex.key", 747 public_key: "testkey.avbpubkey", 748 private_key: "testkey.pem", 749 } 750 751 java_library { 752 name: "foo", 753 srcs: ["b.java"], 754 installable: true, 755 apex_available: ["myapex"], 756 permitted_packages: ["foo"], 757 } 758 759 java_library { 760 name: "bar", 761 srcs: ["b.java"], 762 installable: true, 763 apex_available: ["myapex"], 764 permitted_packages: ["bar"], 765 } 766 767 bootclasspath_fragment { 768 name: "apex-fragment", 769 contents: ["foo", "bar"], 770 apex_available:[ "myapex" ], 771 hidden_api: { 772 split_packages: ["*"], 773 }, 774 } 775 776 platform_bootclasspath { 777 name: "myplatform-bootclasspath", 778 fragments: [{ 779 apex: "myapex", 780 module:"apex-fragment", 781 }], 782 } 783 `) 784} 785 786// Skip bcp_fragment content validation of source apexes if prebuilts are active. 787func TestNonBootJarInPrebuilts(t *testing.T) { 788 t.Parallel() 789 testCases := []struct { 790 description string 791 selectedApexContributions string 792 expectedError string 793 }{ 794 { 795 description: "source is active", 796 selectedApexContributions: "", 797 expectedError: "in contents must also be declared in PRODUCT_APEX_BOOT_JARS", 798 }, 799 { 800 description: "prebuilts are active", 801 selectedApexContributions: "myapex.prebuilt.contributions", 802 expectedError: "", // skip content validation of source bcp fragment 803 }, 804 } 805 bp := ` 806// Source 807apex { 808 name: "myapex", 809 key: "myapex.key", 810 bootclasspath_fragments: ["apex-fragment"], 811 updatable: false, 812 min_sdk_version: "29", 813} 814 815override_apex { 816 name: "myapex.override", // overrides the min_sdk_version, thereby creating different variants of its transitive deps 817 base: "myapex", 818 min_sdk_version: "34", 819} 820 821apex_key { 822 name: "myapex.key", 823 public_key: "testkey.avbpubkey", 824 private_key: "testkey.pem", 825} 826 827java_library { 828 name: "foo", 829 srcs: ["b.java"], 830 installable: true, 831 apex_available: ["myapex"], 832 permitted_packages: ["foo"], 833 min_sdk_version: "29", 834} 835 836java_library { 837 name: "bar", 838 srcs: ["b.java"], 839 installable: true, 840 apex_available: ["myapex"], 841 permitted_packages: ["bar"], 842 min_sdk_version: "29", 843} 844 845bootclasspath_fragment { 846 name: "apex-fragment", 847 contents: ["foo", "bar"], 848 apex_available:[ "myapex" ], 849 hidden_api: { 850 split_packages: ["*"], 851 }, 852} 853 854platform_bootclasspath { 855 name: "myplatform-bootclasspath", 856 fragments: [{ 857 apex: "myapex", 858 module:"apex-fragment", 859 }], 860} 861 862// prebuilts 863prebuilt_apex { 864 name: "myapex", 865 apex_name: "myapex", 866 src: "myapex.apex", 867 exported_bootclasspath_fragments: ["apex-fragment"], 868 } 869 870 prebuilt_bootclasspath_fragment { 871 name: "apex-fragment", 872 contents: ["foo"], 873 hidden_api: { 874 annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", 875 metadata: "my-bootclasspath-fragment/metadata.csv", 876 index: "my-bootclasspath-fragment/index.csv", 877 stub_flags: "my-bootclasspath-fragment/stub-flags.csv", 878 all_flags: "my-bootclasspath-fragment/all-flags.csv", 879 }, 880 } 881 java_import { 882 name: "foo", 883 jars: ["foo.jar"], 884 } 885 886apex_contributions { 887 name: "myapex.prebuilt.contributions", 888 api_domain: "myapex", 889 contents: ["prebuilt_myapex"], 890} 891` 892 893 for _, tc := range testCases { 894 fixture := android.GroupFixturePreparers( 895 prepareForTestWithPlatformBootclasspath, 896 PrepareForTestWithApexBuildComponents, 897 prepareForTestWithMyapex, 898 java.FixtureConfigureApexBootJars("myapex:foo"), 899 android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ADSERVICES", tc.selectedApexContributions), 900 ) 901 if tc.expectedError != "" { 902 fixture = fixture.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(tc.expectedError)) 903 } 904 fixture.RunTestWithBp(t, bp) 905 } 906 907} 908 909// Source and prebuilt apex provide different set of boot jars 910func TestNonBootJarMissingInPrebuiltFragment(t *testing.T) { 911 t.Parallel() 912 bp := ` 913 apex { 914 name: "myapex", 915 key: "myapex.key", 916 bootclasspath_fragments: ["apex-fragment"], 917 updatable: false, 918 } 919 920 apex_key { 921 name: "myapex.key", 922 public_key: "testkey.avbpubkey", 923 private_key: "testkey.pem", 924 } 925 926 java_library { 927 name: "foo", 928 srcs: ["b.java"], 929 installable: true, 930 apex_available: ["myapex"], 931 permitted_packages: ["foo"], 932 } 933 934 java_library { 935 name: "bar", 936 srcs: ["b.java"], 937 installable: true, 938 apex_available: ["myapex"], 939 permitted_packages: ["bar"], 940 } 941 942 bootclasspath_fragment { 943 name: "apex-fragment", 944 contents: ["foo", "bar"], 945 apex_available:[ "myapex" ], 946 hidden_api: { 947 split_packages: ["*"], 948 }, 949 } 950 951 prebuilt_apex { 952 name: "com.google.android.myapex", // mainline prebuilt selection logic in soong relies on the naming convention com.google.android 953 apex_name: "myapex", 954 source_apex_name: "myapex", 955 src: "myapex.apex", 956 exported_bootclasspath_fragments: ["apex-fragment"], 957 } 958 959 java_import { 960 name: "foo", 961 jars: ["foo.jar"], 962 apex_available: ["myapex"], 963 permitted_packages: ["foo"], 964 } 965 966 prebuilt_bootclasspath_fragment { 967 name: "apex-fragment", 968 contents: ["foo"], // Unlike the source fragment, this is missing bar 969 apex_available:[ "myapex" ], 970 hidden_api: { 971 annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", 972 metadata: "my-bootclasspath-fragment/metadata.csv", 973 index: "my-bootclasspath-fragment/index.csv", 974 stub_flags: "my-bootclasspath-fragment/stub-flags.csv", 975 all_flags: "my-bootclasspath-fragment/all-flags.csv", 976 }, 977 } 978 979 // Another prebuilt apex, but this is not selected during the build. 980 prebuilt_apex { 981 name: "com.google.android.myapex.v2", // mainline prebuilt selection logic in soong relies on the naming convention com.google.android 982 apex_name: "myapex", 983 source_apex_name: "myapex", 984 src: "myapex.apex", 985 exported_bootclasspath_fragments: ["apex-fragment.v2"], 986 } 987 988 java_import { 989 name: "bar", 990 jars: ["bar.jar"], 991 apex_available: ["myapex"], 992 permitted_packages: ["bar"], 993 } 994 995 prebuilt_bootclasspath_fragment { 996 name: "apex-fragment.v2", 997 contents: ["bar"], // Unlike the source fragment, this is missing foo 998 apex_available:[ "myapex" ], 999 hidden_api: { 1000 annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", 1001 metadata: "my-bootclasspath-fragment/metadata.csv", 1002 index: "my-bootclasspath-fragment/index.csv", 1003 stub_flags: "my-bootclasspath-fragment/stub-flags.csv", 1004 all_flags: "my-bootclasspath-fragment/all-flags.csv", 1005 }, 1006 } 1007 1008 1009 apex_contributions { 1010 name: "my_apex_contributions", 1011 api_domain: "myapex", 1012 contents: [%v], 1013 } 1014 ` 1015 testCases := []struct { 1016 desc string 1017 configuredBootJars []string 1018 apexContributionContents string 1019 errorExpected bool 1020 }{ 1021 { 1022 desc: "Source apex is selected, and APEX_BOOT_JARS is correctly configured for source apex builds", 1023 configuredBootJars: []string{"myapex:foo", "myapex:bar"}, 1024 }, 1025 { 1026 desc: "Source apex is selected, and APEX_BOOT_JARS is missing bar", 1027 configuredBootJars: []string{"myapex:foo"}, 1028 errorExpected: true, 1029 }, 1030 { 1031 desc: "Prebuilt apex is selected, and APEX_BOOT_JARS is correctly configured for prebuilt apex build", 1032 configuredBootJars: []string{"myapex:foo"}, 1033 apexContributionContents: `"prebuilt_com.google.android.myapex"`, 1034 }, 1035 { 1036 desc: "Prebuilt apex is selected, and APEX_BOOT_JARS is missing foo", 1037 configuredBootJars: []string{"myapex:bar"}, 1038 apexContributionContents: `"prebuilt_com.google.android.myapex"`, 1039 errorExpected: true, 1040 }, 1041 } 1042 1043 for _, tc := range testCases { 1044 fixture := android.GroupFixturePreparers( 1045 prepareForTestWithPlatformBootclasspath, 1046 PrepareForTestWithApexBuildComponents, 1047 prepareForTestWithMyapex, 1048 java.FixtureConfigureApexBootJars(tc.configuredBootJars...), 1049 android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ART", "my_apex_contributions"), 1050 ) 1051 if tc.errorExpected { 1052 fixture = fixture.ExtendWithErrorHandler( 1053 android.FixtureExpectsAtLeastOneErrorMatchingPattern(`in contents.*must also be declared in PRODUCT_APEX_BOOT_JARS`), 1054 ) 1055 } 1056 fixture.RunTestWithBp(t, fmt.Sprintf(bp, tc.apexContributionContents)) 1057 } 1058} 1059