1// Copyright 2021 Google Inc. All rights reserved. 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 java 16 17import ( 18 "fmt" 19 "path/filepath" 20 "regexp" 21 "strings" 22 "testing" 23 24 "android/soong/android" 25) 26 27func TestJavaSdkLibrary(t *testing.T) { 28 result := android.GroupFixturePreparers( 29 prepareForJavaTest, 30 PrepareForTestWithJavaSdkLibraryFiles, 31 FixtureWithPrebuiltApis(map[string][]string{ 32 "28": {"foo"}, 33 "29": {"foo"}, 34 "30": {"bar", "barney", "baz", "betty", "foo", "fred", "quuz", "wilma"}, 35 }), 36 android.PrepareForTestWithBuildFlag("RELEASE_HIDDEN_API_EXPORTABLE_STUBS", "true"), 37 ).RunTestWithBp(t, ` 38 droiddoc_exported_dir { 39 name: "droiddoc-templates-sdk", 40 path: ".", 41 } 42 java_sdk_library { 43 name: "foo", 44 srcs: ["a.java", "b.java"], 45 api_packages: ["foo"], 46 } 47 java_sdk_library { 48 name: "bar", 49 srcs: ["a.java", "b.java"], 50 api_packages: ["bar"], 51 exclude_kotlinc_generated_files: true, 52 } 53 java_library { 54 name: "baz", 55 srcs: ["c.java"], 56 libs: ["foo.stubs.system", "bar.stubs"], 57 sdk_version: "system_current", 58 } 59 java_sdk_library { 60 name: "barney", 61 srcs: ["c.java"], 62 api_only: true, 63 } 64 java_sdk_library { 65 name: "betty", 66 srcs: ["c.java"], 67 shared_library: false, 68 } 69 java_sdk_library_import { 70 name: "quuz", 71 public: { 72 jars: ["c.jar"], 73 current_api: "api/current.txt", 74 removed_api: "api/removed.txt", 75 }, 76 } 77 java_sdk_library_import { 78 name: "fred", 79 public: { 80 jars: ["b.jar"], 81 }, 82 } 83 java_sdk_library_import { 84 name: "wilma", 85 public: { 86 jars: ["b.jar"], 87 }, 88 shared_library: false, 89 } 90 java_library { 91 name: "qux", 92 srcs: ["c.java"], 93 libs: ["baz", "fred.stubs", "quuz.stubs", "wilma.stubs", "barney.stubs.system", "betty.stubs.system"], 94 sdk_version: "system_current", 95 } 96 java_library { 97 name: "baz-test", 98 srcs: ["c.java"], 99 libs: ["foo.stubs.test"], 100 sdk_version: "test_current", 101 } 102 java_library { 103 name: "baz-29", 104 srcs: ["c.java"], 105 libs: ["sdk_system_29_foo"], 106 sdk_version: "system_29", 107 } 108 java_library { 109 name: "baz-module-30", 110 srcs: ["c.java"], 111 libs: ["sdk_module-lib_30_foo"], 112 sdk_version: "module_30", 113 } 114 `) 115 116 // check the existence of the internal modules 117 foo := result.ModuleForTests("foo", "android_common") 118 result.ModuleForTests(apiScopePublic.stubsLibraryModuleName("foo"), "android_common") 119 result.ModuleForTests(apiScopeSystem.stubsLibraryModuleName("foo"), "android_common") 120 result.ModuleForTests(apiScopeTest.stubsLibraryModuleName("foo"), "android_common") 121 result.ModuleForTests(apiScopePublic.stubsSourceModuleName("foo"), "android_common") 122 result.ModuleForTests(apiScopeSystem.stubsSourceModuleName("foo"), "android_common") 123 result.ModuleForTests(apiScopeTest.stubsSourceModuleName("foo"), "android_common") 124 result.ModuleForTests(apiScopePublic.stubsSourceModuleName("foo")+".api.contribution", "") 125 result.ModuleForTests(apiScopePublic.apiLibraryModuleName("foo"), "android_common") 126 result.ModuleForTests("foo"+sdkXmlFileSuffix, "android_common") 127 result.ModuleForTests("foo.api.public.28", "") 128 result.ModuleForTests("foo.api.system.28", "") 129 result.ModuleForTests("foo.api.test.28", "") 130 131 exportedComponentsInfo, _ := android.OtherModuleProvider(result, foo.Module(), android.ExportedComponentsInfoProvider) 132 expectedFooExportedComponents := []string{ 133 "foo-removed.api.combined.public.latest", 134 "foo-removed.api.combined.system.latest", 135 "foo.api.combined.public.latest", 136 "foo.api.combined.system.latest", 137 "foo.stubs", 138 "foo.stubs.exportable", 139 "foo.stubs.exportable.system", 140 "foo.stubs.exportable.test", 141 "foo.stubs.source", 142 "foo.stubs.source.system", 143 "foo.stubs.source.test", 144 "foo.stubs.system", 145 "foo.stubs.test", 146 } 147 android.AssertArrayString(t, "foo exported components", expectedFooExportedComponents, exportedComponentsInfo.Components) 148 149 bazJavac := result.ModuleForTests("baz", "android_common").Rule("javac") 150 // tests if baz is actually linked to the stubs lib 151 android.AssertStringDoesContain(t, "baz javac classpath", bazJavac.Args["classpath"], "foo.stubs.system.jar") 152 // ... and not to the impl lib 153 android.AssertStringDoesNotContain(t, "baz javac classpath", bazJavac.Args["classpath"], "foo.jar") 154 // test if baz is not linked to the system variant of foo 155 android.AssertStringDoesNotContain(t, "baz javac classpath", bazJavac.Args["classpath"], "foo.stubs.jar") 156 157 bazTestJavac := result.ModuleForTests("baz-test", "android_common").Rule("javac") 158 // tests if baz-test is actually linked to the test stubs lib 159 android.AssertStringDoesContain(t, "baz-test javac classpath", bazTestJavac.Args["classpath"], "foo.stubs.test.jar") 160 161 baz29Javac := result.ModuleForTests("baz-29", "android_common").Rule("javac") 162 // tests if baz-29 is actually linked to the system 29 stubs lib 163 android.AssertStringDoesContain(t, "baz-29 javac classpath", baz29Javac.Args["classpath"], "prebuilts/sdk/sdk_system_29_foo/android_common/combined/sdk_system_29_foo.jar") 164 165 bazModule30Javac := result.ModuleForTests("baz-module-30", "android_common").Rule("javac") 166 // tests if "baz-module-30" is actually linked to the module 30 stubs lib 167 android.AssertStringDoesContain(t, "baz-module-30 javac classpath", bazModule30Javac.Args["classpath"], "prebuilts/sdk/sdk_module-lib_30_foo/android_common/combined/sdk_module-lib_30_foo.jar") 168 169 // test if baz has exported SDK lib names foo and bar to qux 170 qux := result.ModuleForTests("qux", "android_common") 171 if quxLib, ok := qux.Module().(*Library); ok { 172 requiredSdkLibs, optionalSdkLibs := quxLib.ClassLoaderContexts().UsesLibs() 173 android.AssertDeepEquals(t, "qux exports (required)", []string{"fred", "quuz", "foo", "bar"}, requiredSdkLibs) 174 android.AssertDeepEquals(t, "qux exports (optional)", []string{}, optionalSdkLibs) 175 } 176 177 // test if quuz have created the api_contribution module 178 result.ModuleForTests(apiScopePublic.stubsSourceModuleName("quuz")+".api.contribution", "") 179 180 fooImplDexJar := result.ModuleForTests("foo.impl", "android_common").Rule("d8") 181 // tests if kotlinc generated files are NOT excluded from output of foo.impl. 182 android.AssertStringDoesNotContain(t, "foo.impl dex", fooImplDexJar.BuildParams.Args["mergeZipsFlags"], "-stripFile META-INF/*.kotlin_module") 183 184 barImplDexJar := result.ModuleForTests("bar.impl", "android_common").Rule("d8") 185 // tests if kotlinc generated files are excluded from output of bar.impl. 186 android.AssertStringDoesContain(t, "bar.impl dex", barImplDexJar.BuildParams.Args["mergeZipsFlags"], "-stripFile META-INF/*.kotlin_module") 187} 188 189func TestJavaSdkLibrary_UpdatableLibrary(t *testing.T) { 190 result := android.GroupFixturePreparers( 191 prepareForJavaTest, 192 PrepareForTestWithJavaSdkLibraryFiles, 193 FixtureWithPrebuiltApis(map[string][]string{ 194 "28": {"foo"}, 195 "29": {"foo"}, 196 "30": {"foo", "fooUpdatable", "fooUpdatableErr"}, 197 }), 198 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 199 variables.Platform_version_active_codenames = []string{"Tiramisu", "U", "V", "W", "X"} 200 }), 201 ).RunTestWithBp(t, 202 ` 203 java_sdk_library { 204 name: "fooUpdatable", 205 srcs: ["a.java", "b.java"], 206 api_packages: ["foo"], 207 on_bootclasspath_since: "U", 208 on_bootclasspath_before: "V", 209 min_device_sdk: "W", 210 max_device_sdk: "X", 211 min_sdk_version: "S", 212 } 213 java_sdk_library { 214 name: "foo", 215 srcs: ["a.java", "b.java"], 216 api_packages: ["foo"], 217 } 218`) 219 220 // test that updatability attributes are passed on correctly 221 fooUpdatable := result.ModuleForTests("fooUpdatable.xml", "android_common").Output("fooUpdatable.xml") 222 fooUpdatableContents := android.ContentFromFileRuleForTests(t, result.TestContext, fooUpdatable) 223 android.AssertStringDoesContain(t, "fooUpdatable.xml contents", fooUpdatableContents, `on-bootclasspath-since="U"`) 224 android.AssertStringDoesContain(t, "fooUpdatable.xml contents", fooUpdatableContents, `on-bootclasspath-before="V"`) 225 android.AssertStringDoesContain(t, "fooUpdatable.xml contents", fooUpdatableContents, `min-device-sdk="W"`) 226 android.AssertStringDoesContain(t, "fooUpdatable.xml contents", fooUpdatableContents, `max-device-sdk="X"`) 227 228 // double check that updatability attributes are not written if they don't exist in the bp file 229 // the permissions file for the foo library defined above 230 fooPermissions := result.ModuleForTests("foo.xml", "android_common").Output("foo.xml") 231 fooPermissionsContents := android.ContentFromFileRuleForTests(t, result.TestContext, fooPermissions) 232 android.AssertStringDoesNotContain(t, "foo.xml contents", fooPermissionsContents, `on-bootclasspath-since`) 233 android.AssertStringDoesNotContain(t, "foo.xml contents", fooPermissionsContents, `on-bootclasspath-before`) 234 android.AssertStringDoesNotContain(t, "foo.xml contents", fooPermissionsContents, `min-device-sdk`) 235 android.AssertStringDoesNotContain(t, "foo.xml contents", fooPermissionsContents, `max-device-sdk`) 236} 237 238func TestJavaSdkLibrary_UpdatableLibrary_Validation_ValidVersion(t *testing.T) { 239 android.GroupFixturePreparers( 240 prepareForJavaTest, 241 PrepareForTestWithJavaSdkLibraryFiles, 242 FixtureWithPrebuiltApis(map[string][]string{ 243 "30": {"fooUpdatable", "fooUpdatableErr"}, 244 }), 245 ).ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern( 246 []string{ 247 `on_bootclasspath_since: "aaa" could not be parsed as an integer and is not a recognized codename`, 248 `on_bootclasspath_before: "bbc" could not be parsed as an integer and is not a recognized codename`, 249 `min_device_sdk: "ccc" could not be parsed as an integer and is not a recognized codename`, 250 `max_device_sdk: "current" is not an allowed value for this attribute`, 251 })).RunTestWithBp(t, 252 ` 253 java_sdk_library { 254 name: "fooUpdatableErr", 255 srcs: ["a.java", "b.java"], 256 api_packages: ["foo"], 257 on_bootclasspath_since: "aaa", 258 on_bootclasspath_before: "bbc", 259 min_device_sdk: "ccc", 260 max_device_sdk: "current", 261 } 262`) 263} 264 265func TestJavaSdkLibrary_UpdatableLibrary_Validation_AtLeastTAttributes(t *testing.T) { 266 android.GroupFixturePreparers( 267 prepareForJavaTest, 268 PrepareForTestWithJavaSdkLibraryFiles, 269 FixtureWithPrebuiltApis(map[string][]string{ 270 "28": {"foo"}, 271 }), 272 ).ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern( 273 []string{ 274 "on_bootclasspath_since: Attribute value needs to be at least T", 275 "on_bootclasspath_before: Attribute value needs to be at least T", 276 "min_device_sdk: Attribute value needs to be at least T", 277 "max_device_sdk: Attribute value needs to be at least T", 278 }, 279 )).RunTestWithBp(t, 280 ` 281 java_sdk_library { 282 name: "foo", 283 srcs: ["a.java", "b.java"], 284 api_packages: ["foo"], 285 on_bootclasspath_since: "S", 286 on_bootclasspath_before: "S", 287 min_device_sdk: "S", 288 max_device_sdk: "S", 289 min_sdk_version: "S", 290 } 291`) 292} 293 294func TestJavaSdkLibrary_UpdatableLibrary_Validation_MinAndMaxDeviceSdk(t *testing.T) { 295 android.GroupFixturePreparers( 296 prepareForJavaTest, 297 PrepareForTestWithJavaSdkLibraryFiles, 298 FixtureWithPrebuiltApis(map[string][]string{ 299 "28": {"foo"}, 300 }), 301 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 302 variables.Platform_version_active_codenames = []string{"Tiramisu", "U", "V"} 303 }), 304 ).ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern( 305 []string{ 306 "min_device_sdk can't be greater than max_device_sdk", 307 }, 308 )).RunTestWithBp(t, 309 ` 310 java_sdk_library { 311 name: "foo", 312 srcs: ["a.java", "b.java"], 313 api_packages: ["foo"], 314 min_device_sdk: "V", 315 max_device_sdk: "U", 316 min_sdk_version: "S", 317 } 318`) 319} 320 321func TestJavaSdkLibrary_UpdatableLibrary_Validation_MinAndMaxDeviceSdkAndModuleMinSdk(t *testing.T) { 322 android.GroupFixturePreparers( 323 prepareForJavaTest, 324 PrepareForTestWithJavaSdkLibraryFiles, 325 FixtureWithPrebuiltApis(map[string][]string{ 326 "28": {"foo"}, 327 }), 328 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 329 variables.Platform_version_active_codenames = []string{"Tiramisu", "U", "V"} 330 }), 331 ).ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern( 332 []string{ 333 regexp.QuoteMeta("min_device_sdk: Can't be less than module's min sdk (V)"), 334 regexp.QuoteMeta("max_device_sdk: Can't be less than module's min sdk (V)"), 335 }, 336 )).RunTestWithBp(t, 337 ` 338 java_sdk_library { 339 name: "foo", 340 srcs: ["a.java", "b.java"], 341 api_packages: ["foo"], 342 min_device_sdk: "U", 343 max_device_sdk: "U", 344 min_sdk_version: "V", 345 } 346`) 347} 348 349func TestJavaSdkLibrary_UpdatableLibrary_usesNewTag(t *testing.T) { 350 result := android.GroupFixturePreparers( 351 prepareForJavaTest, 352 PrepareForTestWithJavaSdkLibraryFiles, 353 FixtureWithPrebuiltApis(map[string][]string{ 354 "30": {"foo"}, 355 }), 356 ).RunTestWithBp(t, 357 ` 358 java_sdk_library { 359 name: "foo", 360 srcs: ["a.java", "b.java"], 361 min_device_sdk: "Tiramisu", 362 min_sdk_version: "S", 363 } 364`) 365 // test that updatability attributes are passed on correctly 366 fooUpdatable := result.ModuleForTests("foo.xml", "android_common").Output("foo.xml") 367 fooUpdatableContents := android.ContentFromFileRuleForTests(t, result.TestContext, fooUpdatable) 368 android.AssertStringDoesContain(t, "foo.xml contents", fooUpdatableContents, `<apex-library`) 369 android.AssertStringDoesNotContain(t, "foo.xml contents", fooUpdatableContents, `<library`) 370} 371 372func TestJavaSdkLibrary_StubOrImplOnlyLibs(t *testing.T) { 373 result := android.GroupFixturePreparers( 374 prepareForJavaTest, 375 PrepareForTestWithJavaSdkLibraryFiles, 376 FixtureWithLastReleaseApis("sdklib"), 377 ).RunTestWithBp(t, ` 378 java_sdk_library { 379 name: "sdklib", 380 srcs: ["a.java"], 381 libs: ["lib"], 382 static_libs: ["static-lib"], 383 impl_only_libs: ["impl-only-lib"], 384 stub_only_libs: ["stub-only-lib"], 385 stub_only_static_libs: ["stub-only-static-lib"], 386 } 387 java_defaults { 388 name: "defaults", 389 srcs: ["a.java"], 390 sdk_version: "current", 391 } 392 java_library { name: "lib", defaults: ["defaults"] } 393 java_library { name: "static-lib", defaults: ["defaults"] } 394 java_library { name: "impl-only-lib", defaults: ["defaults"] } 395 java_library { name: "stub-only-lib", defaults: ["defaults"] } 396 java_library { name: "stub-only-static-lib", defaults: ["defaults"] } 397 `) 398 var expectations = []struct { 399 lib string 400 on_impl_classpath bool 401 on_stub_classpath bool 402 in_impl_combined bool 403 in_stub_combined bool 404 }{ 405 {lib: "lib", on_impl_classpath: true}, 406 {lib: "static-lib", in_impl_combined: true}, 407 {lib: "impl-only-lib", on_impl_classpath: true}, 408 {lib: "stub-only-lib", on_stub_classpath: true}, 409 {lib: "stub-only-static-lib", in_stub_combined: true}, 410 } 411 verify := func(sdklib, dep string, cp, combined bool) { 412 sdklibCp := result.ModuleForTests(sdklib, "android_common").Rule("javac").Args["classpath"] 413 expected := cp || combined // Every combined jar is also on the classpath. 414 android.AssertStringContainsEquals(t, "bad classpath for "+sdklib, sdklibCp, "/"+dep+".jar", expected) 415 416 combineJarInputs := result.ModuleForTests(sdklib, "android_common").Rule("combineJar").Inputs.Strings() 417 depPath := filepath.Join("out", "soong", ".intermediates", dep, "android_common", "turbine-combined", dep+".jar") 418 android.AssertStringListContainsEquals(t, "bad combined inputs for "+sdklib, combineJarInputs, depPath, combined) 419 } 420 for _, expectation := range expectations { 421 verify("sdklib.impl", expectation.lib, expectation.on_impl_classpath, expectation.in_impl_combined) 422 423 stubName := apiScopePublic.sourceStubsLibraryModuleName("sdklib") 424 verify(stubName, expectation.lib, expectation.on_stub_classpath, expectation.in_stub_combined) 425 } 426} 427 428func TestJavaSdkLibrary_DoNotAccessImplWhenItIsNotBuilt(t *testing.T) { 429 result := android.GroupFixturePreparers( 430 prepareForJavaTest, 431 PrepareForTestWithJavaSdkLibraryFiles, 432 FixtureWithLastReleaseApis("foo"), 433 ).RunTestWithBp(t, ` 434 java_sdk_library { 435 name: "foo", 436 srcs: ["a.java"], 437 api_only: true, 438 public: { 439 enabled: true, 440 }, 441 } 442 443 java_library { 444 name: "bar", 445 srcs: ["b.java"], 446 libs: ["foo.stubs"], 447 } 448 `) 449 450 // The bar library should depend on the stubs jar. 451 barLibrary := result.ModuleForTests("bar", "android_common").Rule("javac") 452 if expected, actual := `^-classpath .*:out/soong/[^:]*/turbine-combined/foo\.stubs\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { 453 t.Errorf("expected %q, found %#q", expected, actual) 454 } 455} 456 457func TestJavaSdkLibrary_AccessOutputFiles(t *testing.T) { 458 android.GroupFixturePreparers( 459 prepareForJavaTest, 460 PrepareForTestWithJavaSdkLibraryFiles, 461 FixtureWithLastReleaseApis("foo"), 462 ).RunTestWithBp(t, ` 463 java_sdk_library { 464 name: "foo", 465 srcs: ["a.java"], 466 api_packages: ["foo"], 467 annotations_enabled: true, 468 public: { 469 enabled: true, 470 }, 471 } 472 java_library { 473 name: "bar", 474 srcs: ["b.java", ":foo{.public.stubs.source}"], 475 java_resources: [":foo{.public.annotations.zip}"], 476 } 477 `) 478} 479 480func TestJavaSdkLibrary_AccessOutputFiles_NoAnnotations(t *testing.T) { 481 android.GroupFixturePreparers( 482 prepareForJavaTest, 483 PrepareForTestWithJavaSdkLibraryFiles, 484 FixtureWithLastReleaseApis("foo"), 485 ). 486 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "bar" variant "android_common": unsupported module reference tag ".public.annotations.zip"`)). 487 RunTestWithBp(t, ` 488 java_sdk_library { 489 name: "foo", 490 srcs: ["a.java"], 491 api_packages: ["foo"], 492 public: { 493 enabled: true, 494 }, 495 } 496 497 java_library { 498 name: "bar", 499 srcs: ["b.java", ":foo{.public.stubs.source}"], 500 java_resources: [":foo{.public.annotations.zip}"], 501 } 502 `) 503} 504 505func TestJavaSdkLibrary_AccessOutputFiles_MissingScope(t *testing.T) { 506 android.GroupFixturePreparers( 507 prepareForJavaTest, 508 PrepareForTestWithJavaSdkLibraryFiles, 509 FixtureWithLastReleaseApis("foo"), 510 ). 511 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "bar" variant "android_common": unsupported module reference tag ".system.stubs.source"`)). 512 RunTestWithBp(t, ` 513 java_sdk_library { 514 name: "foo", 515 srcs: ["a.java"], 516 api_packages: ["foo"], 517 public: { 518 enabled: true, 519 }, 520 } 521 522 java_library { 523 name: "bar", 524 srcs: ["b.java", ":foo{.system.stubs.source}"], 525 } 526 `) 527} 528 529func TestJavaSdkLibrary_Deps(t *testing.T) { 530 result := android.GroupFixturePreparers( 531 prepareForJavaTest, 532 PrepareForTestWithJavaSdkLibraryFiles, 533 FixtureWithLastReleaseApis("sdklib"), 534 android.PrepareForTestWithBuildFlag("RELEASE_HIDDEN_API_EXPORTABLE_STUBS", "true"), 535 ).RunTestWithBp(t, ` 536 java_sdk_library { 537 name: "sdklib", 538 srcs: ["a.java"], 539 sdk_version: "none", 540 system_modules: "none", 541 public: { 542 enabled: true, 543 }, 544 } 545 `) 546 547 CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{ 548 `dex2oatd`, 549 `sdklib-removed.api.combined.public.latest`, 550 `sdklib.api.combined.public.latest`, 551 `sdklib.impl`, 552 `sdklib.stubs`, 553 `sdklib.stubs.exportable`, 554 `sdklib.stubs.source`, 555 `sdklib.xml`, 556 }) 557} 558 559func TestJavaSdkLibraryImport_AccessOutputFiles(t *testing.T) { 560 prepareForJavaTest.RunTestWithBp(t, ` 561 java_sdk_library_import { 562 name: "foo", 563 public: { 564 jars: ["a.jar"], 565 stub_srcs: ["a.java"], 566 current_api: "api/current.txt", 567 removed_api: "api/removed.txt", 568 annotations: "x/annotations.zip", 569 }, 570 } 571 572 java_library { 573 name: "bar", 574 srcs: [":foo{.public.stubs.source}"], 575 java_resources: [ 576 ":foo{.public.api.txt}", 577 ":foo{.public.removed-api.txt}", 578 ":foo{.public.annotations.zip}", 579 ], 580 } 581 `) 582} 583 584func TestJavaSdkLibraryImport_AccessOutputFiles_Invalid(t *testing.T) { 585 bp := ` 586 java_sdk_library_import { 587 name: "foo", 588 public: { 589 jars: ["a.jar"], 590 }, 591 } 592 ` 593 594 t.Run("stubs.source", func(t *testing.T) { 595 prepareForJavaTest. 596 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo" is not a SourceFileProducer or having valid output file for tag ".public.stubs.source"`)). 597 RunTestWithBp(t, bp+` 598 java_library { 599 name: "bar", 600 srcs: [":foo{.public.stubs.source}"], 601 java_resources: [ 602 ":foo{.public.api.txt}", 603 ":foo{.public.removed-api.txt}", 604 ], 605 } 606 `) 607 }) 608 609 t.Run("api.txt", func(t *testing.T) { 610 prepareForJavaTest. 611 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo" is not a SourceFileProducer or having valid output file for tag ".public.api.txt"`)). 612 RunTestWithBp(t, bp+` 613 java_library { 614 name: "bar", 615 srcs: ["a.java"], 616 java_resources: [ 617 ":foo{.public.api.txt}", 618 ], 619 } 620 `) 621 }) 622 623 t.Run("removed-api.txt", func(t *testing.T) { 624 prepareForJavaTest. 625 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo" is not a SourceFileProducer or having valid output file for tag ".public.removed-api.txt"`)). 626 RunTestWithBp(t, bp+` 627 java_library { 628 name: "bar", 629 srcs: ["a.java"], 630 java_resources: [ 631 ":foo{.public.removed-api.txt}", 632 ], 633 } 634 `) 635 }) 636} 637 638func TestJavaSdkLibrary_InvalidScopes(t *testing.T) { 639 prepareForJavaTest. 640 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo": enabled api scope "system" depends on disabled scope "public"`)). 641 RunTestWithBp(t, ` 642 java_sdk_library { 643 name: "foo", 644 srcs: ["a.java", "b.java"], 645 api_packages: ["foo"], 646 // Explicitly disable public to test the check that ensures the set of enabled 647 // scopes is consistent. 648 public: { 649 enabled: false, 650 }, 651 system: { 652 enabled: true, 653 }, 654 } 655 `) 656} 657 658func TestJavaSdkLibrary_SdkVersion_ForScope(t *testing.T) { 659 android.GroupFixturePreparers( 660 prepareForJavaTest, 661 PrepareForTestWithJavaSdkLibraryFiles, 662 FixtureWithLastReleaseApis("foo"), 663 ).RunTestWithBp(t, ` 664 java_sdk_library { 665 name: "foo", 666 srcs: ["a.java", "b.java"], 667 api_packages: ["foo"], 668 system: { 669 enabled: true, 670 sdk_version: "module_current", 671 }, 672 } 673 `) 674} 675 676func TestJavaSdkLibrary_ModuleLib(t *testing.T) { 677 android.GroupFixturePreparers( 678 prepareForJavaTest, 679 PrepareForTestWithJavaSdkLibraryFiles, 680 FixtureWithLastReleaseApis("foo"), 681 ).RunTestWithBp(t, ` 682 java_sdk_library { 683 name: "foo", 684 srcs: ["a.java", "b.java"], 685 api_packages: ["foo"], 686 system: { 687 enabled: true, 688 }, 689 module_lib: { 690 enabled: true, 691 }, 692 } 693 `) 694} 695 696func TestJavaSdkLibrary_SystemServer(t *testing.T) { 697 android.GroupFixturePreparers( 698 prepareForJavaTest, 699 PrepareForTestWithJavaSdkLibraryFiles, 700 FixtureWithLastReleaseApis("foo"), 701 ).RunTestWithBp(t, ` 702 java_sdk_library { 703 name: "foo", 704 srcs: ["a.java", "b.java"], 705 api_packages: ["foo"], 706 system: { 707 enabled: true, 708 }, 709 system_server: { 710 enabled: true, 711 }, 712 } 713 `) 714} 715 716func TestJavaSdkLibrary_SystemServer_AccessToStubScopeLibs(t *testing.T) { 717 result := android.GroupFixturePreparers( 718 prepareForJavaTest, 719 PrepareForTestWithJavaSdkLibraryFiles, 720 FixtureWithLastReleaseApis("foo-public", "foo-system", "foo-module-lib", "foo-system-server"), 721 ).RunTestWithBp(t, ` 722 java_sdk_library { 723 name: "foo-public", 724 srcs: ["a.java"], 725 api_packages: ["foo"], 726 public: { 727 enabled: true, 728 }, 729 } 730 731 java_sdk_library { 732 name: "foo-system", 733 srcs: ["a.java"], 734 api_packages: ["foo"], 735 system: { 736 enabled: true, 737 }, 738 } 739 740 java_sdk_library { 741 name: "foo-module-lib", 742 srcs: ["a.java"], 743 api_packages: ["foo"], 744 system: { 745 enabled: true, 746 }, 747 module_lib: { 748 enabled: true, 749 }, 750 } 751 752 java_sdk_library { 753 name: "foo-system-server", 754 srcs: ["a.java"], 755 api_packages: ["foo"], 756 system_server: { 757 enabled: true, 758 }, 759 } 760 761 java_library { 762 name: "bar", 763 srcs: ["a.java"], 764 libs: ["foo-public.stubs", "foo-system.stubs.system", "foo-module-lib.stubs.module_lib", "foo-system-server.stubs.system_server"], 765 sdk_version: "system_server_current", 766 } 767 `) 768 769 stubsPath := func(name string, scope *apiScope) string { 770 name = scope.stubsLibraryModuleName(name) 771 return fmt.Sprintf("out/soong/.intermediates/%[1]s/android_common/turbine-combined/%[1]s.jar", name) 772 } 773 774 // The bar library should depend on the highest (where system server is highest and public is 775 // lowest) API scopes provided by each of the foo-* modules. The highest API scope provided by the 776 // foo-<x> module is <x>. 777 barLibrary := result.ModuleForTests("bar", "android_common").Rule("javac") 778 stubLibraries := []string{ 779 stubsPath("foo-public", apiScopePublic), 780 stubsPath("foo-system", apiScopeSystem), 781 stubsPath("foo-module-lib", apiScopeModuleLib), 782 stubsPath("foo-system-server", apiScopeSystemServer), 783 } 784 expectedPattern := fmt.Sprintf(`^-classpath .*:\Q%s\E$`, strings.Join(stubLibraries, ":")) 785 if expected, actual := expectedPattern, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { 786 t.Errorf("expected pattern %q to match %#q", expected, actual) 787 } 788} 789 790func TestJavaSdkLibraryImport(t *testing.T) { 791 result := prepareForJavaTest.RunTestWithBp(t, ` 792 java_library { 793 name: "foo", 794 srcs: ["a.java"], 795 libs: ["sdklib.stubs"], 796 sdk_version: "current", 797 } 798 799 java_library { 800 name: "foo.system", 801 srcs: ["a.java"], 802 libs: ["sdklib.stubs.system"], 803 sdk_version: "system_current", 804 } 805 806 java_library { 807 name: "foo.test", 808 srcs: ["a.java"], 809 libs: ["sdklib.stubs.test"], 810 sdk_version: "test_current", 811 } 812 813 java_sdk_library_import { 814 name: "sdklib", 815 public: { 816 jars: ["a.jar"], 817 }, 818 system: { 819 jars: ["b.jar"], 820 }, 821 test: { 822 jars: ["c.jar"], 823 stub_srcs: ["c.java"], 824 }, 825 } 826 `) 827 828 for _, scope := range []string{"", ".system", ".test"} { 829 fooModule := result.ModuleForTests("foo"+scope, "android_common") 830 javac := fooModule.Rule("javac") 831 832 sdklibStubsJar := result.ModuleForTests("sdklib.stubs"+scope, "android_common").Output("combined/sdklib.stubs" + scope + ".jar").Output 833 android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], sdklibStubsJar.String()) 834 } 835 836 CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{ 837 `all_apex_contributions`, 838 `dex2oatd`, 839 `prebuilt_sdklib.stubs`, 840 `prebuilt_sdklib.stubs.source.test`, 841 `prebuilt_sdklib.stubs.system`, 842 `prebuilt_sdklib.stubs.test`, 843 }) 844} 845 846func TestJavaSdkLibraryImport_WithSource(t *testing.T) { 847 result := android.GroupFixturePreparers( 848 prepareForJavaTest, 849 PrepareForTestWithJavaSdkLibraryFiles, 850 FixtureWithLastReleaseApis("sdklib"), 851 android.PrepareForTestWithBuildFlag("RELEASE_HIDDEN_API_EXPORTABLE_STUBS", "true"), 852 ).RunTestWithBp(t, ` 853 java_sdk_library { 854 name: "sdklib", 855 srcs: ["a.java"], 856 sdk_version: "none", 857 system_modules: "none", 858 public: { 859 enabled: true, 860 }, 861 } 862 863 java_sdk_library_import { 864 name: "sdklib", 865 public: { 866 jars: ["a.jar"], 867 }, 868 } 869 `) 870 871 CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{ 872 `dex2oatd`, 873 `prebuilt_sdklib`, 874 `sdklib-removed.api.combined.public.latest`, 875 `sdklib.api.combined.public.latest`, 876 `sdklib.impl`, 877 `sdklib.stubs`, 878 `sdklib.stubs.exportable`, 879 `sdklib.stubs.source`, 880 `sdklib.xml`, 881 }) 882 883 CheckModuleDependencies(t, result.TestContext, "prebuilt_sdklib", "android_common", []string{ 884 `all_apex_contributions`, 885 `prebuilt_sdklib.stubs`, 886 `sdklib.impl`, 887 // This should be prebuilt_sdklib.stubs but is set to sdklib.stubs because the 888 // dependency is added after prebuilts may have been renamed and so has to use 889 // the renamed name. 890 `sdklib.xml`, 891 }) 892} 893 894func testJavaSdkLibraryImport_Preferred(t *testing.T, prefer string, preparer android.FixturePreparer) { 895 result := android.GroupFixturePreparers( 896 prepareForJavaTest, 897 PrepareForTestWithJavaSdkLibraryFiles, 898 FixtureWithLastReleaseApis("sdklib"), 899 preparer, 900 android.PrepareForTestWithBuildFlag("RELEASE_HIDDEN_API_EXPORTABLE_STUBS", "true"), 901 ).RunTestWithBp(t, ` 902 java_sdk_library { 903 name: "sdklib", 904 srcs: ["a.java"], 905 sdk_version: "none", 906 system_modules: "none", 907 public: { 908 enabled: true, 909 }, 910 } 911 912 java_sdk_library_import { 913 name: "sdklib", 914 `+prefer+` 915 public: { 916 jars: ["a.jar"], 917 stub_srcs: ["a.java"], 918 current_api: "current.txt", 919 removed_api: "removed.txt", 920 annotations: "annotations.zip", 921 }, 922 } 923 924 java_library { 925 name: "combined", 926 static_libs: [ 927 "sdklib.stubs", 928 ], 929 java_resources: [ 930 ":sdklib.stubs.source", 931 ":sdklib{.public.api.txt}", 932 ":sdklib{.public.removed-api.txt}", 933 ":sdklib{.public.annotations.zip}", 934 ], 935 sdk_version: "none", 936 system_modules: "none", 937 } 938 939 java_library { 940 name: "public", 941 srcs: ["a.java"], 942 libs: ["sdklib.stubs"], 943 sdk_version: "current", 944 } 945 `) 946 947 CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{ 948 `prebuilt_sdklib`, 949 `sdklib-removed.api.combined.public.latest`, 950 `sdklib.api.combined.public.latest`, 951 `sdklib.impl`, 952 `sdklib.stubs`, 953 `sdklib.stubs.exportable`, 954 `sdklib.stubs.source`, 955 `sdklib.xml`, 956 }) 957 958 CheckModuleDependencies(t, result.TestContext, "prebuilt_sdklib", "android_common", []string{ 959 `all_apex_contributions`, 960 `dex2oatd`, 961 `prebuilt_sdklib.stubs`, 962 `prebuilt_sdklib.stubs.source`, 963 `sdklib.impl`, 964 `sdklib.xml`, 965 }) 966 967 // Make sure that dependencies on child modules use the prebuilt when preferred. 968 CheckModuleDependencies(t, result.TestContext, "combined", "android_common", []string{ 969 // Each use of :sdklib{...} adds a dependency onto prebuilt_sdklib. 970 `prebuilt_sdklib`, 971 `prebuilt_sdklib`, 972 `prebuilt_sdklib`, 973 `prebuilt_sdklib.stubs`, 974 `prebuilt_sdklib.stubs.source`, 975 }) 976 977 // Make sure that dependencies on sdklib that resolve to one of the child libraries use the 978 // prebuilt library. 979 public := result.ModuleForTests("public", "android_common") 980 rule := public.Output("javac/public.jar") 981 inputs := rule.Implicits.Strings() 982 expected := "out/soong/.intermediates/prebuilt_sdklib.stubs/android_common/combined/sdklib.stubs.jar" 983 if !android.InList(expected, inputs) { 984 t.Errorf("expected %q to contain %q", inputs, expected) 985 } 986} 987 988func TestJavaSdkLibraryImport_Preferred(t *testing.T) { 989 t.Run("prefer", func(t *testing.T) { 990 testJavaSdkLibraryImport_Preferred(t, "prefer: true,", android.NullFixturePreparer) 991 }) 992} 993 994// If a module is listed in `mainline_module_contributions, it should be used 995// It will supersede any other source vs prebuilt selection mechanism like `prefer` attribute 996func TestSdkLibraryImport_MetadataModuleSupersedesPreferred(t *testing.T) { 997 bp := ` 998 apex_contributions { 999 name: "my_mainline_module_contributions", 1000 api_domain: "my_mainline_module", 1001 contents: [ 1002 // legacy mechanism prefers the prebuilt 1003 // mainline_module_contributions supersedes this since source is listed explicitly 1004 "sdklib.prebuilt_preferred_using_legacy_flags", 1005 1006 // legacy mechanism prefers the source 1007 // mainline_module_contributions supersedes this since prebuilt is listed explicitly 1008 "prebuilt_sdklib.source_preferred_using_legacy_flags", 1009 ], 1010 } 1011 java_sdk_library { 1012 name: "sdklib.prebuilt_preferred_using_legacy_flags", 1013 srcs: ["a.java"], 1014 sdk_version: "none", 1015 system_modules: "none", 1016 public: { 1017 enabled: true, 1018 }, 1019 system: { 1020 enabled: true, 1021 } 1022 } 1023 java_sdk_library_import { 1024 name: "sdklib.prebuilt_preferred_using_legacy_flags", 1025 prefer: true, // prebuilt is preferred using legacy mechanism 1026 public: { 1027 jars: ["a.jar"], 1028 stub_srcs: ["a.java"], 1029 current_api: "current.txt", 1030 removed_api: "removed.txt", 1031 annotations: "annotations.zip", 1032 }, 1033 system: { 1034 jars: ["a.jar"], 1035 stub_srcs: ["a.java"], 1036 current_api: "current.txt", 1037 removed_api: "removed.txt", 1038 annotations: "annotations.zip", 1039 }, 1040 } 1041 java_sdk_library { 1042 name: "sdklib.source_preferred_using_legacy_flags", 1043 srcs: ["a.java"], 1044 sdk_version: "none", 1045 system_modules: "none", 1046 public: { 1047 enabled: true, 1048 }, 1049 system: { 1050 enabled: true, 1051 } 1052 } 1053 java_sdk_library_import { 1054 name: "sdklib.source_preferred_using_legacy_flags", 1055 prefer: false, // source is preferred using legacy mechanism 1056 public: { 1057 jars: ["a.jar"], 1058 stub_srcs: ["a.java"], 1059 current_api: "current.txt", 1060 removed_api: "removed.txt", 1061 annotations: "annotations.zip", 1062 }, 1063 system: { 1064 jars: ["a.jar"], 1065 stub_srcs: ["a.java"], 1066 current_api: "current.txt", 1067 removed_api: "removed.txt", 1068 annotations: "annotations.zip", 1069 }, 1070 } 1071 1072 // rdeps 1073 java_library { 1074 name: "public", 1075 srcs: ["a.java"], 1076 libs: [ 1077 // this should get source since source is listed in my_mainline_module_contributions 1078 "sdklib.prebuilt_preferred_using_legacy_flags.stubs", 1079 "sdklib.prebuilt_preferred_using_legacy_flags.stubs.system", 1080 1081 // this should get prebuilt since source is listed in my_mainline_module_contributions 1082 "sdklib.source_preferred_using_legacy_flags.stubs", 1083 "sdklib.source_preferred_using_legacy_flags.stubs.system", 1084 1085 ], 1086 } 1087 ` 1088 result := android.GroupFixturePreparers( 1089 prepareForJavaTest, 1090 PrepareForTestWithJavaSdkLibraryFiles, 1091 FixtureWithLastReleaseApis("sdklib.source_preferred_using_legacy_flags", "sdklib.prebuilt_preferred_using_legacy_flags"), 1092 android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ADSERVICES", "my_mainline_module_contributions"), 1093 ).RunTestWithBp(t, bp) 1094 1095 // Make sure that rdeps get the correct source vs prebuilt based on mainline_module_contributions 1096 public := result.ModuleForTests("public", "android_common") 1097 rule := public.Output("javac/public.jar") 1098 inputs := rule.Implicits.Strings() 1099 expectedInputs := []string{ 1100 // source 1101 "out/soong/.intermediates/sdklib.prebuilt_preferred_using_legacy_flags.stubs/android_common/turbine-combined/sdklib.prebuilt_preferred_using_legacy_flags.stubs.jar", 1102 "out/soong/.intermediates/sdklib.prebuilt_preferred_using_legacy_flags.stubs.system/android_common/turbine-combined/sdklib.prebuilt_preferred_using_legacy_flags.stubs.system.jar", 1103 1104 // prebuilt 1105 "out/soong/.intermediates/prebuilt_sdklib.source_preferred_using_legacy_flags.stubs/android_common/combined/sdklib.source_preferred_using_legacy_flags.stubs.jar", 1106 "out/soong/.intermediates/prebuilt_sdklib.source_preferred_using_legacy_flags.stubs.system/android_common/combined/sdklib.source_preferred_using_legacy_flags.stubs.system.jar", 1107 } 1108 for _, expected := range expectedInputs { 1109 if !android.InList(expected, inputs) { 1110 t.Errorf("expected %q to contain %q", inputs, expected) 1111 } 1112 } 1113} 1114 1115func TestJavaSdkLibraryDist(t *testing.T) { 1116 result := android.GroupFixturePreparers( 1117 PrepareForTestWithJavaBuildComponents, 1118 PrepareForTestWithJavaDefaultModules, 1119 PrepareForTestWithJavaSdkLibraryFiles, 1120 FixtureWithLastReleaseApis( 1121 "sdklib_no_group", 1122 "sdklib_group_foo", 1123 "sdklib_owner_foo", 1124 "foo"), 1125 android.PrepareForTestWithBuildFlag("RELEASE_HIDDEN_API_EXPORTABLE_STUBS", "true"), 1126 ).RunTestWithBp(t, ` 1127 java_sdk_library { 1128 name: "sdklib_no_group", 1129 srcs: ["foo.java"], 1130 } 1131 1132 java_sdk_library { 1133 name: "sdklib_group_foo", 1134 srcs: ["foo.java"], 1135 dist_group: "foo", 1136 } 1137 1138 java_sdk_library { 1139 name: "sdklib_owner_foo", 1140 srcs: ["foo.java"], 1141 owner: "foo", 1142 } 1143 1144 java_sdk_library { 1145 name: "sdklib_stem_foo", 1146 srcs: ["foo.java"], 1147 dist_stem: "foo", 1148 } 1149 `) 1150 1151 type testCase struct { 1152 module string 1153 distDir string 1154 distStem string 1155 } 1156 testCases := []testCase{ 1157 { 1158 module: "sdklib_no_group", 1159 distDir: "apistubs/unknown/public", 1160 distStem: "sdklib_no_group.jar", 1161 }, 1162 { 1163 module: "sdklib_group_foo", 1164 distDir: "apistubs/foo/public", 1165 distStem: "sdklib_group_foo.jar", 1166 }, 1167 { 1168 // Owner doesn't affect distDir after b/186723288. 1169 module: "sdklib_owner_foo", 1170 distDir: "apistubs/unknown/public", 1171 distStem: "sdklib_owner_foo.jar", 1172 }, 1173 { 1174 module: "sdklib_stem_foo", 1175 distDir: "apistubs/unknown/public", 1176 distStem: "foo.jar", 1177 }, 1178 } 1179 1180 for _, tt := range testCases { 1181 t.Run(tt.module, func(t *testing.T) { 1182 m := result.ModuleForTests(apiScopePublic.exportableStubsLibraryModuleName(tt.module), "android_common").Module().(*Library) 1183 dists := m.Dists() 1184 if len(dists) != 1 { 1185 t.Fatalf("expected exactly 1 dist entry, got %d", len(dists)) 1186 } 1187 if g, w := String(dists[0].Dir), tt.distDir; g != w { 1188 t.Errorf("expected dist dir %q, got %q", w, g) 1189 } 1190 if g, w := String(dists[0].Dest), tt.distStem; g != w { 1191 t.Errorf("expected dist stem %q, got %q", w, g) 1192 } 1193 }) 1194 } 1195} 1196 1197func TestSdkLibrary_CheckMinSdkVersion(t *testing.T) { 1198 preparer := android.GroupFixturePreparers( 1199 PrepareForTestWithJavaBuildComponents, 1200 PrepareForTestWithJavaDefaultModules, 1201 PrepareForTestWithJavaSdkLibraryFiles, 1202 ) 1203 1204 preparer.RunTestWithBp(t, ` 1205 java_sdk_library { 1206 name: "sdklib", 1207 srcs: ["a.java"], 1208 static_libs: ["util"], 1209 min_sdk_version: "30", 1210 unsafe_ignore_missing_latest_api: true, 1211 } 1212 1213 java_library { 1214 name: "util", 1215 srcs: ["a.java"], 1216 min_sdk_version: "30", 1217 } 1218 `) 1219 1220 preparer. 1221 RunTestWithBp(t, ` 1222 java_sdk_library { 1223 name: "sdklib", 1224 srcs: ["a.java"], 1225 libs: ["util"], 1226 impl_only_libs: ["util"], 1227 stub_only_libs: ["util"], 1228 stub_only_static_libs: ["util"], 1229 min_sdk_version: "30", 1230 unsafe_ignore_missing_latest_api: true, 1231 } 1232 1233 java_library { 1234 name: "util", 1235 srcs: ["a.java"], 1236 } 1237 `) 1238 1239 preparer.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "util".*should support min_sdk_version\(30\)`)). 1240 RunTestWithBp(t, ` 1241 java_sdk_library { 1242 name: "sdklib", 1243 srcs: ["a.java"], 1244 static_libs: ["util"], 1245 min_sdk_version: "30", 1246 unsafe_ignore_missing_latest_api: true, 1247 } 1248 1249 java_library { 1250 name: "util", 1251 srcs: ["a.java"], 1252 min_sdk_version: "31", 1253 } 1254 `) 1255 1256 preparer.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "another_util".*should support min_sdk_version\(30\)`)). 1257 RunTestWithBp(t, ` 1258 java_sdk_library { 1259 name: "sdklib", 1260 srcs: ["a.java"], 1261 static_libs: ["util"], 1262 min_sdk_version: "30", 1263 unsafe_ignore_missing_latest_api: true, 1264 } 1265 1266 java_library { 1267 name: "util", 1268 srcs: ["a.java"], 1269 static_libs: ["another_util"], 1270 min_sdk_version: "30", 1271 } 1272 1273 java_library { 1274 name: "another_util", 1275 srcs: ["a.java"], 1276 min_sdk_version: "31", 1277 } 1278 `) 1279} 1280 1281func TestJavaSdkLibrary_StubOnlyLibs_PassedToDroidstubs(t *testing.T) { 1282 result := android.GroupFixturePreparers( 1283 prepareForJavaTest, 1284 PrepareForTestWithJavaSdkLibraryFiles, 1285 FixtureWithLastReleaseApis("foo"), 1286 ).RunTestWithBp(t, ` 1287 java_sdk_library { 1288 name: "foo", 1289 srcs: ["a.java"], 1290 public: { 1291 enabled: true, 1292 }, 1293 stub_only_libs: ["bar-lib"], 1294 } 1295 1296 java_library { 1297 name: "bar-lib", 1298 srcs: ["b.java"], 1299 } 1300 `) 1301 1302 // The foo.stubs.source should depend on bar-lib 1303 fooStubsSources := result.ModuleForTests("foo.stubs.source", "android_common").Module().(*Droidstubs) 1304 eval := fooStubsSources.ConfigurableEvaluator(android.PanickingConfigAndErrorContext(result.TestContext)) 1305 android.AssertStringListContains(t, "foo stubs should depend on bar-lib", fooStubsSources.Javadoc.properties.Libs.GetOrDefault(eval, nil), "bar-lib") 1306} 1307 1308func TestJavaSdkLibrary_Scope_Libs_PassedToDroidstubs(t *testing.T) { 1309 result := android.GroupFixturePreparers( 1310 prepareForJavaTest, 1311 PrepareForTestWithJavaSdkLibraryFiles, 1312 FixtureWithLastReleaseApis("foo"), 1313 ).RunTestWithBp(t, ` 1314 java_sdk_library { 1315 name: "foo", 1316 srcs: ["a.java"], 1317 public: { 1318 enabled: true, 1319 libs: ["bar-lib"], 1320 }, 1321 } 1322 1323 java_library { 1324 name: "bar-lib", 1325 srcs: ["b.java"], 1326 } 1327 `) 1328 1329 // The foo.stubs.source should depend on bar-lib 1330 fooStubsSources := result.ModuleForTests("foo.stubs.source", "android_common").Module().(*Droidstubs) 1331 eval := fooStubsSources.ConfigurableEvaluator(android.PanickingConfigAndErrorContext(result.TestContext)) 1332 android.AssertStringListContains(t, "foo stubs should depend on bar-lib", fooStubsSources.Javadoc.properties.Libs.GetOrDefault(eval, nil), "bar-lib") 1333} 1334 1335func TestJavaSdkLibrary_ApiLibrary(t *testing.T) { 1336 result := android.GroupFixturePreparers( 1337 prepareForJavaTest, 1338 PrepareForTestWithJavaSdkLibraryFiles, 1339 FixtureWithLastReleaseApis("foo"), 1340 ).RunTestWithBp(t, ` 1341 java_sdk_library { 1342 name: "foo", 1343 srcs: ["a.java", "b.java"], 1344 api_packages: ["foo"], 1345 system: { 1346 enabled: true, 1347 }, 1348 module_lib: { 1349 enabled: true, 1350 }, 1351 test: { 1352 enabled: true, 1353 }, 1354 } 1355 `) 1356 1357 testCases := []struct { 1358 scope *apiScope 1359 apiContributions []string 1360 }{ 1361 { 1362 scope: apiScopePublic, 1363 apiContributions: []string{"foo.stubs.source.api.contribution"}, 1364 }, 1365 { 1366 scope: apiScopeSystem, 1367 apiContributions: []string{"foo.stubs.source.system.api.contribution", "foo.stubs.source.api.contribution"}, 1368 }, 1369 { 1370 scope: apiScopeTest, 1371 apiContributions: []string{"foo.stubs.source.test.api.contribution", "foo.stubs.source.system.api.contribution", "foo.stubs.source.api.contribution"}, 1372 }, 1373 { 1374 scope: apiScopeModuleLib, 1375 apiContributions: []string{"foo.stubs.source.module_lib.api.contribution", "foo.stubs.source.system.api.contribution", "foo.stubs.source.api.contribution"}, 1376 }, 1377 } 1378 1379 for _, c := range testCases { 1380 m := result.ModuleForTests(c.scope.apiLibraryModuleName("foo"), "android_common").Module().(*ApiLibrary) 1381 android.AssertArrayString(t, "Module expected to contain api contributions", c.apiContributions, m.properties.Api_contributions) 1382 } 1383} 1384 1385func TestStaticDepStubLibrariesVisibility(t *testing.T) { 1386 android.GroupFixturePreparers( 1387 prepareForJavaTest, 1388 PrepareForTestWithJavaSdkLibraryFiles, 1389 FixtureWithLastReleaseApis("foo"), 1390 android.FixtureMergeMockFs( 1391 map[string][]byte{ 1392 "A.java": nil, 1393 "dir/Android.bp": []byte( 1394 ` 1395 java_library { 1396 name: "bar", 1397 srcs: ["A.java"], 1398 libs: ["foo.stubs.from-source"], 1399 } 1400 `), 1401 "dir/A.java": nil, 1402 }, 1403 ).ExtendWithErrorHandler( 1404 android.FixtureExpectsAtLeastOneErrorMatchingPattern( 1405 `module "bar" variant "android_common": depends on //.:foo.stubs.from-source which is not visible to this module`)), 1406 ).RunTestWithBp(t, ` 1407 java_sdk_library { 1408 name: "foo", 1409 srcs: ["A.java"], 1410 } 1411 `) 1412} 1413 1414func TestSdkLibraryDependency(t *testing.T) { 1415 result := android.GroupFixturePreparers( 1416 prepareForJavaTest, 1417 PrepareForTestWithJavaSdkLibraryFiles, 1418 FixtureWithPrebuiltApis(map[string][]string{ 1419 "30": {"bar", "foo"}, 1420 }), 1421 ).RunTestWithBp(t, 1422 ` 1423 java_sdk_library { 1424 name: "foo", 1425 srcs: ["a.java", "b.java"], 1426 api_packages: ["foo"], 1427 } 1428 1429 java_sdk_library { 1430 name: "bar", 1431 srcs: ["c.java", "b.java"], 1432 libs: [ 1433 "foo.stubs", 1434 ], 1435 uses_libs: [ 1436 "foo", 1437 ], 1438 } 1439`) 1440 1441 barPermissions := result.ModuleForTests("bar.xml", "android_common").Output("bar.xml") 1442 barContents := android.ContentFromFileRuleForTests(t, result.TestContext, barPermissions) 1443 android.AssertStringDoesContain(t, "bar.xml java_sdk_xml command", barContents, `dependency="foo"`) 1444} 1445 1446func TestSdkLibraryExportableStubsLibrary(t *testing.T) { 1447 result := android.GroupFixturePreparers( 1448 prepareForJavaTest, 1449 PrepareForTestWithJavaSdkLibraryFiles, 1450 FixtureWithLastReleaseApis("foo"), 1451 ).RunTestWithBp(t, ` 1452 aconfig_declarations { 1453 name: "bar", 1454 package: "com.example.package", 1455 container: "com.android.foo", 1456 srcs: [ 1457 "bar.aconfig", 1458 ], 1459 } 1460 java_sdk_library { 1461 name: "foo", 1462 srcs: ["a.java", "b.java"], 1463 api_packages: ["foo"], 1464 system: { 1465 enabled: true, 1466 }, 1467 module_lib: { 1468 enabled: true, 1469 }, 1470 test: { 1471 enabled: true, 1472 }, 1473 aconfig_declarations: [ 1474 "bar", 1475 ], 1476 } 1477 `) 1478 1479 exportableStubsLibraryModuleName := apiScopePublic.exportableStubsLibraryModuleName("foo") 1480 exportableSourceStubsLibraryModuleName := apiScopePublic.exportableSourceStubsLibraryModuleName("foo") 1481 1482 // Check modules generation 1483 result.ModuleForTests(exportableStubsLibraryModuleName, "android_common") 1484 result.ModuleForTests(exportableSourceStubsLibraryModuleName, "android_common") 1485 1486 // Check static lib dependency 1487 android.AssertBoolEquals(t, "exportable top level stubs library module depends on the"+ 1488 "exportable source stubs library module", true, 1489 CheckModuleHasDependencyWithTag(t, result.TestContext, exportableStubsLibraryModuleName, 1490 "android_common", staticLibTag, exportableSourceStubsLibraryModuleName), 1491 ) 1492} 1493 1494// For java libraries depending on java_sdk_library(_import) via libs, assert that 1495// rdep gets stubs of source if source is listed in apex_contributions and prebuilt has prefer (legacy mechanism) 1496func TestStubResolutionOfJavaSdkLibraryInLibs(t *testing.T) { 1497 bp := ` 1498 apex_contributions { 1499 name: "my_mainline_module_contributions", 1500 api_domain: "my_mainline_module", 1501 contents: ["sdklib"], // source is selected using apex_contributions, but prebuilt is selected using prefer 1502 } 1503 java_sdk_library { 1504 name: "sdklib", 1505 srcs: ["a.java"], 1506 sdk_version: "none", 1507 system_modules: "none", 1508 public: { 1509 enabled: true, 1510 }, 1511 } 1512 java_sdk_library_import { 1513 name: "sdklib", 1514 public: { 1515 jars: ["a.jar"], 1516 stub_srcs: ["a.java"], 1517 current_api: "current.txt", 1518 removed_api: "removed.txt", 1519 annotations: "annotations.zip", 1520 }, 1521 prefer: true, // Set prefer explicitly on the prebuilt. We will assert that rdep gets source in a test case. 1522 } 1523 // rdeps 1524 java_library { 1525 name: "mymodule", 1526 srcs: ["a.java"], 1527 sdk_version: "current", 1528 libs: ["sdklib.stubs",], // this should be dynamically resolved to sdklib.stubs (source) or prebuilt_sdklib.stubs (prebuilt) 1529 } 1530 ` 1531 1532 fixture := android.GroupFixturePreparers( 1533 prepareForJavaTest, 1534 PrepareForTestWithJavaSdkLibraryFiles, 1535 FixtureWithLastReleaseApis("sdklib"), 1536 // We can use any of the apex contribution build flags from build/soong/android/config.go#mainlineApexContributionBuildFlags here 1537 android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ADSERVICES", "my_mainline_module_contributions"), 1538 ) 1539 1540 result := fixture.RunTestWithBp(t, bp) 1541 // Make sure that rdeps get the correct source vs prebuilt based on mainline_module_contributions 1542 public := result.ModuleForTests("mymodule", "android_common") 1543 rule := public.Output("javac/mymodule.jar") 1544 inputs := rule.Implicits.Strings() 1545 android.AssertStringListContains(t, "Could not find the expected stub on classpath", inputs, "out/soong/.intermediates/sdklib.stubs/android_common/turbine-combined/sdklib.stubs.jar") 1546} 1547 1548// test that rdep gets resolved to the correct version of a java_sdk_library (source or a specific prebuilt) 1549func TestMultipleSdkLibraryPrebuilts(t *testing.T) { 1550 bp := ` 1551 apex_contributions { 1552 name: "my_mainline_module_contributions", 1553 api_domain: "my_mainline_module", 1554 contents: ["%s"], 1555 } 1556 java_sdk_library { 1557 name: "sdklib", 1558 srcs: ["a.java"], 1559 sdk_version: "none", 1560 system_modules: "none", 1561 public: { 1562 enabled: true, 1563 }, 1564 } 1565 java_sdk_library_import { 1566 name: "sdklib.v1", //prebuilt 1567 source_module_name: "sdklib", 1568 public: { 1569 jars: ["a.jar"], 1570 stub_srcs: ["a.java"], 1571 current_api: "current.txt", 1572 removed_api: "removed.txt", 1573 annotations: "annotations.zip", 1574 }, 1575 } 1576 java_sdk_library_import { 1577 name: "sdklib.v2", //prebuilt 1578 source_module_name: "sdklib", 1579 public: { 1580 jars: ["a.jar"], 1581 stub_srcs: ["a.java"], 1582 current_api: "current.txt", 1583 removed_api: "removed.txt", 1584 annotations: "annotations.zip", 1585 }, 1586 } 1587 // rdeps 1588 java_library { 1589 name: "mymodule", 1590 srcs: ["a.java"], 1591 libs: ["sdklib.stubs",], 1592 } 1593 ` 1594 testCases := []struct { 1595 desc string 1596 selectedDependencyName string 1597 expectedStubPath string 1598 }{ 1599 { 1600 desc: "Source library is selected using apex_contributions", 1601 selectedDependencyName: "sdklib", 1602 expectedStubPath: "out/soong/.intermediates/sdklib.stubs/android_common/turbine-combined/sdklib.stubs.jar", 1603 }, 1604 { 1605 desc: "Prebuilt library v1 is selected using apex_contributions", 1606 selectedDependencyName: "prebuilt_sdklib.v1", 1607 expectedStubPath: "out/soong/.intermediates/prebuilt_sdklib.v1.stubs/android_common/combined/sdklib.stubs.jar", 1608 }, 1609 { 1610 desc: "Prebuilt library v2 is selected using apex_contributions", 1611 selectedDependencyName: "prebuilt_sdklib.v2", 1612 expectedStubPath: "out/soong/.intermediates/prebuilt_sdklib.v2.stubs/android_common/combined/sdklib.stubs.jar", 1613 }, 1614 } 1615 1616 fixture := android.GroupFixturePreparers( 1617 prepareForJavaTest, 1618 PrepareForTestWithJavaSdkLibraryFiles, 1619 FixtureWithLastReleaseApis("sdklib", "sdklib.v1", "sdklib.v2"), 1620 android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ADSERVICES", "my_mainline_module_contributions"), 1621 ) 1622 1623 for _, tc := range testCases { 1624 result := fixture.RunTestWithBp(t, fmt.Sprintf(bp, tc.selectedDependencyName)) 1625 1626 // Make sure that rdeps get the correct source vs prebuilt based on mainline_module_contributions 1627 public := result.ModuleForTests("mymodule", "android_common") 1628 rule := public.Output("javac/mymodule.jar") 1629 inputs := rule.Implicits.Strings() 1630 android.AssertStringListContains(t, "Could not find the expected stub on classpath", inputs, tc.expectedStubPath) 1631 } 1632} 1633 1634func TestStubLinkType(t *testing.T) { 1635 android.GroupFixturePreparers( 1636 prepareForJavaTest, 1637 PrepareForTestWithJavaSdkLibraryFiles, 1638 FixtureWithLastReleaseApis("foo"), 1639 ).ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern( 1640 `module "baz" variant "android_common": compiles against system API, but dependency `+ 1641 `"bar.stubs.system" is compiling against module API. In order to fix this, `+ 1642 `consider adjusting sdk_version: OR platform_apis: property of the source or `+ 1643 `target module so that target module is built with the same or smaller API set `+ 1644 `when compared to the source.`), 1645 ).RunTestWithBp(t, ` 1646 java_sdk_library { 1647 name: "foo", 1648 srcs: ["a.java"], 1649 sdk_version: "current", 1650 } 1651 java_library { 1652 name: "bar.stubs.system", 1653 srcs: ["a.java"], 1654 sdk_version: "module_current", 1655 is_stubs_module: false, 1656 } 1657 1658 java_library { 1659 name: "baz", 1660 srcs: ["b.java"], 1661 libs: [ 1662 "foo.stubs.system", 1663 "bar.stubs.system", 1664 ], 1665 sdk_version: "system_current", 1666 } 1667 `) 1668} 1669 1670func TestSdkLibDirectDependency(t *testing.T) { 1671 android.GroupFixturePreparers( 1672 prepareForJavaTest, 1673 PrepareForTestWithJavaSdkLibraryFiles, 1674 FixtureWithLastReleaseApis("foo", "bar"), 1675 ).ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern([]string{ 1676 `module "baz" variant "android_common": cannot depend directly on java_sdk_library ` + 1677 `"foo"; try depending on "foo.stubs", or "foo.impl" instead`, 1678 `module "baz" variant "android_common": cannot depend directly on java_sdk_library ` + 1679 `"prebuilt_bar"; try depending on "bar.stubs", or "bar.impl" instead`, 1680 }), 1681 ).RunTestWithBp(t, ` 1682 java_sdk_library { 1683 name: "foo", 1684 srcs: ["a.java"], 1685 sdk_version: "current", 1686 public: { 1687 enabled: true, 1688 }, 1689 } 1690 1691 java_sdk_library_import { 1692 name: "foo", 1693 public: { 1694 jars: ["a.jar"], 1695 stub_srcs: ["a.java"], 1696 current_api: "current.txt", 1697 removed_api: "removed.txt", 1698 annotations: "annotations.zip", 1699 }, 1700 } 1701 1702 java_sdk_library { 1703 name: "bar", 1704 srcs: ["a.java"], 1705 sdk_version: "current", 1706 public: { 1707 enabled: true, 1708 }, 1709 } 1710 1711 java_sdk_library_import { 1712 name: "bar", 1713 prefer: true, 1714 public: { 1715 jars: ["a.jar"], 1716 stub_srcs: ["a.java"], 1717 current_api: "current.txt", 1718 removed_api: "removed.txt", 1719 annotations: "annotations.zip", 1720 }, 1721 } 1722 1723 java_library { 1724 name: "baz", 1725 srcs: ["b.java"], 1726 libs: [ 1727 "foo", 1728 "bar", 1729 ], 1730 } 1731 `) 1732} 1733 1734func TestSdkLibDirectDependencyWithPrebuiltSdk(t *testing.T) { 1735 android.GroupFixturePreparers( 1736 prepareForJavaTest, 1737 PrepareForTestWithJavaSdkLibraryFiles, 1738 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1739 variables.Platform_sdk_version = intPtr(34) 1740 variables.Platform_sdk_codename = stringPtr("VanillaIceCream") 1741 variables.Platform_version_active_codenames = []string{"VanillaIceCream"} 1742 variables.Platform_systemsdk_versions = []string{"33", "34", "VanillaIceCream"} 1743 variables.DeviceSystemSdkVersions = []string{"VanillaIceCream"} 1744 }), 1745 FixtureWithPrebuiltApis(map[string][]string{ 1746 "33": {"foo"}, 1747 "34": {"foo"}, 1748 "35": {"foo"}, 1749 }), 1750 ).ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern( 1751 `module "baz" variant "android_common": cannot depend directly on java_sdk_library "foo"; `+ 1752 `try depending on "sdk_public_33_foo", "sdk_system_33_foo", "sdk_test_33_foo", `+ 1753 `"sdk_module-lib_33_foo", or "sdk_system-server_33_foo" instead`), 1754 ).RunTestWithBp(t, ` 1755 java_sdk_library { 1756 name: "foo", 1757 srcs: ["a.java"], 1758 sdk_version: "current", 1759 public: { 1760 enabled: true, 1761 }, 1762 system: { 1763 enabled: true, 1764 }, 1765 } 1766 1767 java_library { 1768 name: "baz", 1769 srcs: ["b.java"], 1770 libs: [ 1771 "foo", 1772 ], 1773 sdk_version: "system_33", 1774 } 1775 `) 1776} 1777