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 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 } 90 91 apex_key { 92 name: "myapex.key", 93 public_key: "testkey.avbpubkey", 94 private_key: "testkey.pem", 95 } 96 97 bootclasspath_fragment { 98 name: "bar-fragment", 99 contents: ["bar"], 100 apex_available: ["myapex"], 101 api: { 102 stub_libs: ["foo"], 103 }, 104 hidden_api: { 105 unsupported: [ 106 "bar-unsupported.txt", 107 ], 108 removed: [ 109 "bar-removed.txt", 110 ], 111 max_target_r_low_priority: [ 112 "bar-max-target-r-low-priority.txt", 113 ], 114 max_target_q: [ 115 "bar-max-target-q.txt", 116 ], 117 max_target_p: [ 118 "bar-max-target-p.txt", 119 ], 120 max_target_o_low_priority: [ 121 "bar-max-target-o-low-priority.txt", 122 ], 123 blocked: [ 124 "bar-blocked.txt", 125 ], 126 unsupported_packages: [ 127 "bar-unsupported-packages.txt", 128 ], 129 split_packages: ["*"], 130 }, 131 } 132 133 java_library { 134 name: "bar", 135 apex_available: ["myapex"], 136 srcs: ["a.java"], 137 system_modules: "none", 138 sdk_version: "none", 139 compile_dex: true, 140 permitted_packages: ["bar"], 141 } 142 143 java_sdk_library { 144 name: "foo", 145 srcs: ["a.java"], 146 public: { 147 enabled: true, 148 }, 149 compile_dex: true, 150 } 151 `), 152 ).RunTest(t) 153 154 pbcp := result.Module("platform-bootclasspath", "android_common") 155 info := result.ModuleProvider(pbcp, java.MonolithicHiddenAPIInfoProvider).(java.MonolithicHiddenAPIInfo) 156 157 for _, category := range java.HiddenAPIFlagFileCategories { 158 name := category.PropertyName 159 message := fmt.Sprintf("category %s", name) 160 filename := strings.ReplaceAll(name, "_", "-") 161 expected := []string{fmt.Sprintf("%s.txt", filename), fmt.Sprintf("bar-%s.txt", filename)} 162 android.AssertPathsRelativeToTopEquals(t, message, expected, info.FlagsFilesByCategory[category]) 163 } 164 165 android.AssertPathsRelativeToTopEquals(t, "annotation flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/annotation-flags.csv"}, info.AnnotationFlagsPaths) 166 android.AssertPathsRelativeToTopEquals(t, "metadata flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/metadata.csv"}, info.MetadataPaths) 167 android.AssertPathsRelativeToTopEquals(t, "index flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/index.csv"}, info.IndexPaths) 168 169 android.AssertArrayString(t, "stub flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/filtered-stub-flags.csv:out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/signature-patterns.csv"}, info.StubFlagSubsets.RelativeToTop()) 170 android.AssertArrayString(t, "all flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/filtered-flags.csv:out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/signature-patterns.csv"}, info.FlagSubsets.RelativeToTop()) 171} 172 173// TestPlatformBootclasspath_LegacyPrebuiltFragment verifies that the 174// prebuilt_bootclasspath_fragment falls back to using the complete stub-flags/all-flags if the 175// filtered files are not provided. 176// 177// TODO: Remove once all prebuilts use the filtered_... properties. 178func TestPlatformBootclasspath_LegacyPrebuiltFragment(t *testing.T) { 179 result := android.GroupFixturePreparers( 180 prepareForTestWithPlatformBootclasspath, 181 java.FixtureConfigureApexBootJars("myapex:foo"), 182 java.PrepareForTestWithJavaSdkLibraryFiles, 183 ).RunTestWithBp(t, ` 184 prebuilt_apex { 185 name: "myapex", 186 src: "myapex.apex", 187 exported_bootclasspath_fragments: ["mybootclasspath-fragment"], 188 } 189 190 // A prebuilt java_sdk_library_import that is not preferred by default but will be preferred 191 // because AlwaysUsePrebuiltSdks() is true. 192 java_sdk_library_import { 193 name: "foo", 194 prefer: false, 195 shared_library: false, 196 permitted_packages: ["foo"], 197 public: { 198 jars: ["sdk_library/public/foo-stubs.jar"], 199 stub_srcs: ["sdk_library/public/foo_stub_sources"], 200 current_api: "sdk_library/public/foo.txt", 201 removed_api: "sdk_library/public/foo-removed.txt", 202 sdk_version: "current", 203 }, 204 apex_available: ["myapex"], 205 } 206 207 prebuilt_bootclasspath_fragment { 208 name: "mybootclasspath-fragment", 209 apex_available: [ 210 "myapex", 211 ], 212 contents: [ 213 "foo", 214 ], 215 hidden_api: { 216 stub_flags: "prebuilt-stub-flags.csv", 217 annotation_flags: "prebuilt-annotation-flags.csv", 218 metadata: "prebuilt-metadata.csv", 219 index: "prebuilt-index.csv", 220 all_flags: "prebuilt-all-flags.csv", 221 }, 222 } 223 224 platform_bootclasspath { 225 name: "myplatform-bootclasspath", 226 fragments: [ 227 { 228 apex: "myapex", 229 module:"mybootclasspath-fragment", 230 }, 231 ], 232 } 233`, 234 ) 235 236 pbcp := result.Module("myplatform-bootclasspath", "android_common") 237 info := result.ModuleProvider(pbcp, java.MonolithicHiddenAPIInfoProvider).(java.MonolithicHiddenAPIInfo) 238 239 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()) 240 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()) 241} 242 243func TestPlatformBootclasspathDependencies(t *testing.T) { 244 result := android.GroupFixturePreparers( 245 prepareForTestWithPlatformBootclasspath, 246 prepareForTestWithArtApex, 247 prepareForTestWithMyapex, 248 // Configure some libraries in the art and framework boot images. 249 java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz", "platform:foo"), 250 java.FixtureConfigureApexBootJars("myapex:bar"), 251 java.PrepareForTestWithJavaSdkLibraryFiles, 252 java.FixtureWithLastReleaseApis("foo"), 253 java.PrepareForTestWithDexpreopt, 254 dexpreopt.FixtureDisableDexpreoptBootImages(false), 255 ).RunTestWithBp(t, ` 256 apex { 257 name: "com.android.art", 258 key: "com.android.art.key", 259 bootclasspath_fragments: [ 260 "art-bootclasspath-fragment", 261 ], 262 updatable: false, 263 } 264 265 apex_key { 266 name: "com.android.art.key", 267 public_key: "com.android.art.avbpubkey", 268 private_key: "com.android.art.pem", 269 } 270 271 bootclasspath_fragment { 272 name: "art-bootclasspath-fragment", 273 image_name: "art", 274 apex_available: [ 275 "com.android.art", 276 ], 277 contents: [ 278 "baz", 279 "quuz", 280 ], 281 hidden_api: { 282 split_packages: ["*"], 283 }, 284 } 285 286 java_library { 287 name: "baz", 288 apex_available: [ 289 "com.android.art", 290 ], 291 srcs: ["b.java"], 292 installable: true, 293 } 294 295 // Add a java_import that is not preferred and so won't have an appropriate apex variant created 296 // for it to make sure that the platform_bootclasspath doesn't try and add a dependency onto it. 297 java_import { 298 name: "baz", 299 apex_available: [ 300 "com.android.art", 301 ], 302 jars: ["b.jar"], 303 } 304 305 java_library { 306 name: "quuz", 307 apex_available: [ 308 "com.android.art", 309 ], 310 srcs: ["b.java"], 311 installable: true, 312 } 313 314 apex { 315 name: "myapex", 316 key: "myapex.key", 317 bootclasspath_fragments: [ 318 "my-bootclasspath-fragment", 319 ], 320 updatable: false, 321 } 322 323 bootclasspath_fragment { 324 name: "my-bootclasspath-fragment", 325 contents: ["bar"], 326 apex_available: ["myapex"], 327 hidden_api: { 328 split_packages: ["*"], 329 }, 330 } 331 332 apex_key { 333 name: "myapex.key", 334 public_key: "testkey.avbpubkey", 335 private_key: "testkey.pem", 336 } 337 338 java_sdk_library { 339 name: "foo", 340 srcs: ["b.java"], 341 } 342 343 java_library { 344 name: "bar", 345 srcs: ["b.java"], 346 installable: true, 347 apex_available: ["myapex"], 348 permitted_packages: ["bar"], 349 } 350 351 platform_bootclasspath { 352 name: "myplatform-bootclasspath", 353 354 fragments: [ 355 { 356 apex: "com.android.art", 357 module: "art-bootclasspath-fragment", 358 }, 359 { 360 apex: "myapex", 361 module: "my-bootclasspath-fragment", 362 }, 363 ], 364 } 365`, 366 ) 367 368 java.CheckPlatformBootclasspathModules(t, result, "myplatform-bootclasspath", []string{ 369 // The configured contents of BootJars. 370 "com.android.art:baz", 371 "com.android.art:quuz", 372 "platform:foo", 373 374 // The configured contents of ApexBootJars. 375 "myapex:bar", 376 }) 377 378 java.CheckPlatformBootclasspathFragments(t, result, "myplatform-bootclasspath", []string{ 379 "com.android.art:art-bootclasspath-fragment", 380 "myapex:my-bootclasspath-fragment", 381 }) 382 383 // Make sure that the myplatform-bootclasspath has the correct dependencies. 384 CheckModuleDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{ 385 // The following are stubs. 386 `platform:android_stubs_current`, 387 `platform:android_system_stubs_current`, 388 `platform:android_test_stubs_current`, 389 `platform:legacy.core.platform.api.stubs`, 390 391 // Needed for generating the boot image. 392 `platform:dex2oatd`, 393 394 // The configured contents of BootJars. 395 `com.android.art:baz`, 396 `com.android.art:quuz`, 397 `platform:foo`, 398 399 // The configured contents of ApexBootJars. 400 `myapex:bar`, 401 402 // The fragments. 403 `com.android.art:art-bootclasspath-fragment`, 404 `myapex:my-bootclasspath-fragment`, 405 }) 406} 407 408// TestPlatformBootclasspath_AlwaysUsePrebuiltSdks verifies that the build does not fail when 409// AlwaysUsePrebuiltSdk() returns true. 410func TestPlatformBootclasspath_AlwaysUsePrebuiltSdks(t *testing.T) { 411 result := android.GroupFixturePreparers( 412 prepareForTestWithPlatformBootclasspath, 413 prepareForTestWithMyapex, 414 // Configure two libraries, the first is a java_sdk_library whose prebuilt will be used because 415 // of AlwaysUsePrebuiltsSdk(). The second is a normal library that is unaffected. The order 416 // matters, so that the dependencies resolved by the platform_bootclasspath matches the 417 // configured list. 418 java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"), 419 java.PrepareForTestWithJavaSdkLibraryFiles, 420 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 421 variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true) 422 }), 423 java.FixtureWithPrebuiltApis(map[string][]string{ 424 "current": {}, 425 "30": {"foo"}, 426 }), 427 ).RunTestWithBp(t, ` 428 apex { 429 name: "myapex", 430 key: "myapex.key", 431 bootclasspath_fragments: [ 432 "mybootclasspath-fragment", 433 ], 434 updatable: false, 435 } 436 437 apex_key { 438 name: "myapex.key", 439 public_key: "testkey.avbpubkey", 440 private_key: "testkey.pem", 441 } 442 443 java_library { 444 name: "bar", 445 srcs: ["b.java"], 446 installable: true, 447 apex_available: ["myapex"], 448 permitted_packages: ["bar"], 449 } 450 451 java_sdk_library { 452 name: "foo", 453 srcs: ["b.java"], 454 shared_library: false, 455 public: { 456 enabled: true, 457 }, 458 apex_available: ["myapex"], 459 permitted_packages: ["foo"], 460 } 461 462 prebuilt_apex { 463 name: "myapex", 464 src: "myapex.apex", 465 exported_bootclasspath_fragments: ["mybootclasspath-fragment"], 466 } 467 468 // A prebuilt java_sdk_library_import that is not preferred by default but will be preferred 469 // because AlwaysUsePrebuiltSdks() is true. 470 java_sdk_library_import { 471 name: "foo", 472 prefer: false, 473 shared_library: false, 474 permitted_packages: ["foo"], 475 public: { 476 jars: ["sdk_library/public/foo-stubs.jar"], 477 stub_srcs: ["sdk_library/public/foo_stub_sources"], 478 current_api: "sdk_library/public/foo.txt", 479 removed_api: "sdk_library/public/foo-removed.txt", 480 sdk_version: "current", 481 }, 482 apex_available: ["myapex"], 483 } 484 485 // This always depends on the source foo module, its dependencies are not affected by the 486 // AlwaysUsePrebuiltSdks(). 487 bootclasspath_fragment { 488 name: "mybootclasspath-fragment", 489 apex_available: [ 490 "myapex", 491 ], 492 contents: [ 493 "foo", "bar", 494 ], 495 hidden_api: { 496 split_packages: ["*"], 497 }, 498 } 499 500 prebuilt_bootclasspath_fragment { 501 name: "mybootclasspath-fragment", 502 apex_available: [ 503 "myapex", 504 ], 505 contents: [ 506 "foo", 507 ], 508 hidden_api: { 509 stub_flags: "", 510 annotation_flags: "", 511 metadata: "", 512 index: "", 513 all_flags: "", 514 }, 515 } 516 517 platform_bootclasspath { 518 name: "myplatform-bootclasspath", 519 fragments: [ 520 { 521 apex: "myapex", 522 module:"mybootclasspath-fragment", 523 }, 524 ], 525 } 526`, 527 ) 528 529 java.CheckPlatformBootclasspathModules(t, result, "myplatform-bootclasspath", []string{ 530 // The configured contents of BootJars. 531 "myapex:prebuilt_foo", 532 "myapex:bar", 533 }) 534 535 // Make sure that the myplatform-bootclasspath has the correct dependencies. 536 CheckModuleDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{ 537 // The following are stubs. 538 "platform:prebuilt_sdk_public_current_android", 539 "platform:prebuilt_sdk_system_current_android", 540 "platform:prebuilt_sdk_test_current_android", 541 542 // Not a prebuilt as no prebuilt existed when it was added. 543 "platform:legacy.core.platform.api.stubs", 544 545 // The platform_bootclasspath intentionally adds dependencies on both source and prebuilt 546 // modules when available as it does not know which one will be preferred. 547 "myapex:foo", 548 "myapex:prebuilt_foo", 549 550 // Only a source module exists. 551 "myapex:bar", 552 553 // The fragments. 554 "myapex:mybootclasspath-fragment", 555 "myapex:prebuilt_mybootclasspath-fragment", 556 }) 557} 558 559// CheckModuleDependencies checks the dependencies of the selected module against the expected list. 560// 561// The expected list must be a list of strings of the form "<apex>:<module>", where <apex> is the 562// name of the apex, or platform is it is not part of an apex and <module> is the module name. 563func CheckModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant string, expected []string) { 564 t.Helper() 565 module := ctx.ModuleForTests(name, variant).Module() 566 modules := []android.Module{} 567 ctx.VisitDirectDeps(module, func(m blueprint.Module) { 568 modules = append(modules, m.(android.Module)) 569 }) 570 571 pairs := java.ApexNamePairsFromModules(ctx, modules) 572 android.AssertDeepEquals(t, "module dependencies", expected, pairs) 573} 574 575// TestPlatformBootclasspath_IncludesRemainingApexJars verifies that any apex boot jar is present in 576// platform_bootclasspath's classpaths.proto config, if the apex does not generate its own config 577// by setting generate_classpaths_proto property to false. 578func TestPlatformBootclasspath_IncludesRemainingApexJars(t *testing.T) { 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/soong/target/product/test_device/system/etc/classpaths", 634 ) 635} 636 637func TestBootJarNotInApex(t *testing.T) { 638 android.GroupFixturePreparers( 639 prepareForTestWithPlatformBootclasspath, 640 PrepareForTestWithApexBuildComponents, 641 prepareForTestWithMyapex, 642 java.FixtureConfigureApexBootJars("myapex:foo"), 643 ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( 644 `dependency "foo" of "myplatform-bootclasspath" missing variant`)). 645 RunTestWithBp(t, ` 646 apex { 647 name: "myapex", 648 key: "myapex.key", 649 updatable: false, 650 } 651 652 apex_key { 653 name: "myapex.key", 654 public_key: "testkey.avbpubkey", 655 private_key: "testkey.pem", 656 } 657 658 java_library { 659 name: "foo", 660 srcs: ["b.java"], 661 installable: true, 662 apex_available: [ 663 "myapex", 664 ], 665 } 666 667 bootclasspath_fragment { 668 name: "not-in-apex-fragment", 669 contents: [ 670 "foo", 671 ], 672 hidden_api: { 673 split_packages: ["*"], 674 }, 675 } 676 677 platform_bootclasspath { 678 name: "myplatform-bootclasspath", 679 } 680 `) 681} 682 683func TestBootFragmentNotInApex(t *testing.T) { 684 android.GroupFixturePreparers( 685 prepareForTestWithPlatformBootclasspath, 686 PrepareForTestWithApexBuildComponents, 687 prepareForTestWithMyapex, 688 java.FixtureConfigureApexBootJars("myapex:foo"), 689 ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( 690 `library foo.*have no corresponding fragment.*`)).RunTestWithBp(t, ` 691 apex { 692 name: "myapex", 693 key: "myapex.key", 694 java_libs: ["foo"], 695 updatable: false, 696 } 697 698 apex_key { 699 name: "myapex.key", 700 public_key: "testkey.avbpubkey", 701 private_key: "testkey.pem", 702 } 703 704 java_library { 705 name: "foo", 706 srcs: ["b.java"], 707 installable: true, 708 apex_available: ["myapex"], 709 permitted_packages: ["foo"], 710 } 711 712 bootclasspath_fragment { 713 name: "not-in-apex-fragment", 714 contents: ["foo"], 715 hidden_api: { 716 split_packages: ["*"], 717 }, 718 } 719 720 platform_bootclasspath { 721 name: "myplatform-bootclasspath", 722 } 723 `) 724} 725 726func TestNonBootJarInFragment(t *testing.T) { 727 android.GroupFixturePreparers( 728 prepareForTestWithPlatformBootclasspath, 729 PrepareForTestWithApexBuildComponents, 730 prepareForTestWithMyapex, 731 java.FixtureConfigureApexBootJars("myapex:foo"), 732 ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( 733 `in contents must also be declared in PRODUCT_APEX_BOOT_JARS`)). 734 RunTestWithBp(t, ` 735 apex { 736 name: "myapex", 737 key: "myapex.key", 738 bootclasspath_fragments: ["apex-fragment"], 739 updatable: false, 740 } 741 742 apex_key { 743 name: "myapex.key", 744 public_key: "testkey.avbpubkey", 745 private_key: "testkey.pem", 746 } 747 748 java_library { 749 name: "foo", 750 srcs: ["b.java"], 751 installable: true, 752 apex_available: ["myapex"], 753 permitted_packages: ["foo"], 754 } 755 756 java_library { 757 name: "bar", 758 srcs: ["b.java"], 759 installable: true, 760 apex_available: ["myapex"], 761 permitted_packages: ["bar"], 762 } 763 764 bootclasspath_fragment { 765 name: "apex-fragment", 766 contents: ["foo", "bar"], 767 apex_available:[ "myapex" ], 768 hidden_api: { 769 split_packages: ["*"], 770 }, 771 } 772 773 platform_bootclasspath { 774 name: "myplatform-bootclasspath", 775 fragments: [{ 776 apex: "myapex", 777 module:"apex-fragment", 778 }], 779 } 780 `) 781} 782