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