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