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 "path" 20 "sort" 21 "strings" 22 "testing" 23 24 "android/soong/android" 25 "android/soong/dexpreopt" 26 "android/soong/java" 27 28 "github.com/google/blueprint/proptools" 29) 30 31// Contains tests for bootclasspath_fragment logic from java/bootclasspath_fragment.go as the ART 32// bootclasspath_fragment requires modules from the ART apex. 33 34var prepareForTestWithBootclasspathFragment = android.GroupFixturePreparers( 35 java.PrepareForTestWithDexpreopt, 36 PrepareForTestWithApexBuildComponents, 37) 38 39// Some additional files needed for the art apex. 40var prepareForTestWithArtApex = android.GroupFixturePreparers( 41 android.FixtureMergeMockFs(android.MockFS{ 42 "com.android.art.avbpubkey": nil, 43 "com.android.art.pem": nil, 44 "system/sepolicy/apex/com.android.art-file_contexts": nil, 45 }), 46 dexpreopt.FixtureSetBootImageProfiles("art/build/boot/boot-image-profile.txt"), 47) 48 49func TestBootclasspathFragments(t *testing.T) { 50 result := android.GroupFixturePreparers( 51 prepareForTestWithBootclasspathFragment, 52 // Configure some libraries in the art bootclasspath_fragment and platform_bootclasspath. 53 java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz", "platform:foo", "platform:bar"), 54 prepareForTestWithArtApex, 55 56 java.PrepareForTestWithJavaSdkLibraryFiles, 57 java.FixtureWithLastReleaseApis("foo"), 58 ).RunTestWithBp(t, ` 59 java_sdk_library { 60 name: "foo", 61 srcs: ["b.java"], 62 } 63 64 java_library { 65 name: "bar", 66 srcs: ["b.java"], 67 installable: true, 68 } 69 70 apex { 71 name: "com.android.art", 72 key: "com.android.art.key", 73 bootclasspath_fragments: ["art-bootclasspath-fragment"], 74 updatable: false, 75 } 76 77 apex_key { 78 name: "com.android.art.key", 79 public_key: "com.android.art.avbpubkey", 80 private_key: "com.android.art.pem", 81 } 82 83 java_library { 84 name: "baz", 85 apex_available: [ 86 "com.android.art", 87 ], 88 srcs: ["b.java"], 89 compile_dex: true, 90 } 91 92 java_library { 93 name: "quuz", 94 apex_available: [ 95 "com.android.art", 96 ], 97 srcs: ["b.java"], 98 compile_dex: true, 99 } 100 101 bootclasspath_fragment { 102 name: "art-bootclasspath-fragment", 103 image_name: "art", 104 // Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above. 105 contents: ["baz", "quuz"], 106 apex_available: [ 107 "com.android.art", 108 ], 109 hidden_api: { 110 split_packages: ["*"], 111 }, 112 } 113`, 114 ) 115 116 // Make sure that the art-bootclasspath-fragment is using the correct configuration. 117 checkBootclasspathFragment(t, result, "art-bootclasspath-fragment", "android_common_apex10000", 118 "com.android.art:baz,com.android.art:quuz") 119} 120 121func TestBootclasspathFragments_FragmentDependency(t *testing.T) { 122 result := android.GroupFixturePreparers( 123 prepareForTestWithBootclasspathFragment, 124 // Configure some libraries in the art bootclasspath_fragment and platform_bootclasspath. 125 java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz"), 126 java.FixtureConfigureApexBootJars("someapex:foo", "someapex:bar"), 127 prepareForTestWithArtApex, 128 129 java.PrepareForTestWithJavaSdkLibraryFiles, 130 java.FixtureWithLastReleaseApis("foo", "baz"), 131 ).RunTestWithBp(t, ` 132 java_sdk_library { 133 name: "foo", 134 srcs: ["b.java"], 135 shared_library: false, 136 public: { 137 enabled: true, 138 }, 139 system: { 140 enabled: true, 141 }, 142 } 143 144 java_library { 145 name: "bar", 146 srcs: ["b.java"], 147 installable: true, 148 } 149 150 apex { 151 name: "com.android.art", 152 key: "com.android.art.key", 153 bootclasspath_fragments: ["art-bootclasspath-fragment"], 154 updatable: false, 155 } 156 157 apex_key { 158 name: "com.android.art.key", 159 public_key: "com.android.art.avbpubkey", 160 private_key: "com.android.art.pem", 161 } 162 163 java_sdk_library { 164 name: "baz", 165 apex_available: [ 166 "com.android.art", 167 ], 168 srcs: ["b.java"], 169 shared_library: false, 170 public: { 171 enabled: true, 172 }, 173 system: { 174 enabled: true, 175 }, 176 test: { 177 enabled: true, 178 }, 179 } 180 181 java_library { 182 name: "quuz", 183 apex_available: [ 184 "com.android.art", 185 ], 186 srcs: ["b.java"], 187 compile_dex: true, 188 } 189 190 bootclasspath_fragment { 191 name: "art-bootclasspath-fragment", 192 image_name: "art", 193 // Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above. 194 contents: ["baz", "quuz"], 195 apex_available: [ 196 "com.android.art", 197 ], 198 hidden_api: { 199 split_packages: ["*"], 200 }, 201 } 202 203 bootclasspath_fragment { 204 name: "other-bootclasspath-fragment", 205 contents: ["foo", "bar"], 206 fragments: [ 207 { 208 apex: "com.android.art", 209 module: "art-bootclasspath-fragment", 210 }, 211 ], 212 hidden_api: { 213 split_packages: ["*"], 214 }, 215 } 216`, 217 ) 218 219 checkAPIScopeStubs := func(message string, info java.HiddenAPIInfo, apiScope *java.HiddenAPIScope, expectedPaths ...string) { 220 t.Helper() 221 paths := info.TransitiveStubDexJarsByScope.StubDexJarsForScope(apiScope) 222 android.AssertPathsRelativeToTopEquals(t, fmt.Sprintf("%s %s", message, apiScope), expectedPaths, paths) 223 } 224 225 // Check stub dex paths exported by art. 226 artFragment := result.Module("art-bootclasspath-fragment", "android_common") 227 artInfo := result.ModuleProvider(artFragment, java.HiddenAPIInfoProvider).(java.HiddenAPIInfo) 228 229 bazPublicStubs := "out/soong/.intermediates/baz.stubs/android_common/dex/baz.stubs.jar" 230 bazSystemStubs := "out/soong/.intermediates/baz.stubs.system/android_common/dex/baz.stubs.system.jar" 231 bazTestStubs := "out/soong/.intermediates/baz.stubs.test/android_common/dex/baz.stubs.test.jar" 232 233 checkAPIScopeStubs("art", artInfo, java.PublicHiddenAPIScope, bazPublicStubs) 234 checkAPIScopeStubs("art", artInfo, java.SystemHiddenAPIScope, bazSystemStubs) 235 checkAPIScopeStubs("art", artInfo, java.TestHiddenAPIScope, bazTestStubs) 236 checkAPIScopeStubs("art", artInfo, java.CorePlatformHiddenAPIScope) 237 238 // Check stub dex paths exported by other. 239 otherFragment := result.Module("other-bootclasspath-fragment", "android_common") 240 otherInfo := result.ModuleProvider(otherFragment, java.HiddenAPIInfoProvider).(java.HiddenAPIInfo) 241 242 fooPublicStubs := "out/soong/.intermediates/foo.stubs/android_common/dex/foo.stubs.jar" 243 fooSystemStubs := "out/soong/.intermediates/foo.stubs.system/android_common/dex/foo.stubs.system.jar" 244 245 checkAPIScopeStubs("other", otherInfo, java.PublicHiddenAPIScope, bazPublicStubs, fooPublicStubs) 246 checkAPIScopeStubs("other", otherInfo, java.SystemHiddenAPIScope, bazSystemStubs, fooSystemStubs) 247 checkAPIScopeStubs("other", otherInfo, java.TestHiddenAPIScope, bazTestStubs, fooSystemStubs) 248 checkAPIScopeStubs("other", otherInfo, java.CorePlatformHiddenAPIScope) 249} 250 251func checkBootclasspathFragment(t *testing.T, result *android.TestResult, moduleName, variantName string, expectedConfiguredModules string) { 252 t.Helper() 253 254 bootclasspathFragment := result.ModuleForTests(moduleName, variantName).Module().(*java.BootclasspathFragmentModule) 255 256 bootclasspathFragmentInfo := result.ModuleProvider(bootclasspathFragment, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo) 257 modules := bootclasspathFragmentInfo.Modules() 258 android.AssertStringEquals(t, "invalid modules for "+moduleName, expectedConfiguredModules, modules.String()) 259} 260 261func TestBootclasspathFragmentInArtApex(t *testing.T) { 262 commonPreparer := android.GroupFixturePreparers( 263 prepareForTestWithBootclasspathFragment, 264 prepareForTestWithArtApex, 265 266 android.FixtureWithRootAndroidBp(` 267 apex { 268 name: "com.android.art", 269 key: "com.android.art.key", 270 bootclasspath_fragments: [ 271 "mybootclasspathfragment", 272 ], 273 // bar (like foo) should be transitively included in this apex because it is part of the 274 // mybootclasspathfragment bootclasspath_fragment. 275 updatable: false, 276 } 277 278 apex_key { 279 name: "com.android.art.key", 280 public_key: "testkey.avbpubkey", 281 private_key: "testkey.pem", 282 } 283 284 java_library { 285 name: "foo", 286 srcs: ["b.java"], 287 installable: true, 288 apex_available: [ 289 "com.android.art", 290 ], 291 } 292 293 java_library { 294 name: "bar", 295 srcs: ["b.java"], 296 installable: true, 297 apex_available: [ 298 "com.android.art", 299 ], 300 } 301 302 java_import { 303 name: "foo", 304 jars: ["foo.jar"], 305 apex_available: [ 306 "com.android.art", 307 ], 308 compile_dex: true, 309 } 310 311 java_import { 312 name: "bar", 313 jars: ["bar.jar"], 314 apex_available: [ 315 "com.android.art", 316 ], 317 compile_dex: true, 318 } 319 `), 320 ) 321 322 contentsInsert := func(contents []string) string { 323 insert := "" 324 if contents != nil { 325 insert = fmt.Sprintf(`contents: ["%s"],`, strings.Join(contents, `", "`)) 326 } 327 return insert 328 } 329 330 addSource := func(contents ...string) android.FixturePreparer { 331 text := fmt.Sprintf(` 332 bootclasspath_fragment { 333 name: "mybootclasspathfragment", 334 image_name: "art", 335 %s 336 apex_available: [ 337 "com.android.art", 338 ], 339 hidden_api: { 340 split_packages: ["*"], 341 }, 342 } 343 `, contentsInsert(contents)) 344 345 return android.FixtureAddTextFile("art/build/boot/Android.bp", text) 346 } 347 348 addPrebuilt := func(prefer bool, contents ...string) android.FixturePreparer { 349 text := fmt.Sprintf(` 350 prebuilt_apex { 351 name: "com.android.art", 352 arch: { 353 arm64: { 354 src: "com.android.art-arm64.apex", 355 }, 356 arm: { 357 src: "com.android.art-arm.apex", 358 }, 359 }, 360 exported_bootclasspath_fragments: ["mybootclasspathfragment"], 361 } 362 363 prebuilt_bootclasspath_fragment { 364 name: "mybootclasspathfragment", 365 image_name: "art", 366 %s 367 prefer: %t, 368 apex_available: [ 369 "com.android.art", 370 ], 371 hidden_api: { 372 annotation_flags: "mybootclasspathfragment/annotation-flags.csv", 373 metadata: "mybootclasspathfragment/metadata.csv", 374 index: "mybootclasspathfragment/index.csv", 375 stub_flags: "mybootclasspathfragment/stub-flags.csv", 376 all_flags: "mybootclasspathfragment/all-flags.csv", 377 }, 378 } 379 `, contentsInsert(contents), prefer) 380 return android.FixtureAddTextFile("prebuilts/module_sdk/art/Android.bp", text) 381 } 382 383 t.Run("boot image files from source", func(t *testing.T) { 384 result := android.GroupFixturePreparers( 385 commonPreparer, 386 387 // Configure some libraries in the art bootclasspath_fragment that match the source 388 // bootclasspath_fragment's contents property. 389 java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"), 390 addSource("foo", "bar"), 391 java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"), 392 ).RunTest(t) 393 394 ensureExactContents(t, result.TestContext, "com.android.art", "android_common_com.android.art_image", []string{ 395 "etc/boot-image.prof", 396 "etc/classpaths/bootclasspath.pb", 397 "javalib/bar.jar", 398 "javalib/foo.jar", 399 }) 400 401 java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art_image", []string{ 402 `com.android.art.key`, 403 `mybootclasspathfragment`, 404 }) 405 406 // Make sure that the source bootclasspath_fragment copies its dex files to the predefined 407 // locations for the art image. 408 module := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000") 409 checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo") 410 }) 411 412 t.Run("generate boot image profile even if dexpreopt is disabled", func(t *testing.T) { 413 result := android.GroupFixturePreparers( 414 commonPreparer, 415 416 // Configure some libraries in the art bootclasspath_fragment that match the source 417 // bootclasspath_fragment's contents property. 418 java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"), 419 addSource("foo", "bar"), 420 java.FixtureSetBootImageInstallDirOnDevice("art", "system/framework"), 421 dexpreopt.FixtureDisableDexpreoptBootImages(true), 422 ).RunTest(t) 423 424 ensureExactContents(t, result.TestContext, "com.android.art", "android_common_com.android.art_image", []string{ 425 "etc/boot-image.prof", 426 "etc/classpaths/bootclasspath.pb", 427 "javalib/bar.jar", 428 "javalib/foo.jar", 429 }) 430 }) 431 432 t.Run("boot image disable generate profile", func(t *testing.T) { 433 result := android.GroupFixturePreparers( 434 commonPreparer, 435 436 // Configure some libraries in the art bootclasspath_fragment that match the source 437 // bootclasspath_fragment's contents property. 438 java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"), 439 addSource("foo", "bar"), 440 dexpreopt.FixtureDisableGenerateProfile(true), 441 ).RunTest(t) 442 443 files := getFiles(t, result.TestContext, "com.android.art", "android_common_com.android.art_image") 444 for _, file := range files { 445 matched, _ := path.Match("etc/boot-image.prof", file.path) 446 android.AssertBoolEquals(t, "\"etc/boot-image.prof\" should not be in the APEX", matched, false) 447 } 448 }) 449 450 t.Run("boot image files with preferred prebuilt", func(t *testing.T) { 451 result := android.GroupFixturePreparers( 452 commonPreparer, 453 454 // Configure some libraries in the art bootclasspath_fragment that match the source 455 // bootclasspath_fragment's contents property. 456 java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"), 457 addSource("foo", "bar"), 458 459 // Make sure that a preferred prebuilt with consistent contents doesn't affect the apex. 460 addPrebuilt(true, "foo", "bar"), 461 462 java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"), 463 ).RunTest(t) 464 465 ensureExactDeapexedContents(t, result.TestContext, "com.android.art", "android_common", []string{ 466 "etc/boot-image.prof", 467 "javalib/bar.jar", 468 "javalib/foo.jar", 469 }) 470 471 java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art_image", []string{ 472 `com.android.art.key`, 473 `mybootclasspathfragment`, 474 `prebuilt_com.android.art`, 475 }) 476 477 // Make sure that the prebuilt bootclasspath_fragment copies its dex files to the predefined 478 // locations for the art image. 479 module := result.ModuleForTests("prebuilt_mybootclasspathfragment", "android_common_com.android.art") 480 checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo") 481 }) 482 483 t.Run("source with inconsistency between config and contents", func(t *testing.T) { 484 android.GroupFixturePreparers( 485 commonPreparer, 486 487 // Create an inconsistency between the ArtApexJars configuration and the art source 488 // bootclasspath_fragment module's contents property. 489 java.FixtureConfigureBootJars("com.android.art:foo"), 490 addSource("foo", "bar"), 491 ). 492 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`\QArtApexJars configuration specifies []string{"foo"}, contents property specifies []string{"foo", "bar"}\E`)). 493 RunTest(t) 494 }) 495 496 t.Run("prebuilt with inconsistency between config and contents", func(t *testing.T) { 497 android.GroupFixturePreparers( 498 commonPreparer, 499 500 // Create an inconsistency between the ArtApexJars configuration and the art 501 // prebuilt_bootclasspath_fragment module's contents property. 502 java.FixtureConfigureBootJars("com.android.art:foo"), 503 addPrebuilt(false, "foo", "bar"), 504 ). 505 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`\QArtApexJars configuration specifies []string{"foo"}, contents property specifies []string{"foo", "bar"}\E`)). 506 RunTest(t) 507 }) 508 509 t.Run("preferred prebuilt with inconsistency between config and contents", func(t *testing.T) { 510 android.GroupFixturePreparers( 511 commonPreparer, 512 513 // Create an inconsistency between the ArtApexJars configuration and the art 514 // prebuilt_bootclasspath_fragment module's contents property. 515 java.FixtureConfigureBootJars("com.android.art:foo"), 516 addPrebuilt(true, "foo", "bar"), 517 518 // Source contents property is consistent with the config. 519 addSource("foo"), 520 ). 521 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`\QArtApexJars configuration specifies []string{"foo"}, contents property specifies []string{"foo", "bar"}\E`)). 522 RunTest(t) 523 }) 524 525 t.Run("source preferred and prebuilt with inconsistency between config and contents", func(t *testing.T) { 526 android.GroupFixturePreparers( 527 commonPreparer, 528 529 // Create an inconsistency between the ArtApexJars configuration and the art 530 // prebuilt_bootclasspath_fragment module's contents property. 531 java.FixtureConfigureBootJars("com.android.art:foo"), 532 addPrebuilt(false, "foo", "bar"), 533 534 // Source contents property is consistent with the config. 535 addSource("foo"), 536 537 // This should pass because while the prebuilt is inconsistent with the configuration it is 538 // not actually used. 539 ).RunTest(t) 540 }) 541} 542 543func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) { 544 preparers := android.GroupFixturePreparers( 545 prepareForTestWithBootclasspathFragment, 546 prepareForTestWithArtApex, 547 548 android.FixtureMergeMockFs(android.MockFS{ 549 "com.android.art-arm64.apex": nil, 550 "com.android.art-arm.apex": nil, 551 }), 552 553 // Configure some libraries in the art bootclasspath_fragment. 554 java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"), 555 java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"), 556 ) 557 558 bp := ` 559 prebuilt_apex { 560 name: "com.android.art", 561 arch: { 562 arm64: { 563 src: "com.android.art-arm64.apex", 564 }, 565 arm: { 566 src: "com.android.art-arm.apex", 567 }, 568 }, 569 exported_bootclasspath_fragments: ["mybootclasspathfragment"], 570 } 571 572 java_import { 573 name: "foo", 574 jars: ["foo.jar"], 575 apex_available: [ 576 "com.android.art", 577 ], 578 } 579 580 java_import { 581 name: "bar", 582 jars: ["bar.jar"], 583 apex_available: [ 584 "com.android.art", 585 ], 586 } 587 588 prebuilt_bootclasspath_fragment { 589 name: "mybootclasspathfragment", 590 image_name: "art", 591 // Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above. 592 contents: ["foo", "bar"], 593 apex_available: [ 594 "com.android.art", 595 ], 596 hidden_api: { 597 annotation_flags: "mybootclasspathfragment/annotation-flags.csv", 598 metadata: "mybootclasspathfragment/metadata.csv", 599 index: "mybootclasspathfragment/index.csv", 600 stub_flags: "mybootclasspathfragment/stub-flags.csv", 601 all_flags: "mybootclasspathfragment/all-flags.csv", 602 }, 603 } 604 605 // A prebuilt apex with the same apex_name that shouldn't interfere when it isn't enabled. 606 prebuilt_apex { 607 name: "com.mycompany.android.art", 608 apex_name: "com.android.art", 609 %s 610 src: "com.mycompany.android.art.apex", 611 exported_bootclasspath_fragments: ["mybootclasspathfragment"], 612 } 613 ` 614 615 t.Run("disabled alternative APEX", func(t *testing.T) { 616 result := preparers.RunTestWithBp(t, fmt.Sprintf(bp, "enabled: false,")) 617 618 java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{ 619 `com.android.art.apex.selector`, 620 `prebuilt_mybootclasspathfragment`, 621 }) 622 623 java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_com.android.art", []string{ 624 `com.android.art.deapexer`, 625 `dex2oatd`, 626 `prebuilt_bar`, 627 `prebuilt_foo`, 628 }) 629 630 module := result.ModuleForTests("mybootclasspathfragment", "android_common_com.android.art") 631 checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo") 632 }) 633 634 t.Run("enabled alternative APEX", func(t *testing.T) { 635 preparers.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( 636 "Multiple installable prebuilt APEXes provide ambiguous deapexers: com.android.art and com.mycompany.android.art")). 637 RunTestWithBp(t, fmt.Sprintf(bp, "")) 638 }) 639} 640 641// checkCopiesToPredefinedLocationForArt checks that the supplied modules are copied to the 642// predefined locations of boot dex jars used as inputs for the ART boot image. 643func checkCopiesToPredefinedLocationForArt(t *testing.T, config android.Config, module android.TestingModule, modules ...string) { 644 t.Helper() 645 bootJarLocations := []string{} 646 for _, output := range module.AllOutputs() { 647 output = android.StringRelativeToTop(config, output) 648 if strings.HasPrefix(output, "out/soong/dexpreopt_arm64/dex_artjars_input/") { 649 bootJarLocations = append(bootJarLocations, output) 650 } 651 } 652 653 sort.Strings(bootJarLocations) 654 expected := []string{} 655 for _, m := range modules { 656 expected = append(expected, fmt.Sprintf("out/soong/dexpreopt_arm64/dex_artjars_input/%s.jar", m)) 657 } 658 sort.Strings(expected) 659 660 android.AssertArrayString(t, "copies to predefined locations for art", expected, bootJarLocations) 661} 662 663func TestBootclasspathFragmentContentsNoName(t *testing.T) { 664 result := android.GroupFixturePreparers( 665 prepareForTestWithBootclasspathFragment, 666 prepareForTestWithMyapex, 667 // Configure bootclasspath jars to ensure that hidden API encoding is performed on them. 668 java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"), 669 // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding 670 // is disabled. 671 android.FixtureAddTextFile("frameworks/base/Android.bp", ""), 672 673 java.PrepareForTestWithJavaSdkLibraryFiles, 674 java.FixtureWithLastReleaseApis("foo"), 675 ).RunTestWithBp(t, ` 676 apex { 677 name: "myapex", 678 key: "myapex.key", 679 bootclasspath_fragments: [ 680 "mybootclasspathfragment", 681 ], 682 updatable: false, 683 } 684 685 apex_key { 686 name: "myapex.key", 687 public_key: "testkey.avbpubkey", 688 private_key: "testkey.pem", 689 } 690 691 java_sdk_library { 692 name: "foo", 693 srcs: ["b.java"], 694 shared_library: false, 695 public: {enabled: true}, 696 apex_available: [ 697 "myapex", 698 ], 699 } 700 701 java_library { 702 name: "bar", 703 srcs: ["b.java"], 704 installable: true, 705 apex_available: [ 706 "myapex", 707 ], 708 } 709 710 bootclasspath_fragment { 711 name: "mybootclasspathfragment", 712 contents: [ 713 "foo", 714 "bar", 715 ], 716 apex_available: [ 717 "myapex", 718 ], 719 hidden_api: { 720 split_packages: ["*"], 721 }, 722 } 723 `) 724 725 ensureExactContents(t, result.TestContext, "myapex", "android_common_myapex_image", []string{ 726 // This does not include art, oat or vdex files as they are only included for the art boot 727 // image. 728 "etc/classpaths/bootclasspath.pb", 729 "javalib/bar.jar", 730 "javalib/foo.jar", 731 }) 732 733 java.CheckModuleDependencies(t, result.TestContext, "myapex", "android_common_myapex_image", []string{ 734 `myapex.key`, 735 `mybootclasspathfragment`, 736 }) 737 738 apex := result.ModuleForTests("myapex", "android_common_myapex_image") 739 apexRule := apex.Rule("apexRule") 740 copyCommands := apexRule.Args["copy_commands"] 741 742 // Make sure that the fragment provides the hidden API encoded dex jars to the APEX. 743 fragment := result.Module("mybootclasspathfragment", "android_common_apex10000") 744 745 info := result.ModuleProvider(fragment, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo) 746 747 checkFragmentExportedDexJar := func(name string, expectedDexJar string) { 748 module := result.Module(name, "android_common_apex10000") 749 dexJar, err := info.DexBootJarPathForContentModule(module) 750 if err != nil { 751 t.Error(err) 752 } 753 android.AssertPathRelativeToTopEquals(t, name+" dex", expectedDexJar, dexJar) 754 755 expectedCopyCommand := fmt.Sprintf("&& cp -f %s out/soong/.intermediates/myapex/android_common_myapex_image/image.apex/javalib/%s.jar", expectedDexJar, name) 756 android.AssertStringDoesContain(t, name+" apex copy command", copyCommands, expectedCopyCommand) 757 } 758 759 checkFragmentExportedDexJar("foo", "out/soong/.intermediates/mybootclasspathfragment/android_common_apex10000/hiddenapi-modular/encoded/foo.jar") 760 checkFragmentExportedDexJar("bar", "out/soong/.intermediates/mybootclasspathfragment/android_common_apex10000/hiddenapi-modular/encoded/bar.jar") 761} 762 763func getDexJarPath(result *android.TestResult, name string) string { 764 module := result.Module(name, "android_common") 765 return module.(java.UsesLibraryDependency).DexJarBuildPath().Path().RelativeToTop().String() 766} 767 768// TestBootclasspathFragment_HiddenAPIList checks to make sure that the correct parameters are 769// passed to the hiddenapi list tool. 770func TestBootclasspathFragment_HiddenAPIList(t *testing.T) { 771 result := android.GroupFixturePreparers( 772 prepareForTestWithBootclasspathFragment, 773 prepareForTestWithArtApex, 774 prepareForTestWithMyapex, 775 // Configure bootclasspath jars to ensure that hidden API encoding is performed on them. 776 java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz"), 777 java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"), 778 // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding 779 // is disabled. 780 android.FixtureAddTextFile("frameworks/base/Android.bp", ""), 781 782 java.PrepareForTestWithJavaSdkLibraryFiles, 783 java.FixtureWithLastReleaseApis("foo", "quuz"), 784 ).RunTestWithBp(t, ` 785 apex { 786 name: "com.android.art", 787 key: "com.android.art.key", 788 bootclasspath_fragments: ["art-bootclasspath-fragment"], 789 updatable: false, 790 } 791 792 apex_key { 793 name: "com.android.art.key", 794 public_key: "com.android.art.avbpubkey", 795 private_key: "com.android.art.pem", 796 } 797 798 java_library { 799 name: "baz", 800 apex_available: [ 801 "com.android.art", 802 ], 803 srcs: ["b.java"], 804 compile_dex: true, 805 } 806 807 java_sdk_library { 808 name: "quuz", 809 apex_available: [ 810 "com.android.art", 811 ], 812 srcs: ["b.java"], 813 compile_dex: true, 814 public: {enabled: true}, 815 system: {enabled: true}, 816 test: {enabled: true}, 817 module_lib: {enabled: true}, 818 } 819 820 bootclasspath_fragment { 821 name: "art-bootclasspath-fragment", 822 image_name: "art", 823 // Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above. 824 contents: ["baz", "quuz"], 825 apex_available: [ 826 "com.android.art", 827 ], 828 hidden_api: { 829 split_packages: ["*"], 830 }, 831 } 832 833 apex { 834 name: "myapex", 835 key: "myapex.key", 836 bootclasspath_fragments: [ 837 "mybootclasspathfragment", 838 ], 839 updatable: false, 840 } 841 842 apex_key { 843 name: "myapex.key", 844 public_key: "testkey.avbpubkey", 845 private_key: "testkey.pem", 846 } 847 848 java_sdk_library { 849 name: "foo", 850 srcs: ["b.java"], 851 shared_library: false, 852 public: {enabled: true}, 853 apex_available: [ 854 "myapex", 855 ], 856 } 857 858 java_library { 859 name: "bar", 860 srcs: ["b.java"], 861 installable: true, 862 apex_available: [ 863 "myapex", 864 ], 865 } 866 867 bootclasspath_fragment { 868 name: "mybootclasspathfragment", 869 contents: [ 870 "foo", 871 "bar", 872 ], 873 apex_available: [ 874 "myapex", 875 ], 876 fragments: [ 877 { 878 apex: "com.android.art", 879 module: "art-bootclasspath-fragment", 880 }, 881 ], 882 hidden_api: { 883 split_packages: ["*"], 884 }, 885 } 886 `) 887 888 java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_apex10000", []string{ 889 "art-bootclasspath-fragment", 890 "bar", 891 "dex2oatd", 892 "foo", 893 }) 894 895 fooStubs := getDexJarPath(result, "foo.stubs") 896 quuzPublicStubs := getDexJarPath(result, "quuz.stubs") 897 quuzSystemStubs := getDexJarPath(result, "quuz.stubs.system") 898 quuzTestStubs := getDexJarPath(result, "quuz.stubs.test") 899 quuzModuleLibStubs := getDexJarPath(result, "quuz.stubs.module_lib") 900 901 // Make sure that the fragment uses the quuz stub dex jars when generating the hidden API flags. 902 fragment := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000") 903 904 rule := fragment.Rule("modularHiddenAPIStubFlagsFile") 905 command := rule.RuleParams.Command 906 android.AssertStringDoesContain(t, "check correct rule", command, "hiddenapi list") 907 908 // Make sure that the quuz stubs are available for resolving references from the implementation 909 // boot dex jars provided by this module. 910 android.AssertStringDoesContain(t, "quuz widest", command, "--dependency-stub-dex="+quuzModuleLibStubs) 911 912 // Make sure that the quuz stubs are available for resolving references from the different API 913 // stubs provided by this module. 914 android.AssertStringDoesContain(t, "public", command, "--public-stub-classpath="+quuzPublicStubs+":"+fooStubs) 915 android.AssertStringDoesContain(t, "system", command, "--system-stub-classpath="+quuzSystemStubs+":"+fooStubs) 916 android.AssertStringDoesContain(t, "test", command, "--test-stub-classpath="+quuzTestStubs+":"+fooStubs) 917} 918 919// TestBootclasspathFragment_AndroidNonUpdatable checks to make sure that setting 920// additional_stubs: ["android-non-updatable"] causes the source android-non-updatable modules to be 921// added to the hiddenapi list tool. 922func TestBootclasspathFragment_AndroidNonUpdatable(t *testing.T) { 923 result := android.GroupFixturePreparers( 924 prepareForTestWithBootclasspathFragment, 925 prepareForTestWithArtApex, 926 prepareForTestWithMyapex, 927 // Configure bootclasspath jars to ensure that hidden API encoding is performed on them. 928 java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz"), 929 java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"), 930 // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding 931 // is disabled. 932 android.FixtureAddTextFile("frameworks/base/Android.bp", ""), 933 934 java.PrepareForTestWithJavaSdkLibraryFiles, 935 java.FixtureWithLastReleaseApis("foo", "android-non-updatable"), 936 ).RunTestWithBp(t, ` 937 java_sdk_library { 938 name: "android-non-updatable", 939 srcs: ["b.java"], 940 compile_dex: true, 941 public: { 942 enabled: true, 943 }, 944 system: { 945 enabled: true, 946 }, 947 test: { 948 enabled: true, 949 }, 950 module_lib: { 951 enabled: true, 952 }, 953 } 954 955 apex { 956 name: "com.android.art", 957 key: "com.android.art.key", 958 bootclasspath_fragments: ["art-bootclasspath-fragment"], 959 updatable: false, 960 } 961 962 apex_key { 963 name: "com.android.art.key", 964 public_key: "com.android.art.avbpubkey", 965 private_key: "com.android.art.pem", 966 } 967 968 java_library { 969 name: "baz", 970 apex_available: [ 971 "com.android.art", 972 ], 973 srcs: ["b.java"], 974 compile_dex: true, 975 } 976 977 java_library { 978 name: "quuz", 979 apex_available: [ 980 "com.android.art", 981 ], 982 srcs: ["b.java"], 983 compile_dex: true, 984 } 985 986 bootclasspath_fragment { 987 name: "art-bootclasspath-fragment", 988 image_name: "art", 989 // Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above. 990 contents: ["baz", "quuz"], 991 apex_available: [ 992 "com.android.art", 993 ], 994 hidden_api: { 995 split_packages: ["*"], 996 }, 997 } 998 999 apex { 1000 name: "myapex", 1001 key: "myapex.key", 1002 bootclasspath_fragments: [ 1003 "mybootclasspathfragment", 1004 ], 1005 updatable: false, 1006 } 1007 1008 apex_key { 1009 name: "myapex.key", 1010 public_key: "testkey.avbpubkey", 1011 private_key: "testkey.pem", 1012 } 1013 1014 java_sdk_library { 1015 name: "foo", 1016 srcs: ["b.java"], 1017 shared_library: false, 1018 public: {enabled: true}, 1019 apex_available: [ 1020 "myapex", 1021 ], 1022 } 1023 1024 java_library { 1025 name: "bar", 1026 srcs: ["b.java"], 1027 installable: true, 1028 apex_available: [ 1029 "myapex", 1030 ], 1031 } 1032 1033 bootclasspath_fragment { 1034 name: "mybootclasspathfragment", 1035 contents: [ 1036 "foo", 1037 "bar", 1038 ], 1039 apex_available: [ 1040 "myapex", 1041 ], 1042 additional_stubs: ["android-non-updatable"], 1043 fragments: [ 1044 { 1045 apex: "com.android.art", 1046 module: "art-bootclasspath-fragment", 1047 }, 1048 ], 1049 hidden_api: { 1050 split_packages: ["*"], 1051 }, 1052 } 1053 `) 1054 1055 java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_apex10000", []string{ 1056 "android-non-updatable.stubs", 1057 "android-non-updatable.stubs.module_lib", 1058 "android-non-updatable.stubs.system", 1059 "android-non-updatable.stubs.test", 1060 "art-bootclasspath-fragment", 1061 "bar", 1062 "dex2oatd", 1063 "foo", 1064 }) 1065 1066 nonUpdatablePublicStubs := getDexJarPath(result, "android-non-updatable.stubs") 1067 nonUpdatableSystemStubs := getDexJarPath(result, "android-non-updatable.stubs.system") 1068 nonUpdatableTestStubs := getDexJarPath(result, "android-non-updatable.stubs.test") 1069 nonUpdatableModuleLibStubs := getDexJarPath(result, "android-non-updatable.stubs.module_lib") 1070 1071 // Make sure that the fragment uses the android-non-updatable modules when generating the hidden 1072 // API flags. 1073 fragment := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000") 1074 1075 rule := fragment.Rule("modularHiddenAPIStubFlagsFile") 1076 command := rule.RuleParams.Command 1077 android.AssertStringDoesContain(t, "check correct rule", command, "hiddenapi list") 1078 1079 // Make sure that the module_lib non-updatable stubs are available for resolving references from 1080 // the implementation boot dex jars provided by this module. 1081 android.AssertStringDoesContain(t, "android-non-updatable widest", command, "--dependency-stub-dex="+nonUpdatableModuleLibStubs) 1082 1083 // Make sure that the appropriate non-updatable stubs are available for resolving references from 1084 // the different API stubs provided by this module. 1085 android.AssertStringDoesContain(t, "public", command, "--public-stub-classpath="+nonUpdatablePublicStubs) 1086 android.AssertStringDoesContain(t, "system", command, "--system-stub-classpath="+nonUpdatableSystemStubs) 1087 android.AssertStringDoesContain(t, "test", command, "--test-stub-classpath="+nonUpdatableTestStubs) 1088} 1089 1090// TestBootclasspathFragment_AndroidNonUpdatable_AlwaysUsePrebuiltSdks checks to make sure that 1091// setting additional_stubs: ["android-non-updatable"] causes the prebuilt android-non-updatable 1092// modules to be added to the hiddenapi list tool. 1093func TestBootclasspathFragment_AndroidNonUpdatable_AlwaysUsePrebuiltSdks(t *testing.T) { 1094 result := android.GroupFixturePreparers( 1095 prepareForTestWithBootclasspathFragment, 1096 java.PrepareForTestWithDexpreopt, 1097 prepareForTestWithArtApex, 1098 prepareForTestWithMyapex, 1099 // Configure bootclasspath jars to ensure that hidden API encoding is performed on them. 1100 java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz"), 1101 java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"), 1102 // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding 1103 // is disabled. 1104 android.FixtureAddTextFile("frameworks/base/Android.bp", ""), 1105 1106 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1107 variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true) 1108 }), 1109 1110 java.PrepareForTestWithJavaSdkLibraryFiles, 1111 java.FixtureWithPrebuiltApis(map[string][]string{ 1112 "current": {"android-non-updatable"}, 1113 "30": {"foo"}, 1114 }), 1115 ).RunTestWithBp(t, ` 1116 apex { 1117 name: "com.android.art", 1118 key: "com.android.art.key", 1119 bootclasspath_fragments: ["art-bootclasspath-fragment"], 1120 updatable: false, 1121 } 1122 1123 apex_key { 1124 name: "com.android.art.key", 1125 public_key: "com.android.art.avbpubkey", 1126 private_key: "com.android.art.pem", 1127 } 1128 1129 java_library { 1130 name: "baz", 1131 apex_available: [ 1132 "com.android.art", 1133 ], 1134 srcs: ["b.java"], 1135 compile_dex: true, 1136 } 1137 1138 java_library { 1139 name: "quuz", 1140 apex_available: [ 1141 "com.android.art", 1142 ], 1143 srcs: ["b.java"], 1144 compile_dex: true, 1145 } 1146 1147 bootclasspath_fragment { 1148 name: "art-bootclasspath-fragment", 1149 image_name: "art", 1150 // Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above. 1151 contents: ["baz", "quuz"], 1152 apex_available: [ 1153 "com.android.art", 1154 ], 1155 hidden_api: { 1156 split_packages: ["*"], 1157 }, 1158 } 1159 1160 apex { 1161 name: "myapex", 1162 key: "myapex.key", 1163 bootclasspath_fragments: [ 1164 "mybootclasspathfragment", 1165 ], 1166 updatable: false, 1167 } 1168 1169 apex_key { 1170 name: "myapex.key", 1171 public_key: "testkey.avbpubkey", 1172 private_key: "testkey.pem", 1173 } 1174 1175 java_sdk_library { 1176 name: "foo", 1177 srcs: ["b.java"], 1178 shared_library: false, 1179 public: {enabled: true}, 1180 apex_available: [ 1181 "myapex", 1182 ], 1183 } 1184 1185 java_library { 1186 name: "bar", 1187 srcs: ["b.java"], 1188 installable: true, 1189 apex_available: [ 1190 "myapex", 1191 ], 1192 } 1193 1194 bootclasspath_fragment { 1195 name: "mybootclasspathfragment", 1196 contents: [ 1197 "foo", 1198 "bar", 1199 ], 1200 apex_available: [ 1201 "myapex", 1202 ], 1203 additional_stubs: ["android-non-updatable"], 1204 fragments: [ 1205 { 1206 apex: "com.android.art", 1207 module: "art-bootclasspath-fragment", 1208 }, 1209 ], 1210 hidden_api: { 1211 split_packages: ["*"], 1212 }, 1213 } 1214 `) 1215 1216 java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_apex10000", []string{ 1217 "art-bootclasspath-fragment", 1218 "bar", 1219 "dex2oatd", 1220 "foo", 1221 "prebuilt_sdk_module-lib_current_android-non-updatable", 1222 "prebuilt_sdk_public_current_android-non-updatable", 1223 "prebuilt_sdk_system_current_android-non-updatable", 1224 "prebuilt_sdk_test_current_android-non-updatable", 1225 }) 1226 1227 nonUpdatablePublicStubs := getDexJarPath(result, "sdk_public_current_android-non-updatable") 1228 nonUpdatableSystemStubs := getDexJarPath(result, "sdk_system_current_android-non-updatable") 1229 nonUpdatableTestStubs := getDexJarPath(result, "sdk_test_current_android-non-updatable") 1230 nonUpdatableModuleLibStubs := getDexJarPath(result, "sdk_module-lib_current_android-non-updatable") 1231 1232 // Make sure that the fragment uses the android-non-updatable modules when generating the hidden 1233 // API flags. 1234 fragment := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000") 1235 1236 rule := fragment.Rule("modularHiddenAPIStubFlagsFile") 1237 command := rule.RuleParams.Command 1238 android.AssertStringDoesContain(t, "check correct rule", command, "hiddenapi list") 1239 1240 // Make sure that the module_lib non-updatable stubs are available for resolving references from 1241 // the implementation boot dex jars provided by this module. 1242 android.AssertStringDoesContain(t, "android-non-updatable widest", command, "--dependency-stub-dex="+nonUpdatableModuleLibStubs) 1243 1244 // Make sure that the appropriate non-updatable stubs are available for resolving references from 1245 // the different API stubs provided by this module. 1246 android.AssertStringDoesContain(t, "public", command, "--public-stub-classpath="+nonUpdatablePublicStubs) 1247 android.AssertStringDoesContain(t, "system", command, "--system-stub-classpath="+nonUpdatableSystemStubs) 1248 android.AssertStringDoesContain(t, "test", command, "--test-stub-classpath="+nonUpdatableTestStubs) 1249} 1250 1251// TODO(b/177892522) - add test for host apex. 1252