1// Copyright 2017 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 "reflect" 21 "sort" 22 "strings" 23 "testing" 24 25 "github.com/google/blueprint/proptools" 26 27 "android/soong/android" 28 "android/soong/cc" 29 "android/soong/dexpreopt" 30) 31 32// testApp runs tests using the prepareForJavaTest 33// 34// See testJava for an explanation as to how to stop using this deprecated method. 35// 36// deprecated 37func testApp(t *testing.T, bp string) *android.TestContext { 38 t.Helper() 39 result := prepareForJavaTest.RunTestWithBp(t, bp) 40 return result.TestContext 41} 42 43func TestApp(t *testing.T) { 44 resourceFiles := []string{ 45 "res/layout/layout.xml", 46 "res/values/strings.xml", 47 "res/values-en-rUS/strings.xml", 48 } 49 50 compiledResourceFiles := []string{ 51 "aapt2/res/layout_layout.xml.flat", 52 "aapt2/res/values_strings.arsc.flat", 53 "aapt2/res/values-en-rUS_strings.arsc.flat", 54 } 55 56 for _, moduleType := range []string{"android_app", "android_library"} { 57 t.Run(moduleType, func(t *testing.T) { 58 result := android.GroupFixturePreparers( 59 prepareForJavaTest, 60 android.FixtureModifyMockFS(func(fs android.MockFS) { 61 for _, file := range resourceFiles { 62 fs[file] = nil 63 } 64 }), 65 ).RunTestWithBp(t, moduleType+` { 66 name: "foo", 67 srcs: ["a.java"], 68 sdk_version: "current" 69 } 70 `) 71 72 foo := result.ModuleForTests("foo", "android_common") 73 74 var expectedLinkImplicits []string 75 76 manifestFixer := foo.Output("manifest_fixer/AndroidManifest.xml") 77 expectedLinkImplicits = append(expectedLinkImplicits, manifestFixer.Output.String()) 78 79 frameworkRes := result.ModuleForTests("framework-res", "android_common") 80 expectedLinkImplicits = append(expectedLinkImplicits, 81 frameworkRes.Output("package-res.apk").Output.String()) 82 83 // Test the mapping from input files to compiled output file names 84 compile := foo.Output(compiledResourceFiles[0]) 85 android.AssertDeepEquals(t, "aapt2 compile inputs", resourceFiles, compile.Inputs.Strings()) 86 87 compiledResourceOutputs := compile.Outputs.Strings() 88 sort.Strings(compiledResourceOutputs) 89 90 expectedLinkImplicits = append(expectedLinkImplicits, compiledResourceOutputs...) 91 92 list := foo.Output("aapt2/res.list") 93 expectedLinkImplicits = append(expectedLinkImplicits, list.Output.String()) 94 95 // Check that the link rule uses 96 res := result.ModuleForTests("foo", "android_common").Output("package-res.apk") 97 android.AssertDeepEquals(t, "aapt2 link implicits", expectedLinkImplicits, res.Implicits.Strings()) 98 }) 99 } 100} 101 102func TestAppSplits(t *testing.T) { 103 ctx := testApp(t, ` 104 android_app { 105 name: "foo", 106 srcs: ["a.java"], 107 package_splits: ["v4", "v7,hdpi"], 108 sdk_version: "current" 109 }`) 110 111 foo := ctx.ModuleForTests("foo", "android_common") 112 113 expectedOutputs := []string{ 114 "out/soong/.intermediates/foo/android_common/foo.apk", 115 "out/soong/.intermediates/foo/android_common/foo_v4.apk", 116 "out/soong/.intermediates/foo/android_common/foo_v7_hdpi.apk", 117 } 118 for _, expectedOutput := range expectedOutputs { 119 foo.Output(expectedOutput) 120 } 121 122 outputFiles := foo.OutputFiles(ctx, t, "") 123 android.AssertPathsRelativeToTopEquals(t, `OutputFiles("")`, expectedOutputs, outputFiles) 124} 125 126func TestPlatformAPIs(t *testing.T) { 127 testJava(t, ` 128 android_app { 129 name: "foo", 130 srcs: ["a.java"], 131 platform_apis: true, 132 } 133 `) 134 135 testJava(t, ` 136 android_app { 137 name: "foo", 138 srcs: ["a.java"], 139 sdk_version: "current", 140 } 141 `) 142 143 testJavaError(t, "This module has conflicting settings. sdk_version is empty, which means that this module is build against platform APIs. However platform_apis is not set to true", ` 144 android_app { 145 name: "bar", 146 srcs: ["b.java"], 147 } 148 `) 149 150 testJavaError(t, "This module has conflicting settings. sdk_version is not empty, which means this module cannot use platform APIs. However platform_apis is set to true.", ` 151 android_app { 152 name: "bar", 153 srcs: ["b.java"], 154 sdk_version: "system_current", 155 platform_apis: true, 156 } 157 `) 158} 159 160func TestAndroidAppLinkType(t *testing.T) { 161 testJava(t, ` 162 android_app { 163 name: "foo", 164 srcs: ["a.java"], 165 libs: ["bar"], 166 static_libs: ["baz"], 167 platform_apis: true, 168 } 169 170 java_library { 171 name: "bar", 172 sdk_version: "current", 173 srcs: ["b.java"], 174 } 175 176 android_library { 177 name: "baz", 178 sdk_version: "system_current", 179 srcs: ["c.java"], 180 } 181 `) 182 183 testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", ` 184 android_app { 185 name: "foo", 186 srcs: ["a.java"], 187 libs: ["bar"], 188 sdk_version: "current", 189 static_libs: ["baz"], 190 } 191 192 java_library { 193 name: "bar", 194 sdk_version: "current", 195 srcs: ["b.java"], 196 } 197 198 android_library { 199 name: "baz", 200 sdk_version: "system_current", 201 srcs: ["c.java"], 202 } 203 `) 204 205 testJava(t, ` 206 android_app { 207 name: "foo", 208 srcs: ["a.java"], 209 libs: ["bar"], 210 sdk_version: "system_current", 211 static_libs: ["baz"], 212 } 213 214 java_library { 215 name: "bar", 216 sdk_version: "current", 217 srcs: ["b.java"], 218 } 219 220 android_library { 221 name: "baz", 222 sdk_version: "system_current", 223 srcs: ["c.java"], 224 } 225 `) 226 227 testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", ` 228 android_app { 229 name: "foo", 230 srcs: ["a.java"], 231 libs: ["bar"], 232 sdk_version: "system_current", 233 static_libs: ["baz"], 234 } 235 236 java_library { 237 name: "bar", 238 sdk_version: "current", 239 srcs: ["b.java"], 240 } 241 242 android_library { 243 name: "baz", 244 srcs: ["c.java"], 245 } 246 `) 247} 248 249func TestUpdatableApps(t *testing.T) { 250 testCases := []struct { 251 name string 252 bp string 253 expectedError string 254 }{ 255 { 256 name: "Stable public SDK", 257 bp: `android_app { 258 name: "foo", 259 srcs: ["a.java"], 260 sdk_version: "29", 261 min_sdk_version: "29", 262 updatable: true, 263 }`, 264 }, 265 { 266 name: "Stable system SDK", 267 bp: `android_app { 268 name: "foo", 269 srcs: ["a.java"], 270 sdk_version: "system_29", 271 min_sdk_version: "29", 272 updatable: true, 273 }`, 274 }, 275 { 276 name: "Current public SDK", 277 bp: `android_app { 278 name: "foo", 279 srcs: ["a.java"], 280 sdk_version: "current", 281 min_sdk_version: "29", 282 updatable: true, 283 }`, 284 }, 285 { 286 name: "Current system SDK", 287 bp: `android_app { 288 name: "foo", 289 srcs: ["a.java"], 290 sdk_version: "system_current", 291 min_sdk_version: "29", 292 updatable: true, 293 }`, 294 }, 295 { 296 name: "Current module SDK", 297 bp: `android_app { 298 name: "foo", 299 srcs: ["a.java"], 300 sdk_version: "module_current", 301 min_sdk_version: "29", 302 updatable: true, 303 }`, 304 }, 305 { 306 name: "Current core SDK", 307 bp: `android_app { 308 name: "foo", 309 srcs: ["a.java"], 310 sdk_version: "core_current", 311 min_sdk_version: "29", 312 updatable: true, 313 }`, 314 }, 315 { 316 name: "No Platform APIs", 317 bp: `android_app { 318 name: "foo", 319 srcs: ["a.java"], 320 platform_apis: true, 321 min_sdk_version: "29", 322 updatable: true, 323 }`, 324 expectedError: "Updatable apps must use stable SDKs", 325 }, 326 { 327 name: "No Core Platform APIs", 328 bp: `android_app { 329 name: "foo", 330 srcs: ["a.java"], 331 sdk_version: "core_platform", 332 min_sdk_version: "29", 333 updatable: true, 334 }`, 335 expectedError: "Updatable apps must use stable SDKs", 336 }, 337 { 338 name: "No unspecified APIs", 339 bp: `android_app { 340 name: "foo", 341 srcs: ["a.java"], 342 updatable: true, 343 min_sdk_version: "29", 344 }`, 345 expectedError: "Updatable apps must use stable SDK", 346 }, 347 { 348 name: "Must specify min_sdk_version", 349 bp: `android_app { 350 name: "app_without_min_sdk_version", 351 srcs: ["a.java"], 352 sdk_version: "29", 353 updatable: true, 354 }`, 355 expectedError: "updatable apps must set min_sdk_version.", 356 }, 357 } 358 359 for _, test := range testCases { 360 t.Run(test.name, func(t *testing.T) { 361 errorHandler := android.FixtureExpectsNoErrors 362 if test.expectedError != "" { 363 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(test.expectedError) 364 } 365 android.GroupFixturePreparers( 366 prepareForJavaTest, FixtureWithPrebuiltApis(map[string][]string{ 367 "29": {"foo"}, 368 })). 369 ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, test.bp) 370 }) 371 } 372} 373 374func TestUpdatableApps_TransitiveDepsShouldSetMinSdkVersion(t *testing.T) { 375 testJavaError(t, `module "bar".*: should support min_sdk_version\(29\)`, cc.GatherRequiredDepsForTest(android.Android)+` 376 android_app { 377 name: "foo", 378 srcs: ["a.java"], 379 updatable: true, 380 sdk_version: "current", 381 min_sdk_version: "29", 382 static_libs: ["bar"], 383 } 384 385 java_library { 386 name: "bar", 387 sdk_version: "current", 388 } 389 `) 390} 391 392func TestUpdatableApps_JniLibsShouldShouldSupportMinSdkVersion(t *testing.T) { 393 testJava(t, cc.GatherRequiredDepsForTest(android.Android)+` 394 android_app { 395 name: "foo", 396 srcs: ["a.java"], 397 updatable: true, 398 sdk_version: "current", 399 min_sdk_version: "current", 400 jni_libs: ["libjni"], 401 } 402 403 cc_library { 404 name: "libjni", 405 stl: "none", 406 system_shared_libs: [], 407 sdk_version: "current", 408 } 409 `) 410} 411 412func TestUpdatableApps_JniLibShouldBeBuiltAgainstMinSdkVersion(t *testing.T) { 413 bp := cc.GatherRequiredDepsForTest(android.Android) + ` 414 android_app { 415 name: "foo", 416 srcs: ["a.java"], 417 updatable: true, 418 sdk_version: "current", 419 min_sdk_version: "29", 420 jni_libs: ["libjni"], 421 } 422 423 cc_library { 424 name: "libjni", 425 stl: "none", 426 system_shared_libs: [], 427 sdk_version: "current", 428 min_sdk_version: "29", 429 } 430 ` 431 fs := map[string][]byte{ 432 "prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtbegin_so.o": nil, 433 "prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtend_so.o": nil, 434 "prebuilts/ndk/current/platforms/android-29/arch-arm/usr/lib/crtbegin_so.o": nil, 435 "prebuilts/ndk/current/platforms/android-29/arch-arm/usr/lib/crtend_so.o": nil, 436 } 437 438 ctx, _ := testJavaWithFS(t, bp, fs) 439 440 inputs := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared").Description("link").Implicits 441 var crtbeginFound, crtendFound bool 442 expectedCrtBegin := ctx.ModuleForTests("crtbegin_so", 443 "android_arm64_armv8-a_sdk_29").Rule("noAddrSig").Output 444 expectedCrtEnd := ctx.ModuleForTests("crtend_so", 445 "android_arm64_armv8-a_sdk_29").Rule("noAddrSig").Output 446 implicits := []string{} 447 for _, input := range inputs { 448 implicits = append(implicits, input.String()) 449 if strings.HasSuffix(input.String(), expectedCrtBegin.String()) { 450 crtbeginFound = true 451 } else if strings.HasSuffix(input.String(), expectedCrtEnd.String()) { 452 crtendFound = true 453 } 454 } 455 if !crtbeginFound { 456 t.Error(fmt.Sprintf( 457 "expected implicit with suffix %q, have the following implicits:\n%s", 458 expectedCrtBegin, strings.Join(implicits, "\n"))) 459 } 460 if !crtendFound { 461 t.Error(fmt.Sprintf( 462 "expected implicit with suffix %q, have the following implicits:\n%s", 463 expectedCrtEnd, strings.Join(implicits, "\n"))) 464 } 465} 466 467func TestUpdatableApps_ErrorIfJniLibDoesntSupportMinSdkVersion(t *testing.T) { 468 bp := cc.GatherRequiredDepsForTest(android.Android) + ` 469 android_app { 470 name: "foo", 471 srcs: ["a.java"], 472 updatable: true, 473 sdk_version: "current", 474 min_sdk_version: "29", // this APK should support 29 475 jni_libs: ["libjni"], 476 } 477 478 cc_library { 479 name: "libjni", 480 stl: "none", 481 sdk_version: "current", 482 min_sdk_version: "current", 483 } 484 ` 485 testJavaError(t, `"libjni" .*: min_sdk_version\(current\) is higher than min_sdk_version\(29\)`, bp) 486} 487 488func TestUpdatableApps_ErrorIfDepMinSdkVersionIsHigher(t *testing.T) { 489 bp := cc.GatherRequiredDepsForTest(android.Android) + ` 490 android_app { 491 name: "foo", 492 srcs: ["a.java"], 493 updatable: true, 494 sdk_version: "current", 495 min_sdk_version: "29", // this APK should support 29 496 jni_libs: ["libjni"], 497 } 498 499 cc_library { 500 name: "libjni", 501 stl: "none", 502 shared_libs: ["libbar"], 503 system_shared_libs: [], 504 sdk_version: "27", 505 min_sdk_version: "27", 506 } 507 508 cc_library { 509 name: "libbar", 510 stl: "none", 511 system_shared_libs: [], 512 sdk_version: "current", 513 min_sdk_version: "current", 514 } 515 ` 516 testJavaError(t, `"libjni" .*: links "libbar" built against newer API version "current"`, bp) 517} 518 519func TestUpdatableApps_ApplyDefaultUpdatableModuleVersion(t *testing.T) { 520 result := android.GroupFixturePreparers( 521 PrepareForTestWithJavaDefaultModules, 522 ).RunTestWithBp(t, ` 523 android_app { 524 name: "com.android.foo", 525 srcs: ["a.java"], 526 sdk_version: "current", 527 min_sdk_version: "31", 528 updatable: true, 529 } 530 `) 531 foo := result.ModuleForTests("com.android.foo", "android_common").Rule("manifestFixer") 532 android.AssertStringDoesContain(t, 533 "com.android.foo: expected manifest fixer to set override-placeholder-version to RELEASE_DEFAULT_UPDATABLE_MODULE_VERSION", 534 foo.BuildParams.Args["args"], 535 fmt.Sprintf("--override-placeholder-version %s", testDefaultUpdatableModuleVersion), 536 ) 537} 538 539func TestUpdatableApps_ApplyOverrideApexManifestDefaultVersion(t *testing.T) { 540 result := android.GroupFixturePreparers( 541 PrepareForTestWithJavaDefaultModules, 542 android.FixtureMergeEnv(map[string]string{ 543 "OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION": "1234", 544 }), 545 ).RunTestWithBp(t, ` 546 android_app { 547 name: "com.android.foo", 548 srcs: ["a.java"], 549 sdk_version: "current", 550 min_sdk_version: "31", 551 updatable: true, 552 } 553 `) 554 foo := result.ModuleForTests("com.android.foo", "android_common").Rule("manifestFixer") 555 android.AssertStringDoesContain(t, 556 "com.android.foo: expected manifest fixer to set override-placeholder-version to 1234", 557 foo.BuildParams.Args["args"], 558 "--override-placeholder-version 1234", 559 ) 560} 561 562func TestResourceDirs(t *testing.T) { 563 testCases := []struct { 564 name string 565 prop string 566 resources []string 567 }{ 568 { 569 name: "no resource_dirs", 570 prop: "", 571 resources: []string{"res/res/values/strings.xml"}, 572 }, 573 { 574 name: "resource_dirs", 575 prop: `resource_dirs: ["res"]`, 576 resources: []string{"res/res/values/strings.xml"}, 577 }, 578 { 579 name: "empty resource_dirs", 580 prop: `resource_dirs: []`, 581 resources: nil, 582 }, 583 } 584 585 fs := android.MockFS{ 586 "res/res/values/strings.xml": nil, 587 } 588 589 bp := ` 590 android_app { 591 name: "foo", 592 sdk_version: "current", 593 %s 594 } 595 ` 596 597 for _, testCase := range testCases { 598 t.Run(testCase.name, func(t *testing.T) { 599 result := android.GroupFixturePreparers( 600 PrepareForTestWithJavaDefaultModules, 601 fs.AddToFixture(), 602 ).RunTestWithBp(t, fmt.Sprintf(bp, testCase.prop)) 603 604 module := result.ModuleForTests("foo", "android_common") 605 resourceList := module.MaybeOutput("aapt2/res.list") 606 607 var resources []string 608 if resourceList.Rule != nil { 609 for _, compiledResource := range resourceList.Inputs.Strings() { 610 resources = append(resources, module.Output(compiledResource).Inputs.Strings()...) 611 } 612 } 613 614 android.AssertDeepEquals(t, "resource files", testCase.resources, resources) 615 }) 616 } 617} 618 619func TestLibraryAssets(t *testing.T) { 620 bp := ` 621 android_app { 622 name: "foo", 623 sdk_version: "current", 624 static_libs: ["lib1", "lib2", "lib3"], 625 } 626 627 android_library { 628 name: "lib1", 629 sdk_version: "current", 630 asset_dirs: ["assets_a"], 631 } 632 633 android_library { 634 name: "lib2", 635 sdk_version: "current", 636 } 637 638 android_library { 639 name: "lib3", 640 sdk_version: "current", 641 static_libs: ["lib4", "import"], 642 } 643 644 android_library { 645 name: "lib4", 646 sdk_version: "current", 647 asset_dirs: ["assets_b"], 648 } 649 650 android_library { 651 name: "lib5", 652 sdk_version: "current", 653 assets: [ 654 "path/to/asset_file_1", 655 "path/to/asset_file_2", 656 ], 657 } 658 659 android_library_import { 660 name: "import", 661 sdk_version: "current", 662 aars: ["import.aar"], 663 } 664 ` 665 666 testCases := []struct { 667 name string 668 assetFlag string 669 assetPackages []string 670 tmpAssetDirInputs []string 671 tmpAssetDirOutputs []string 672 }{ 673 { 674 name: "foo", 675 // lib1 has its own assets. lib3 doesn't have any, but lib4 and import have assets. 676 assetPackages: []string{ 677 "out/soong/.intermediates/foo/android_common/aapt2/package-res.apk", 678 "out/soong/.intermediates/lib1/android_common/assets.zip", 679 "out/soong/.intermediates/lib4/android_common/assets.zip", 680 "out/soong/.intermediates/import/android_common/assets.zip", 681 }, 682 }, 683 { 684 name: "lib1", 685 assetFlag: "-A assets_a", 686 }, 687 { 688 name: "lib2", 689 }, 690 { 691 name: "lib3", 692 }, 693 { 694 name: "lib4", 695 assetFlag: "-A assets_b", 696 }, 697 { 698 name: "lib5", 699 assetFlag: "-A out/soong/.intermediates/lib5/android_common/tmp_asset_dir", 700 tmpAssetDirInputs: []string{ 701 "path/to/asset_file_1", 702 "path/to/asset_file_2", 703 }, 704 tmpAssetDirOutputs: []string{ 705 "out/soong/.intermediates/lib5/android_common/tmp_asset_dir/path/to/asset_file_1", 706 "out/soong/.intermediates/lib5/android_common/tmp_asset_dir/path/to/asset_file_2", 707 }, 708 }, 709 } 710 ctx := testApp(t, bp) 711 712 for _, test := range testCases { 713 t.Run(test.name, func(t *testing.T) { 714 m := ctx.ModuleForTests(test.name, "android_common") 715 716 // Check asset flag in aapt2 link flags 717 var aapt2link android.TestingBuildParams 718 if len(test.assetPackages) > 0 { 719 aapt2link = m.Output("aapt2/package-res.apk") 720 } else { 721 aapt2link = m.Output("package-res.apk") 722 } 723 aapt2link = aapt2link 724 aapt2Flags := aapt2link.Args["flags"] 725 if test.assetFlag != "" { 726 android.AssertStringDoesContain(t, "asset flag", aapt2Flags, test.assetFlag) 727 } else { 728 android.AssertStringDoesNotContain(t, "aapt2 link flags", aapt2Flags, " -A ") 729 } 730 731 // Check asset merge rule. 732 if len(test.assetPackages) > 0 { 733 mergeAssets := m.Output("package-res.apk") 734 android.AssertPathsRelativeToTopEquals(t, "mergeAssets inputs", test.assetPackages, mergeAssets.Inputs) 735 } 736 737 if len(test.tmpAssetDirInputs) > 0 { 738 rule := m.Rule("tmp_asset_dir") 739 inputs := rule.Implicits 740 outputs := append(android.WritablePaths{rule.Output}, rule.ImplicitOutputs...).Paths() 741 android.AssertPathsRelativeToTopEquals(t, "tmp_asset_dir inputs", test.tmpAssetDirInputs, inputs) 742 android.AssertPathsRelativeToTopEquals(t, "tmp_asset_dir outputs", test.tmpAssetDirOutputs, outputs) 743 } 744 }) 745 } 746} 747 748func TestAppJavaResources(t *testing.T) { 749 bp := ` 750 android_app { 751 name: "foo", 752 sdk_version: "current", 753 java_resources: ["resources/a"], 754 srcs: ["a.java"], 755 } 756 757 android_app { 758 name: "bar", 759 sdk_version: "current", 760 java_resources: ["resources/a"], 761 } 762 ` 763 764 ctx := testApp(t, bp) 765 766 foo := ctx.ModuleForTests("foo", "android_common") 767 fooResources := foo.Output("res/foo.jar") 768 fooDexJar := foo.Output("dex-withres/foo.jar") 769 fooDexJarAligned := foo.Output("dex-withres-aligned/foo.jar") 770 fooApk := foo.Rule("combineApk") 771 772 if g, w := fooDexJar.Inputs.Strings(), fooResources.Output.String(); !android.InList(w, g) { 773 t.Errorf("expected resource jar %q in foo dex jar inputs %q", w, g) 774 } 775 776 if g, w := fooDexJarAligned.Input.String(), fooDexJar.Output.String(); g != w { 777 t.Errorf("expected dex jar %q in foo aligned dex jar inputs %q", w, g) 778 } 779 780 if g, w := fooApk.Inputs.Strings(), fooDexJarAligned.Output.String(); !android.InList(w, g) { 781 t.Errorf("expected aligned dex jar %q in foo apk inputs %q", w, g) 782 } 783 784 bar := ctx.ModuleForTests("bar", "android_common") 785 barResources := bar.Output("res/bar.jar") 786 barApk := bar.Rule("combineApk") 787 788 if g, w := barApk.Inputs.Strings(), barResources.Output.String(); !android.InList(w, g) { 789 t.Errorf("expected resources jar %q in bar apk inputs %q", w, g) 790 } 791} 792 793func TestAndroidResourceProcessor(t *testing.T) { 794 testCases := []struct { 795 name string 796 appUsesRP bool 797 directLibUsesRP bool 798 transitiveLibUsesRP bool 799 sharedLibUsesRP bool 800 sharedTransitiveStaticLibUsesRP bool 801 sharedTransitiveSharedLibUsesRP bool 802 803 dontVerifyApp bool 804 appResources []string 805 appOverlays []string 806 appImports []string 807 appSrcJars []string 808 appClasspath []string 809 appCombined []string 810 811 dontVerifyDirect bool 812 directResources []string 813 directOverlays []string 814 directImports []string 815 directSrcJars []string 816 directClasspath []string 817 directCombined []string 818 819 dontVerifyTransitive bool 820 transitiveResources []string 821 transitiveOverlays []string 822 transitiveImports []string 823 transitiveSrcJars []string 824 transitiveClasspath []string 825 transitiveCombined []string 826 827 dontVerifyDirectImport bool 828 directImportResources []string 829 directImportOverlays []string 830 directImportImports []string 831 832 dontVerifyTransitiveImport bool 833 transitiveImportResources []string 834 transitiveImportOverlays []string 835 transitiveImportImports []string 836 837 dontVerifyShared bool 838 sharedResources []string 839 sharedOverlays []string 840 sharedImports []string 841 sharedSrcJars []string 842 sharedClasspath []string 843 sharedCombined []string 844 }{ 845 { 846 // Test with all modules set to use_resource_processor: false (except android_library_import modules, 847 // which always use resource processor). 848 name: "legacy", 849 appUsesRP: false, 850 directLibUsesRP: false, 851 transitiveLibUsesRP: false, 852 853 appResources: nil, 854 appOverlays: []string{ 855 "out/soong/.intermediates/transitive/android_common/package-res.apk", 856 "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk", 857 "out/soong/.intermediates/transitive_import/android_common/package-res.apk", 858 "out/soong/.intermediates/direct/android_common/package-res.apk", 859 "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk", 860 "out/soong/.intermediates/direct_import/android_common/package-res.apk", 861 "out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat", 862 }, 863 appImports: []string{ 864 "out/soong/.intermediates/shared/android_common/package-res.apk", 865 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk", 866 }, 867 appSrcJars: []string{"out/soong/.intermediates/app/android_common/gen/android/R.srcjar"}, 868 appClasspath: []string{ 869 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", 870 "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar", 871 "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar", 872 "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar", 873 }, 874 appCombined: []string{ 875 "out/soong/.intermediates/app/android_common/javac/app.jar", 876 "out/soong/.intermediates/direct/android_common/combined/direct.jar", 877 "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar", 878 }, 879 880 directResources: nil, 881 directOverlays: []string{ 882 "out/soong/.intermediates/transitive/android_common/package-res.apk", 883 "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk", 884 "out/soong/.intermediates/transitive_import/android_common/package-res.apk", 885 "out/soong/.intermediates/direct/android_common/aapt2/direct/res/values_strings.arsc.flat", 886 }, 887 directImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"}, 888 directSrcJars: []string{"out/soong/.intermediates/direct/android_common/gen/android/R.srcjar"}, 889 directClasspath: []string{ 890 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", 891 "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar", 892 "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar", 893 }, 894 directCombined: []string{ 895 "out/soong/.intermediates/direct/android_common/javac/direct.jar", 896 "out/soong/.intermediates/transitive/android_common/javac/transitive.jar", 897 "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar", 898 }, 899 900 transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"}, 901 transitiveOverlays: nil, 902 transitiveImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"}, 903 transitiveSrcJars: []string{"out/soong/.intermediates/transitive/android_common/gen/android/R.srcjar"}, 904 transitiveClasspath: []string{"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar"}, 905 transitiveCombined: nil, 906 907 sharedResources: nil, 908 sharedOverlays: []string{ 909 "out/soong/.intermediates/shared_transitive_static/android_common/package-res.apk", 910 "out/soong/.intermediates/shared/android_common/aapt2/shared/res/values_strings.arsc.flat", 911 }, 912 sharedImports: []string{ 913 "out/soong/.intermediates/shared_transitive_shared/android_common/package-res.apk", 914 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk", 915 }, 916 sharedSrcJars: []string{"out/soong/.intermediates/shared/android_common/gen/android/R.srcjar"}, 917 sharedClasspath: []string{ 918 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", 919 "out/soong/.intermediates/shared_transitive_shared/android_common/turbine-combined/shared_transitive_shared.jar", 920 "out/soong/.intermediates/shared_transitive_static/android_common/turbine-combined/shared_transitive_static.jar", 921 }, 922 sharedCombined: []string{ 923 "out/soong/.intermediates/shared/android_common/javac/shared.jar", 924 "out/soong/.intermediates/shared_transitive_static/android_common/javac/shared_transitive_static.jar", 925 }, 926 927 directImportResources: nil, 928 directImportOverlays: []string{"out/soong/.intermediates/direct_import/android_common/flat-res/gen_res.flata"}, 929 directImportImports: []string{ 930 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk", 931 "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk", 932 }, 933 934 transitiveImportResources: nil, 935 transitiveImportOverlays: []string{"out/soong/.intermediates/transitive_import/android_common/flat-res/gen_res.flata"}, 936 transitiveImportImports: []string{ 937 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk", 938 "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk", 939 }, 940 }, 941 { 942 // Test with all modules set to use_resource_processor: true. 943 name: "resource_processor", 944 appUsesRP: true, 945 directLibUsesRP: true, 946 transitiveLibUsesRP: true, 947 sharedLibUsesRP: true, 948 sharedTransitiveSharedLibUsesRP: true, 949 sharedTransitiveStaticLibUsesRP: true, 950 951 appResources: nil, 952 appOverlays: []string{ 953 "out/soong/.intermediates/transitive/android_common/package-res.apk", 954 "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk", 955 "out/soong/.intermediates/transitive_import/android_common/package-res.apk", 956 "out/soong/.intermediates/direct/android_common/package-res.apk", 957 "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk", 958 "out/soong/.intermediates/direct_import/android_common/package-res.apk", 959 "out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat", 960 }, 961 appImports: []string{ 962 "out/soong/.intermediates/shared/android_common/package-res.apk", 963 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk", 964 }, 965 appSrcJars: nil, 966 appClasspath: []string{ 967 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", 968 "out/soong/.intermediates/app/android_common/busybox/R.jar", 969 "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar", 970 "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar", 971 "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar", 972 }, 973 appCombined: []string{ 974 "out/soong/.intermediates/app/android_common/javac/app.jar", 975 "out/soong/.intermediates/app/android_common/busybox/R.jar", 976 "out/soong/.intermediates/direct/android_common/combined/direct.jar", 977 "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar", 978 }, 979 980 directResources: nil, 981 directOverlays: []string{"out/soong/.intermediates/direct/android_common/aapt2/direct/res/values_strings.arsc.flat"}, 982 directImports: []string{ 983 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk", 984 "out/soong/.intermediates/transitive_import/android_common/package-res.apk", 985 "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk", 986 "out/soong/.intermediates/transitive/android_common/package-res.apk", 987 }, 988 directSrcJars: nil, 989 directClasspath: []string{ 990 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", 991 "out/soong/.intermediates/direct/android_common/busybox/R.jar", 992 "out/soong/.intermediates/transitive/android_common/busybox/R.jar", 993 "out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar", 994 "out/soong/.intermediates/transitive_import/android_common/busybox/R.jar", 995 "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar", 996 "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar", 997 }, 998 directCombined: []string{ 999 "out/soong/.intermediates/direct/android_common/javac/direct.jar", 1000 "out/soong/.intermediates/transitive/android_common/javac/transitive.jar", 1001 "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar", 1002 }, 1003 1004 transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"}, 1005 transitiveOverlays: nil, 1006 transitiveImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"}, 1007 transitiveSrcJars: nil, 1008 transitiveClasspath: []string{ 1009 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", 1010 "out/soong/.intermediates/transitive/android_common/busybox/R.jar", 1011 }, 1012 transitiveCombined: nil, 1013 1014 sharedResources: nil, 1015 sharedOverlays: []string{"out/soong/.intermediates/shared/android_common/aapt2/shared/res/values_strings.arsc.flat"}, 1016 sharedImports: []string{ 1017 "out/soong/.intermediates/shared_transitive_shared/android_common/package-res.apk", 1018 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk", 1019 "out/soong/.intermediates/shared_transitive_static/android_common/package-res.apk", 1020 }, 1021 sharedSrcJars: nil, 1022 sharedClasspath: []string{ 1023 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", 1024 "out/soong/.intermediates/shared/android_common/busybox/R.jar", 1025 "out/soong/.intermediates/shared_transitive_static/android_common/busybox/R.jar", 1026 "out/soong/.intermediates/shared_transitive_shared/android_common/busybox/R.jar", 1027 "out/soong/.intermediates/shared_transitive_shared/android_common/turbine-combined/shared_transitive_shared.jar", 1028 "out/soong/.intermediates/shared_transitive_static/android_common/turbine-combined/shared_transitive_static.jar", 1029 }, 1030 sharedCombined: []string{ 1031 "out/soong/.intermediates/shared/android_common/javac/shared.jar", 1032 "out/soong/.intermediates/shared_transitive_static/android_common/javac/shared_transitive_static.jar", 1033 }, 1034 1035 directImportResources: nil, 1036 directImportOverlays: []string{"out/soong/.intermediates/direct_import/android_common/flat-res/gen_res.flata"}, 1037 directImportImports: []string{ 1038 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk", 1039 "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk", 1040 }, 1041 1042 transitiveImportResources: nil, 1043 transitiveImportOverlays: []string{"out/soong/.intermediates/transitive_import/android_common/flat-res/gen_res.flata"}, 1044 transitiveImportImports: []string{ 1045 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk", 1046 "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk", 1047 }, 1048 }, { 1049 // Test an app building with resource processor enabled but with dependencies built without 1050 // resource processor. 1051 name: "app_resource_processor", 1052 appUsesRP: true, 1053 directLibUsesRP: false, 1054 transitiveLibUsesRP: false, 1055 1056 appResources: nil, 1057 appOverlays: []string{ 1058 "out/soong/.intermediates/transitive/android_common/package-res.apk", 1059 "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk", 1060 "out/soong/.intermediates/transitive_import/android_common/package-res.apk", 1061 "out/soong/.intermediates/direct/android_common/package-res.apk", 1062 "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk", 1063 "out/soong/.intermediates/direct_import/android_common/package-res.apk", 1064 "out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat", 1065 }, 1066 appImports: []string{ 1067 "out/soong/.intermediates/shared/android_common/package-res.apk", 1068 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk", 1069 }, 1070 appSrcJars: nil, 1071 appClasspath: []string{ 1072 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", 1073 // R.jar has to come before direct.jar 1074 "out/soong/.intermediates/app/android_common/busybox/R.jar", 1075 "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar", 1076 "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar", 1077 "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar", 1078 }, 1079 appCombined: []string{ 1080 "out/soong/.intermediates/app/android_common/javac/app.jar", 1081 "out/soong/.intermediates/app/android_common/busybox/R.jar", 1082 "out/soong/.intermediates/direct/android_common/combined/direct.jar", 1083 "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar", 1084 }, 1085 1086 dontVerifyDirect: true, 1087 dontVerifyTransitive: true, 1088 dontVerifyShared: true, 1089 dontVerifyDirectImport: true, 1090 dontVerifyTransitiveImport: true, 1091 }, 1092 { 1093 // Test an app building without resource processor enabled but with a dependency built with 1094 // resource processor. 1095 name: "app_dependency_lib_resource_processor", 1096 appUsesRP: false, 1097 directLibUsesRP: true, 1098 transitiveLibUsesRP: false, 1099 1100 appOverlays: []string{ 1101 "out/soong/.intermediates/transitive/android_common/package-res.apk", 1102 "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk", 1103 "out/soong/.intermediates/transitive_import/android_common/package-res.apk", 1104 "out/soong/.intermediates/direct/android_common/package-res.apk", 1105 "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk", 1106 "out/soong/.intermediates/direct_import/android_common/package-res.apk", 1107 "out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat", 1108 }, 1109 appImports: []string{ 1110 "out/soong/.intermediates/shared/android_common/package-res.apk", 1111 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk", 1112 }, 1113 appSrcJars: []string{"out/soong/.intermediates/app/android_common/gen/android/R.srcjar"}, 1114 appClasspath: []string{ 1115 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", 1116 "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar", 1117 "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar", 1118 "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar", 1119 }, 1120 appCombined: []string{ 1121 "out/soong/.intermediates/app/android_common/javac/app.jar", 1122 "out/soong/.intermediates/direct/android_common/combined/direct.jar", 1123 "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar", 1124 }, 1125 1126 directResources: nil, 1127 directOverlays: []string{"out/soong/.intermediates/direct/android_common/aapt2/direct/res/values_strings.arsc.flat"}, 1128 directImports: []string{ 1129 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk", 1130 "out/soong/.intermediates/transitive_import/android_common/package-res.apk", 1131 "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk", 1132 "out/soong/.intermediates/transitive/android_common/package-res.apk", 1133 }, 1134 directSrcJars: nil, 1135 directClasspath: []string{ 1136 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", 1137 "out/soong/.intermediates/direct/android_common/busybox/R.jar", 1138 "out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar", 1139 "out/soong/.intermediates/transitive_import/android_common/busybox/R.jar", 1140 "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar", 1141 "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar", 1142 }, 1143 directCombined: []string{ 1144 "out/soong/.intermediates/direct/android_common/javac/direct.jar", 1145 "out/soong/.intermediates/transitive/android_common/javac/transitive.jar", 1146 "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar", 1147 }, 1148 1149 dontVerifyTransitive: true, 1150 dontVerifyShared: true, 1151 dontVerifyDirectImport: true, 1152 dontVerifyTransitiveImport: true, 1153 }, 1154 { 1155 // Test a library building without resource processor enabled but with a dependency built with 1156 // resource processor. 1157 name: "lib_dependency_lib_resource_processor", 1158 appUsesRP: false, 1159 directLibUsesRP: false, 1160 transitiveLibUsesRP: true, 1161 1162 appOverlays: []string{ 1163 "out/soong/.intermediates/transitive/android_common/package-res.apk", 1164 "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk", 1165 "out/soong/.intermediates/transitive_import/android_common/package-res.apk", 1166 "out/soong/.intermediates/direct/android_common/package-res.apk", 1167 "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk", 1168 "out/soong/.intermediates/direct_import/android_common/package-res.apk", 1169 "out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat", 1170 }, 1171 appImports: []string{ 1172 "out/soong/.intermediates/shared/android_common/package-res.apk", 1173 "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk", 1174 }, 1175 appSrcJars: []string{"out/soong/.intermediates/app/android_common/gen/android/R.srcjar"}, 1176 appClasspath: []string{ 1177 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", 1178 "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar", 1179 "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar", 1180 "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar", 1181 }, 1182 appCombined: []string{ 1183 "out/soong/.intermediates/app/android_common/javac/app.jar", 1184 "out/soong/.intermediates/direct/android_common/combined/direct.jar", 1185 "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar", 1186 }, 1187 1188 directResources: nil, 1189 directOverlays: []string{ 1190 "out/soong/.intermediates/transitive/android_common/package-res.apk", 1191 "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk", 1192 "out/soong/.intermediates/transitive_import/android_common/package-res.apk", 1193 "out/soong/.intermediates/direct/android_common/aapt2/direct/res/values_strings.arsc.flat", 1194 }, 1195 directImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"}, 1196 directSrcJars: []string{"out/soong/.intermediates/direct/android_common/gen/android/R.srcjar"}, 1197 directClasspath: []string{ 1198 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", 1199 "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar", 1200 "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar", 1201 }, 1202 directCombined: []string{ 1203 "out/soong/.intermediates/direct/android_common/javac/direct.jar", 1204 "out/soong/.intermediates/transitive/android_common/javac/transitive.jar", 1205 "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar", 1206 }, 1207 1208 transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"}, 1209 transitiveOverlays: nil, 1210 transitiveImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"}, 1211 transitiveSrcJars: nil, 1212 transitiveClasspath: []string{ 1213 "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", 1214 "out/soong/.intermediates/transitive/android_common/busybox/R.jar", 1215 }, 1216 transitiveCombined: nil, 1217 1218 dontVerifyShared: true, 1219 dontVerifyDirectImport: true, 1220 dontVerifyTransitiveImport: true, 1221 }, 1222 } 1223 1224 for _, testCase := range testCases { 1225 t.Run(testCase.name, func(t *testing.T) { 1226 bp := fmt.Sprintf(` 1227 android_app { 1228 name: "app", 1229 sdk_version: "current", 1230 srcs: ["app/app.java"], 1231 resource_dirs: ["app/res"], 1232 manifest: "app/AndroidManifest.xml", 1233 libs: ["shared"], 1234 static_libs: ["direct", "direct_import"], 1235 use_resource_processor: %v, 1236 } 1237 1238 android_library { 1239 name: "direct", 1240 sdk_version: "current", 1241 srcs: ["direct/direct.java"], 1242 resource_dirs: ["direct/res"], 1243 manifest: "direct/AndroidManifest.xml", 1244 static_libs: ["transitive", "transitive_import"], 1245 use_resource_processor: %v, 1246 } 1247 1248 android_library { 1249 name: "transitive", 1250 sdk_version: "current", 1251 srcs: ["transitive/transitive.java"], 1252 resource_dirs: ["transitive/res"], 1253 manifest: "transitive/AndroidManifest.xml", 1254 use_resource_processor: %v, 1255 } 1256 1257 android_library { 1258 name: "shared", 1259 sdk_version: "current", 1260 srcs: ["shared/shared.java"], 1261 resource_dirs: ["shared/res"], 1262 manifest: "shared/AndroidManifest.xml", 1263 use_resource_processor: %v, 1264 libs: ["shared_transitive_shared"], 1265 static_libs: ["shared_transitive_static"], 1266 } 1267 1268 android_library { 1269 name: "shared_transitive_shared", 1270 sdk_version: "current", 1271 srcs: ["shared_transitive_shared/shared_transitive_shared.java"], 1272 resource_dirs: ["shared_transitive_shared/res"], 1273 manifest: "shared_transitive_shared/AndroidManifest.xml", 1274 use_resource_processor: %v, 1275 } 1276 1277 android_library { 1278 name: "shared_transitive_static", 1279 sdk_version: "current", 1280 srcs: ["shared_transitive_static/shared.java"], 1281 resource_dirs: ["shared_transitive_static/res"], 1282 manifest: "shared_transitive_static/AndroidManifest.xml", 1283 use_resource_processor: %v, 1284 } 1285 1286 android_library_import { 1287 name: "direct_import", 1288 sdk_version: "current", 1289 aars: ["direct_import.aar"], 1290 static_libs: ["direct_import_dep"], 1291 } 1292 1293 android_library_import { 1294 name: "direct_import_dep", 1295 sdk_version: "current", 1296 aars: ["direct_import_dep.aar"], 1297 } 1298 1299 android_library_import { 1300 name: "transitive_import", 1301 sdk_version: "current", 1302 aars: ["transitive_import.aar"], 1303 static_libs: ["transitive_import_dep"], 1304 } 1305 1306 android_library_import { 1307 name: "transitive_import_dep", 1308 sdk_version: "current", 1309 aars: ["transitive_import_dep.aar"], 1310 } 1311 `, testCase.appUsesRP, testCase.directLibUsesRP, testCase.transitiveLibUsesRP, 1312 testCase.sharedLibUsesRP, testCase.sharedTransitiveSharedLibUsesRP, testCase.sharedTransitiveStaticLibUsesRP) 1313 1314 fs := android.MockFS{ 1315 "app/res/values/strings.xml": nil, 1316 "direct/res/values/strings.xml": nil, 1317 "transitive/res/values/strings.xml": nil, 1318 "shared/res/values/strings.xml": nil, 1319 "shared_transitive_static/res/values/strings.xml": nil, 1320 "shared_transitive_shared/res/values/strings.xml": nil, 1321 } 1322 1323 result := android.GroupFixturePreparers( 1324 PrepareForTestWithJavaDefaultModules, 1325 fs.AddToFixture(), 1326 ).RunTestWithBp(t, bp) 1327 1328 type aaptInfo struct { 1329 resources, overlays, imports, srcJars, classpath, combined android.Paths 1330 } 1331 1332 getAaptInfo := func(moduleName string) (aaptInfo aaptInfo) { 1333 mod := result.ModuleForTests(moduleName, "android_common") 1334 resourceListRule := mod.MaybeOutput("aapt2/res.list") 1335 overlayListRule := mod.MaybeOutput("aapt2/overlay.list") 1336 aaptRule := mod.Rule("aapt2Link") 1337 javacRule := mod.MaybeRule("javac") 1338 combinedRule := mod.MaybeOutput("combined/" + moduleName + ".jar") 1339 1340 aaptInfo.resources = resourceListRule.Inputs 1341 aaptInfo.overlays = overlayListRule.Inputs 1342 1343 aaptFlags := strings.Split(aaptRule.Args["flags"], " ") 1344 for i, flag := range aaptFlags { 1345 if flag == "-I" && i+1 < len(aaptFlags) { 1346 aaptInfo.imports = append(aaptInfo.imports, android.PathForTesting(aaptFlags[i+1])) 1347 } 1348 } 1349 1350 if len(javacRule.Args["srcJars"]) > 0 { 1351 aaptInfo.srcJars = android.PathsForTesting(strings.Split(javacRule.Args["srcJars"], " ")...) 1352 } 1353 1354 if len(javacRule.Args["classpath"]) > 0 { 1355 classpathArg := strings.TrimPrefix(javacRule.Args["classpath"], "-classpath ") 1356 aaptInfo.classpath = android.PathsForTesting(strings.Split(classpathArg, ":")...) 1357 } 1358 1359 aaptInfo.combined = combinedRule.Inputs 1360 return 1361 } 1362 1363 app := getAaptInfo("app") 1364 direct := getAaptInfo("direct") 1365 transitive := getAaptInfo("transitive") 1366 shared := getAaptInfo("shared") 1367 directImport := getAaptInfo("direct_import") 1368 transitiveImport := getAaptInfo("transitive_import") 1369 1370 if !testCase.dontVerifyApp { 1371 android.AssertPathsRelativeToTopEquals(t, "app resources", testCase.appResources, app.resources) 1372 android.AssertPathsRelativeToTopEquals(t, "app overlays", testCase.appOverlays, app.overlays) 1373 android.AssertPathsRelativeToTopEquals(t, "app imports", testCase.appImports, app.imports) 1374 android.AssertPathsRelativeToTopEquals(t, "app srcjars", testCase.appSrcJars, app.srcJars) 1375 android.AssertPathsRelativeToTopEquals(t, "app classpath", testCase.appClasspath, app.classpath) 1376 android.AssertPathsRelativeToTopEquals(t, "app combined", testCase.appCombined, app.combined) 1377 } 1378 1379 if !testCase.dontVerifyDirect { 1380 android.AssertPathsRelativeToTopEquals(t, "direct resources", testCase.directResources, direct.resources) 1381 android.AssertPathsRelativeToTopEquals(t, "direct overlays", testCase.directOverlays, direct.overlays) 1382 android.AssertPathsRelativeToTopEquals(t, "direct imports", testCase.directImports, direct.imports) 1383 android.AssertPathsRelativeToTopEquals(t, "direct srcjars", testCase.directSrcJars, direct.srcJars) 1384 android.AssertPathsRelativeToTopEquals(t, "direct classpath", testCase.directClasspath, direct.classpath) 1385 android.AssertPathsRelativeToTopEquals(t, "direct combined", testCase.directCombined, direct.combined) 1386 } 1387 1388 if !testCase.dontVerifyTransitive { 1389 android.AssertPathsRelativeToTopEquals(t, "transitive resources", testCase.transitiveResources, transitive.resources) 1390 android.AssertPathsRelativeToTopEquals(t, "transitive overlays", testCase.transitiveOverlays, transitive.overlays) 1391 android.AssertPathsRelativeToTopEquals(t, "transitive imports", testCase.transitiveImports, transitive.imports) 1392 android.AssertPathsRelativeToTopEquals(t, "transitive srcjars", testCase.transitiveSrcJars, transitive.srcJars) 1393 android.AssertPathsRelativeToTopEquals(t, "transitive classpath", testCase.transitiveClasspath, transitive.classpath) 1394 android.AssertPathsRelativeToTopEquals(t, "transitive combined", testCase.transitiveCombined, transitive.combined) 1395 } 1396 1397 if !testCase.dontVerifyShared { 1398 android.AssertPathsRelativeToTopEquals(t, "shared resources", testCase.sharedResources, shared.resources) 1399 android.AssertPathsRelativeToTopEquals(t, "shared overlays", testCase.sharedOverlays, shared.overlays) 1400 android.AssertPathsRelativeToTopEquals(t, "shared imports", testCase.sharedImports, shared.imports) 1401 android.AssertPathsRelativeToTopEquals(t, "shared srcjars", testCase.sharedSrcJars, shared.srcJars) 1402 android.AssertPathsRelativeToTopEquals(t, "shared classpath", testCase.sharedClasspath, shared.classpath) 1403 android.AssertPathsRelativeToTopEquals(t, "shared combined", testCase.sharedCombined, shared.combined) 1404 } 1405 1406 if !testCase.dontVerifyDirectImport { 1407 android.AssertPathsRelativeToTopEquals(t, "direct_import resources", testCase.directImportResources, directImport.resources) 1408 android.AssertPathsRelativeToTopEquals(t, "direct_import overlays", testCase.directImportOverlays, directImport.overlays) 1409 android.AssertPathsRelativeToTopEquals(t, "direct_import imports", testCase.directImportImports, directImport.imports) 1410 } 1411 1412 if !testCase.dontVerifyTransitiveImport { 1413 android.AssertPathsRelativeToTopEquals(t, "transitive_import resources", testCase.transitiveImportResources, transitiveImport.resources) 1414 android.AssertPathsRelativeToTopEquals(t, "transitive_import overlays", testCase.transitiveImportOverlays, transitiveImport.overlays) 1415 android.AssertPathsRelativeToTopEquals(t, "transitive_import imports", testCase.transitiveImportImports, transitiveImport.imports) 1416 } 1417 }) 1418 } 1419} 1420 1421func TestAndroidResourceOverlays(t *testing.T) { 1422 type moduleAndVariant struct { 1423 module string 1424 variant string 1425 } 1426 1427 testCases := []struct { 1428 name string 1429 enforceRROTargets []string 1430 enforceRROExcludedOverlays []string 1431 resourceFiles map[moduleAndVariant][]string 1432 overlayFiles map[moduleAndVariant][]string 1433 rroDirs map[moduleAndVariant][]string 1434 }{ 1435 { 1436 name: "no RRO", 1437 enforceRROTargets: nil, 1438 enforceRROExcludedOverlays: nil, 1439 resourceFiles: map[moduleAndVariant][]string{ 1440 {"foo", "android_common"}: nil, 1441 {"bar", "android_common"}: {"bar/res/res/values/strings.xml"}, 1442 {"lib", "android_common"}: nil, 1443 {"lib2", "android_common"}: {"lib2/res/res/values/strings.xml"}, 1444 }, 1445 overlayFiles: map[moduleAndVariant][]string{ 1446 {"foo", "android_common"}: { 1447 "out/soong/.intermediates/lib2/android_common/package-res.apk", 1448 "out/soong/.intermediates/lib/android_common/package-res.apk", 1449 "out/soong/.intermediates/lib3/android_common/package-res.apk", 1450 "foo/res/res/values/strings.xml", 1451 "device/vendor/blah/static_overlay/foo/res/values/strings.xml", 1452 "device/vendor/blah/overlay/foo/res/values/strings.xml", 1453 "product/vendor/blah/overlay/foo/res/values/strings.xml", 1454 }, 1455 {"bar", "android_common"}: { 1456 "device/vendor/blah/static_overlay/bar/res/values/strings.xml", 1457 "device/vendor/blah/overlay/bar/res/values/strings.xml", 1458 }, 1459 {"lib", "android_common"}: { 1460 "out/soong/.intermediates/lib2/android_common/package-res.apk", 1461 "lib/res/res/values/strings.xml", 1462 "device/vendor/blah/overlay/lib/res/values/strings.xml", 1463 }, 1464 }, 1465 rroDirs: map[moduleAndVariant][]string{ 1466 {"foo", "android_common"}: nil, 1467 {"bar", "android_common"}: nil, 1468 }, 1469 }, 1470 { 1471 name: "enforce RRO on foo", 1472 enforceRROTargets: []string{"foo"}, 1473 enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"}, 1474 resourceFiles: map[moduleAndVariant][]string{ 1475 {"foo", "android_common"}: nil, 1476 {"bar", "android_common"}: {"bar/res/res/values/strings.xml"}, 1477 {"lib", "android_common"}: nil, 1478 {"lib", "android_common_rro"}: nil, 1479 {"lib2", "android_common"}: {"lib2/res/res/values/strings.xml"}, 1480 {"lib2", "android_common_rro"}: {"lib2/res/res/values/strings.xml"}, 1481 }, 1482 overlayFiles: map[moduleAndVariant][]string{ 1483 {"foo", "android_common"}: { 1484 "out/soong/.intermediates/lib2/android_common_rro/package-res.apk", 1485 "out/soong/.intermediates/lib/android_common_rro/package-res.apk", 1486 "out/soong/.intermediates/lib3/android_common_rro/package-res.apk", 1487 "foo/res/res/values/strings.xml", 1488 "device/vendor/blah/static_overlay/foo/res/values/strings.xml", 1489 }, 1490 {"bar", "android_common"}: { 1491 "device/vendor/blah/static_overlay/bar/res/values/strings.xml", 1492 "device/vendor/blah/overlay/bar/res/values/strings.xml", 1493 }, 1494 {"lib", "android_common"}: { 1495 "out/soong/.intermediates/lib2/android_common/package-res.apk", 1496 "lib/res/res/values/strings.xml", 1497 "device/vendor/blah/overlay/lib/res/values/strings.xml", 1498 }, 1499 {"lib", "android_common_rro"}: { 1500 "out/soong/.intermediates/lib2/android_common_rro/package-res.apk", 1501 "lib/res/res/values/strings.xml", 1502 }, 1503 }, 1504 1505 rroDirs: map[moduleAndVariant][]string{ 1506 {"foo", "android_common"}: { 1507 "device:device/vendor/blah/overlay/foo/res", 1508 "product:product/vendor/blah/overlay/foo/res", 1509 "device:device/vendor/blah/overlay/lib/res", 1510 }, 1511 {"bar", "android_common"}: nil, 1512 {"lib", "android_common"}: nil, 1513 {"lib", "android_common_rro"}: {"device:device/vendor/blah/overlay/lib/res"}, 1514 }, 1515 }, 1516 { 1517 name: "enforce RRO on all", 1518 enforceRROTargets: []string{"*"}, 1519 enforceRROExcludedOverlays: []string{ 1520 // Excluding specific apps/res directories also allowed. 1521 "device/vendor/blah/static_overlay/foo", 1522 "device/vendor/blah/static_overlay/bar/res", 1523 }, 1524 resourceFiles: map[moduleAndVariant][]string{ 1525 {"foo", "android_common"}: nil, 1526 {"bar", "android_common"}: {"bar/res/res/values/strings.xml"}, 1527 {"lib", "android_common"}: nil, 1528 {"lib2", "android_common"}: {"lib2/res/res/values/strings.xml"}, 1529 }, 1530 overlayFiles: map[moduleAndVariant][]string{ 1531 {"foo", "android_common"}: { 1532 "out/soong/.intermediates/lib2/android_common/package-res.apk", 1533 "out/soong/.intermediates/lib/android_common/package-res.apk", 1534 "out/soong/.intermediates/lib3/android_common/package-res.apk", 1535 "foo/res/res/values/strings.xml", 1536 "device/vendor/blah/static_overlay/foo/res/values/strings.xml", 1537 }, 1538 {"bar", "android_common"}: {"device/vendor/blah/static_overlay/bar/res/values/strings.xml"}, 1539 {"lib", "android_common"}: { 1540 "out/soong/.intermediates/lib2/android_common/package-res.apk", 1541 "lib/res/res/values/strings.xml", 1542 }, 1543 }, 1544 rroDirs: map[moduleAndVariant][]string{ 1545 {"foo", "android_common"}: { 1546 "device:device/vendor/blah/overlay/foo/res", 1547 "product:product/vendor/blah/overlay/foo/res", 1548 // Lib dep comes after the direct deps 1549 "device:device/vendor/blah/overlay/lib/res", 1550 }, 1551 {"bar", "android_common"}: {"device:device/vendor/blah/overlay/bar/res"}, 1552 {"lib", "android_common"}: {"device:device/vendor/blah/overlay/lib/res"}, 1553 }, 1554 }, 1555 } 1556 1557 deviceResourceOverlays := []string{ 1558 "device/vendor/blah/overlay", 1559 "device/vendor/blah/overlay2", 1560 "device/vendor/blah/static_overlay", 1561 } 1562 1563 productResourceOverlays := []string{ 1564 "product/vendor/blah/overlay", 1565 } 1566 1567 fs := android.MockFS{ 1568 "foo/res/res/values/strings.xml": nil, 1569 "bar/res/res/values/strings.xml": nil, 1570 "lib/res/res/values/strings.xml": nil, 1571 "lib2/res/res/values/strings.xml": nil, 1572 "device/vendor/blah/overlay/foo/res/values/strings.xml": nil, 1573 "device/vendor/blah/overlay/bar/res/values/strings.xml": nil, 1574 "device/vendor/blah/overlay/lib/res/values/strings.xml": nil, 1575 "device/vendor/blah/static_overlay/foo/res/values/strings.xml": nil, 1576 "device/vendor/blah/static_overlay/bar/res/values/strings.xml": nil, 1577 "device/vendor/blah/overlay2/res/values/strings.xml": nil, 1578 "product/vendor/blah/overlay/foo/res/values/strings.xml": nil, 1579 } 1580 1581 bp := ` 1582 android_app { 1583 name: "foo", 1584 sdk_version: "current", 1585 resource_dirs: ["foo/res"], 1586 static_libs: ["lib", "lib3"], 1587 } 1588 1589 android_app { 1590 name: "bar", 1591 sdk_version: "current", 1592 resource_dirs: ["bar/res"], 1593 } 1594 1595 android_library { 1596 name: "lib", 1597 sdk_version: "current", 1598 resource_dirs: ["lib/res"], 1599 static_libs: ["lib2"], 1600 } 1601 1602 android_library { 1603 name: "lib2", 1604 sdk_version: "current", 1605 resource_dirs: ["lib2/res"], 1606 } 1607 1608 // This library has the same resources as lib (should not lead to dupe RROs) 1609 android_library { 1610 name: "lib3", 1611 sdk_version: "current", 1612 resource_dirs: ["lib/res"] 1613 } 1614 ` 1615 1616 for _, testCase := range testCases { 1617 t.Run(testCase.name, func(t *testing.T) { 1618 result := android.GroupFixturePreparers( 1619 PrepareForTestWithJavaDefaultModules, 1620 fs.AddToFixture(), 1621 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1622 variables.DeviceResourceOverlays = deviceResourceOverlays 1623 variables.ProductResourceOverlays = productResourceOverlays 1624 if testCase.enforceRROTargets != nil { 1625 variables.EnforceRROTargets = testCase.enforceRROTargets 1626 } 1627 if testCase.enforceRROExcludedOverlays != nil { 1628 variables.EnforceRROExcludedOverlays = testCase.enforceRROExcludedOverlays 1629 } 1630 }), 1631 ).RunTestWithBp(t, bp) 1632 1633 resourceListToFiles := func(module android.TestingModule, list []string) (files []string) { 1634 for _, o := range list { 1635 res := module.MaybeOutput(o) 1636 if res.Rule != nil { 1637 // If the overlay is compiled as part of this moduleAndVariant (i.e. a .arsc.flat file), 1638 // verify the inputs to the .arsc.flat rule. 1639 files = append(files, res.Inputs.Strings()...) 1640 } else { 1641 // Otherwise, verify the full path to the output of the other moduleAndVariant 1642 files = append(files, o) 1643 } 1644 } 1645 return files 1646 } 1647 1648 getResources := func(moduleName, variantName string) (resourceFiles, overlayFiles, rroDirs []string) { 1649 module := result.ModuleForTests(moduleName, variantName) 1650 resourceList := module.MaybeOutput("aapt2/res.list") 1651 if resourceList.Rule != nil { 1652 resourceFiles = resourceListToFiles(module, android.PathsRelativeToTop(resourceList.Inputs)) 1653 } 1654 overlayList := module.MaybeOutput("aapt2/overlay.list") 1655 if overlayList.Rule != nil { 1656 overlayFiles = resourceListToFiles(module, android.PathsRelativeToTop(overlayList.Inputs)) 1657 } 1658 1659 for _, d := range module.Module().(AndroidLibraryDependency).RRODirsDepSet().ToList() { 1660 var prefix string 1661 if d.overlayType == device { 1662 prefix = "device:" 1663 } else if d.overlayType == product { 1664 prefix = "product:" 1665 } else { 1666 t.Fatalf("Unexpected overlayType %d", d.overlayType) 1667 } 1668 rroDirs = append(rroDirs, prefix+android.PathRelativeToTop(d.path)) 1669 } 1670 1671 return resourceFiles, overlayFiles, rroDirs 1672 } 1673 1674 modules := []moduleAndVariant{ 1675 {"foo", "android_common"}, 1676 {"foo", "android_common_rro"}, 1677 {"bar", "android_common"}, 1678 {"bar", "android_common_rro"}, 1679 {"lib", "android_common"}, 1680 {"lib", "android_common_rro"}, 1681 {"lib2", "android_common"}, 1682 {"lib2", "android_common_rro"}, 1683 } 1684 for _, moduleAndVariant := range modules { 1685 if _, exists := testCase.resourceFiles[moduleAndVariant]; !exists { 1686 continue 1687 } 1688 resourceFiles, overlayFiles, rroDirs := getResources(moduleAndVariant.module, moduleAndVariant.variant) 1689 1690 if !reflect.DeepEqual(resourceFiles, testCase.resourceFiles[moduleAndVariant]) { 1691 t.Errorf("expected %s resource files:\n %#v\n got:\n %#v", 1692 moduleAndVariant, testCase.resourceFiles[moduleAndVariant], resourceFiles) 1693 } 1694 if !reflect.DeepEqual(overlayFiles, testCase.overlayFiles[moduleAndVariant]) { 1695 t.Errorf("expected %s overlay files:\n %#v\n got:\n %#v", 1696 moduleAndVariant, testCase.overlayFiles[moduleAndVariant], overlayFiles) 1697 } 1698 if !reflect.DeepEqual(rroDirs, testCase.rroDirs[moduleAndVariant]) { 1699 t.Errorf("expected %s rroDirs: %#v\n got:\n %#v", 1700 moduleAndVariant, testCase.rroDirs[moduleAndVariant], rroDirs) 1701 } 1702 } 1703 }) 1704 } 1705} 1706 1707func checkSdkVersion(t *testing.T, result *android.TestResult, expectedSdkVersion string) { 1708 foo := result.ModuleForTests("foo", "android_common") 1709 link := foo.Output("package-res.apk") 1710 linkFlags := strings.Split(link.Args["flags"], " ") 1711 min := android.IndexList("--min-sdk-version", linkFlags) 1712 target := android.IndexList("--target-sdk-version", linkFlags) 1713 1714 if min == -1 || target == -1 || min == len(linkFlags)-1 || target == len(linkFlags)-1 { 1715 t.Fatalf("missing --min-sdk-version or --target-sdk-version in link flags: %q", linkFlags) 1716 } 1717 1718 gotMinSdkVersion := linkFlags[min+1] 1719 gotTargetSdkVersion := linkFlags[target+1] 1720 1721 android.AssertStringEquals(t, "incorrect --min-sdk-version", expectedSdkVersion, gotMinSdkVersion) 1722 1723 android.AssertStringEquals(t, "incorrect --target-sdk-version", expectedSdkVersion, gotTargetSdkVersion) 1724} 1725 1726func TestAppSdkVersion(t *testing.T) { 1727 testCases := []struct { 1728 name string 1729 sdkVersion string 1730 platformSdkInt int 1731 platformSdkCodename string 1732 platformSdkFinal bool 1733 minSdkVersionBp string 1734 expectedMinSdkVersion string 1735 platformApis bool 1736 activeCodenames []string 1737 }{ 1738 { 1739 name: "current final SDK", 1740 sdkVersion: "current", 1741 platformSdkInt: 27, 1742 platformSdkCodename: "REL", 1743 platformSdkFinal: true, 1744 expectedMinSdkVersion: "27", 1745 }, 1746 { 1747 name: "current non-final SDK", 1748 sdkVersion: "current", 1749 platformSdkInt: 27, 1750 platformSdkCodename: "OMR1", 1751 platformSdkFinal: false, 1752 expectedMinSdkVersion: "OMR1", 1753 activeCodenames: []string{"OMR1"}, 1754 }, 1755 { 1756 name: "default final SDK", 1757 sdkVersion: "", 1758 platformApis: true, 1759 platformSdkInt: 27, 1760 platformSdkCodename: "REL", 1761 platformSdkFinal: true, 1762 expectedMinSdkVersion: "27", 1763 }, 1764 { 1765 name: "default non-final SDK", 1766 sdkVersion: "", 1767 platformApis: true, 1768 platformSdkInt: 27, 1769 platformSdkCodename: "OMR1", 1770 platformSdkFinal: false, 1771 expectedMinSdkVersion: "OMR1", 1772 activeCodenames: []string{"OMR1"}, 1773 }, 1774 { 1775 name: "14", 1776 sdkVersion: "14", 1777 expectedMinSdkVersion: "14", 1778 platformSdkCodename: "S", 1779 activeCodenames: []string{"S"}, 1780 }, 1781 { 1782 name: "two active SDKs", 1783 sdkVersion: "module_current", 1784 minSdkVersionBp: "UpsideDownCake", 1785 expectedMinSdkVersion: "UpsideDownCake", // And not VanillaIceCream 1786 platformSdkCodename: "VanillaIceCream", 1787 activeCodenames: []string{"UpsideDownCake", "VanillaIceCream"}, 1788 }, 1789 } 1790 1791 for _, moduleType := range []string{"android_app", "android_library"} { 1792 for _, test := range testCases { 1793 t.Run(moduleType+" "+test.name, func(t *testing.T) { 1794 platformApiProp := "" 1795 if test.platformApis { 1796 platformApiProp = "platform_apis: true," 1797 } 1798 minSdkVersionProp := "" 1799 if test.minSdkVersionBp != "" { 1800 minSdkVersionProp = fmt.Sprintf(` min_sdk_version: "%s",`, test.minSdkVersionBp) 1801 } 1802 bp := fmt.Sprintf(`%s { 1803 name: "foo", 1804 srcs: ["a.java"], 1805 sdk_version: "%s", 1806 %s 1807 %s 1808 }`, moduleType, test.sdkVersion, platformApiProp, minSdkVersionProp) 1809 1810 result := android.GroupFixturePreparers( 1811 prepareForJavaTest, 1812 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1813 variables.Platform_sdk_version = &test.platformSdkInt 1814 variables.Platform_sdk_codename = &test.platformSdkCodename 1815 variables.Platform_version_active_codenames = test.activeCodenames 1816 variables.Platform_sdk_final = &test.platformSdkFinal 1817 }), 1818 FixtureWithPrebuiltApis(map[string][]string{ 1819 "14": {"foo"}, 1820 }), 1821 ).RunTestWithBp(t, bp) 1822 1823 checkSdkVersion(t, result, test.expectedMinSdkVersion) 1824 }) 1825 } 1826 } 1827} 1828 1829func TestVendorAppSdkVersion(t *testing.T) { 1830 testCases := []struct { 1831 name string 1832 sdkVersion string 1833 platformSdkInt int 1834 platformSdkCodename string 1835 platformSdkFinal bool 1836 deviceCurrentApiLevelForVendorModules string 1837 expectedMinSdkVersion string 1838 }{ 1839 { 1840 name: "current final SDK", 1841 sdkVersion: "current", 1842 platformSdkInt: 29, 1843 platformSdkCodename: "REL", 1844 platformSdkFinal: true, 1845 deviceCurrentApiLevelForVendorModules: "29", 1846 expectedMinSdkVersion: "29", 1847 }, 1848 { 1849 name: "current final SDK", 1850 sdkVersion: "current", 1851 platformSdkInt: 29, 1852 platformSdkCodename: "REL", 1853 platformSdkFinal: true, 1854 deviceCurrentApiLevelForVendorModules: "28", 1855 expectedMinSdkVersion: "28", 1856 }, 1857 { 1858 name: "current final SDK", 1859 sdkVersion: "current", 1860 platformSdkInt: 29, 1861 platformSdkCodename: "Q", 1862 platformSdkFinal: false, 1863 deviceCurrentApiLevelForVendorModules: "28", 1864 expectedMinSdkVersion: "28", 1865 }, 1866 } 1867 1868 for _, moduleType := range []string{"android_app", "android_library"} { 1869 for _, sdkKind := range []string{"", "system_"} { 1870 for _, test := range testCases { 1871 t.Run(moduleType+" "+test.name, func(t *testing.T) { 1872 bp := fmt.Sprintf(`%s { 1873 name: "foo", 1874 srcs: ["a.java"], 1875 sdk_version: "%s%s", 1876 vendor: true, 1877 }`, moduleType, sdkKind, test.sdkVersion) 1878 1879 result := android.GroupFixturePreparers( 1880 prepareForJavaTest, 1881 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1882 variables.Platform_sdk_version = &test.platformSdkInt 1883 variables.Platform_sdk_codename = &test.platformSdkCodename 1884 variables.Platform_sdk_final = &test.platformSdkFinal 1885 variables.DeviceCurrentApiLevelForVendorModules = &test.deviceCurrentApiLevelForVendorModules 1886 variables.DeviceSystemSdkVersions = []string{"28", "29"} 1887 }), 1888 FixtureWithPrebuiltApis(map[string][]string{ 1889 "28": {"foo"}, 1890 "29": {"foo"}, 1891 "current": {"foo"}, 1892 }), 1893 ).RunTestWithBp(t, bp) 1894 1895 checkSdkVersion(t, result, test.expectedMinSdkVersion) 1896 }) 1897 } 1898 } 1899 } 1900} 1901 1902func TestJNIABI(t *testing.T) { 1903 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+` 1904 cc_library { 1905 name: "libjni", 1906 system_shared_libs: [], 1907 sdk_version: "current", 1908 stl: "none", 1909 } 1910 1911 android_test { 1912 name: "test", 1913 sdk_version: "core_platform", 1914 jni_libs: ["libjni"], 1915 } 1916 1917 android_test { 1918 name: "test_first", 1919 sdk_version: "core_platform", 1920 compile_multilib: "first", 1921 jni_libs: ["libjni"], 1922 } 1923 1924 android_test { 1925 name: "test_both", 1926 sdk_version: "core_platform", 1927 compile_multilib: "both", 1928 jni_libs: ["libjni"], 1929 } 1930 1931 android_test { 1932 name: "test_32", 1933 sdk_version: "core_platform", 1934 compile_multilib: "32", 1935 jni_libs: ["libjni"], 1936 } 1937 1938 android_test { 1939 name: "test_64", 1940 sdk_version: "core_platform", 1941 compile_multilib: "64", 1942 jni_libs: ["libjni"], 1943 } 1944 `) 1945 1946 testCases := []struct { 1947 name string 1948 abis []string 1949 }{ 1950 {"test", []string{"arm64-v8a"}}, 1951 {"test_first", []string{"arm64-v8a"}}, 1952 {"test_both", []string{"arm64-v8a", "armeabi-v7a"}}, 1953 {"test_32", []string{"armeabi-v7a"}}, 1954 {"test_64", []string{"arm64-v8a"}}, 1955 } 1956 1957 for _, test := range testCases { 1958 t.Run(test.name, func(t *testing.T) { 1959 app := ctx.ModuleForTests(test.name, "android_common") 1960 jniLibZip := app.Output("jnilibs.zip") 1961 var abis []string 1962 args := strings.Fields(jniLibZip.Args["jarArgs"]) 1963 for i := 0; i < len(args); i++ { 1964 if args[i] == "-P" { 1965 abis = append(abis, filepath.Base(args[i+1])) 1966 i++ 1967 } 1968 } 1969 if !reflect.DeepEqual(abis, test.abis) { 1970 t.Errorf("want abis %v, got %v", test.abis, abis) 1971 } 1972 }) 1973 } 1974} 1975 1976func TestAppSdkVersionByPartition(t *testing.T) { 1977 testJavaError(t, "sdk_version must have a value when the module is located at vendor or product", ` 1978 android_app { 1979 name: "foo", 1980 srcs: ["a.java"], 1981 vendor: true, 1982 platform_apis: true, 1983 } 1984 `) 1985 1986 testJava(t, ` 1987 android_app { 1988 name: "bar", 1989 srcs: ["b.java"], 1990 platform_apis: true, 1991 } 1992 `) 1993 1994 for _, enforce := range []bool{true, false} { 1995 bp := ` 1996 android_app { 1997 name: "foo", 1998 srcs: ["a.java"], 1999 product_specific: true, 2000 platform_apis: true, 2001 } 2002 ` 2003 2004 errorHandler := android.FixtureExpectsNoErrors 2005 if enforce { 2006 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern("sdk_version must have a value when the module is located at vendor or product") 2007 } 2008 2009 android.GroupFixturePreparers( 2010 PrepareForTestWithJavaDefaultModules, 2011 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 2012 variables.EnforceProductPartitionInterface = proptools.BoolPtr(enforce) 2013 }), 2014 ). 2015 ExtendWithErrorHandler(errorHandler). 2016 RunTestWithBp(t, bp) 2017 } 2018} 2019 2020func TestJNIPackaging(t *testing.T) { 2021 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+` 2022 cc_library { 2023 name: "libjni", 2024 system_shared_libs: [], 2025 stl: "none", 2026 sdk_version: "current", 2027 } 2028 2029 android_app { 2030 name: "app", 2031 jni_libs: ["libjni"], 2032 sdk_version: "current", 2033 } 2034 2035 android_app { 2036 name: "app_noembed", 2037 jni_libs: ["libjni"], 2038 use_embedded_native_libs: false, 2039 sdk_version: "current", 2040 } 2041 2042 android_app { 2043 name: "app_embed", 2044 jni_libs: ["libjni"], 2045 use_embedded_native_libs: true, 2046 sdk_version: "current", 2047 } 2048 2049 android_test { 2050 name: "test", 2051 sdk_version: "current", 2052 jni_libs: ["libjni"], 2053 } 2054 2055 android_test { 2056 name: "test_noembed", 2057 sdk_version: "current", 2058 jni_libs: ["libjni"], 2059 use_embedded_native_libs: false, 2060 } 2061 2062 android_test_helper_app { 2063 name: "test_helper", 2064 sdk_version: "current", 2065 jni_libs: ["libjni"], 2066 } 2067 2068 android_test_helper_app { 2069 name: "test_helper_noembed", 2070 sdk_version: "current", 2071 jni_libs: ["libjni"], 2072 use_embedded_native_libs: false, 2073 } 2074 `) 2075 2076 testCases := []struct { 2077 name string 2078 packaged bool 2079 compressed bool 2080 }{ 2081 {"app", false, false}, 2082 {"app_noembed", false, false}, 2083 {"app_embed", true, false}, 2084 {"test", true, false}, 2085 {"test_noembed", true, true}, 2086 {"test_helper", true, false}, 2087 {"test_helper_noembed", true, true}, 2088 } 2089 2090 for _, test := range testCases { 2091 t.Run(test.name, func(t *testing.T) { 2092 app := ctx.ModuleForTests(test.name, "android_common") 2093 jniLibZip := app.MaybeOutput("jnilibs.zip") 2094 if g, w := (jniLibZip.Rule != nil), test.packaged; g != w { 2095 t.Errorf("expected jni packaged %v, got %v", w, g) 2096 } 2097 2098 if jniLibZip.Rule != nil { 2099 if g, w := !strings.Contains(jniLibZip.Args["jarArgs"], "-L 0"), test.compressed; g != w { 2100 t.Errorf("expected jni compressed %v, got %v", w, g) 2101 } 2102 2103 if !strings.Contains(jniLibZip.Implicits[0].String(), "_sdk_") { 2104 t.Errorf("expected input %q to use sdk variant", jniLibZip.Implicits[0].String()) 2105 } 2106 } 2107 }) 2108 } 2109} 2110 2111func TestJNISDK(t *testing.T) { 2112 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+` 2113 cc_library { 2114 name: "libjni", 2115 system_shared_libs: [], 2116 stl: "none", 2117 sdk_version: "current", 2118 } 2119 2120 android_test { 2121 name: "app_platform", 2122 jni_libs: ["libjni"], 2123 platform_apis: true, 2124 } 2125 2126 android_test { 2127 name: "app_sdk", 2128 jni_libs: ["libjni"], 2129 sdk_version: "current", 2130 } 2131 2132 android_test { 2133 name: "app_force_platform", 2134 jni_libs: ["libjni"], 2135 sdk_version: "current", 2136 jni_uses_platform_apis: true, 2137 } 2138 2139 android_test { 2140 name: "app_force_sdk", 2141 jni_libs: ["libjni"], 2142 platform_apis: true, 2143 jni_uses_sdk_apis: true, 2144 } 2145 2146 cc_library { 2147 name: "libvendorjni", 2148 system_shared_libs: [], 2149 stl: "none", 2150 vendor: true, 2151 } 2152 2153 android_test { 2154 name: "app_vendor", 2155 jni_libs: ["libvendorjni"], 2156 sdk_version: "current", 2157 vendor: true, 2158 } 2159 `) 2160 2161 testCases := []struct { 2162 name string 2163 sdkJNI bool 2164 vendorJNI bool 2165 }{ 2166 {name: "app_platform"}, 2167 {name: "app_sdk", sdkJNI: true}, 2168 {name: "app_force_platform"}, 2169 {name: "app_force_sdk", sdkJNI: true}, 2170 {name: "app_vendor", vendorJNI: true}, 2171 } 2172 2173 platformJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_shared"). 2174 Output("libjni.so").Output.String() 2175 sdkJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared"). 2176 Output("libjni.so").Output.String() 2177 vendorJNI := ctx.ModuleForTests("libvendorjni", "android_vendor_arm64_armv8-a_shared"). 2178 Output("libvendorjni.so").Output.String() 2179 2180 for _, test := range testCases { 2181 t.Run(test.name, func(t *testing.T) { 2182 app := ctx.ModuleForTests(test.name, "android_common") 2183 2184 jniLibZip := app.MaybeOutput("jnilibs.zip") 2185 if len(jniLibZip.Implicits) != 1 { 2186 t.Fatalf("expected exactly one jni library, got %q", jniLibZip.Implicits.Strings()) 2187 } 2188 gotJNI := jniLibZip.Implicits[0].String() 2189 2190 if test.sdkJNI { 2191 if gotJNI != sdkJNI { 2192 t.Errorf("expected SDK JNI library %q, got %q", sdkJNI, gotJNI) 2193 } 2194 } else if test.vendorJNI { 2195 if gotJNI != vendorJNI { 2196 t.Errorf("expected platform JNI library %q, got %q", vendorJNI, gotJNI) 2197 } 2198 } else { 2199 if gotJNI != platformJNI { 2200 t.Errorf("expected platform JNI library %q, got %q", platformJNI, gotJNI) 2201 } 2202 } 2203 }) 2204 } 2205 2206 t.Run("jni_uses_platform_apis_error", func(t *testing.T) { 2207 testJavaError(t, `jni_uses_platform_apis: can only be set for modules that set sdk_version`, ` 2208 android_test { 2209 name: "app_platform", 2210 platform_apis: true, 2211 jni_uses_platform_apis: true, 2212 } 2213 `) 2214 }) 2215 2216 t.Run("jni_uses_sdk_apis_error", func(t *testing.T) { 2217 testJavaError(t, `jni_uses_sdk_apis: can only be set for modules that do not set sdk_version`, ` 2218 android_test { 2219 name: "app_sdk", 2220 sdk_version: "current", 2221 jni_uses_sdk_apis: true, 2222 } 2223 `) 2224 }) 2225 2226} 2227 2228func TestCertificates(t *testing.T) { 2229 testCases := []struct { 2230 name string 2231 bp string 2232 allowMissingDependencies bool 2233 certificateOverride string 2234 expectedCertSigningFlags string 2235 expectedCertificate string 2236 }{ 2237 { 2238 name: "default", 2239 bp: ` 2240 android_app { 2241 name: "foo", 2242 srcs: ["a.java"], 2243 sdk_version: "current", 2244 } 2245 `, 2246 certificateOverride: "", 2247 expectedCertSigningFlags: "", 2248 expectedCertificate: "build/make/target/product/security/testkey", 2249 }, 2250 { 2251 name: "module certificate property", 2252 bp: ` 2253 android_app { 2254 name: "foo", 2255 srcs: ["a.java"], 2256 certificate: ":new_certificate", 2257 sdk_version: "current", 2258 } 2259 2260 android_app_certificate { 2261 name: "new_certificate", 2262 certificate: "cert/new_cert", 2263 } 2264 `, 2265 certificateOverride: "", 2266 expectedCertSigningFlags: "", 2267 expectedCertificate: "cert/new_cert", 2268 }, 2269 { 2270 name: "path certificate property", 2271 bp: ` 2272 android_app { 2273 name: "foo", 2274 srcs: ["a.java"], 2275 certificate: "expiredkey", 2276 sdk_version: "current", 2277 } 2278 `, 2279 certificateOverride: "", 2280 expectedCertSigningFlags: "", 2281 expectedCertificate: "build/make/target/product/security/expiredkey", 2282 }, 2283 { 2284 name: "certificate overrides", 2285 bp: ` 2286 android_app { 2287 name: "foo", 2288 srcs: ["a.java"], 2289 certificate: "expiredkey", 2290 sdk_version: "current", 2291 } 2292 2293 android_app_certificate { 2294 name: "new_certificate", 2295 certificate: "cert/new_cert", 2296 } 2297 `, 2298 certificateOverride: "foo:new_certificate", 2299 expectedCertSigningFlags: "", 2300 expectedCertificate: "cert/new_cert", 2301 }, 2302 { 2303 name: "certificate signing flags", 2304 bp: ` 2305 android_app { 2306 name: "foo", 2307 srcs: ["a.java"], 2308 certificate: ":new_certificate", 2309 lineage: "lineage.bin", 2310 rotationMinSdkVersion: "32", 2311 sdk_version: "current", 2312 } 2313 2314 android_app_certificate { 2315 name: "new_certificate", 2316 certificate: "cert/new_cert", 2317 } 2318 `, 2319 certificateOverride: "", 2320 expectedCertSigningFlags: "--lineage lineage.bin --rotation-min-sdk-version 32", 2321 expectedCertificate: "cert/new_cert", 2322 }, 2323 { 2324 name: "cert signing flags from filegroup", 2325 bp: ` 2326 android_app { 2327 name: "foo", 2328 srcs: ["a.java"], 2329 certificate: ":new_certificate", 2330 lineage: ":lineage_bin", 2331 rotationMinSdkVersion: "32", 2332 sdk_version: "current", 2333 } 2334 2335 android_app_certificate { 2336 name: "new_certificate", 2337 certificate: "cert/new_cert", 2338 } 2339 2340 filegroup { 2341 name: "lineage_bin", 2342 srcs: ["lineage.bin"], 2343 } 2344 `, 2345 certificateOverride: "", 2346 expectedCertSigningFlags: "--lineage lineage.bin --rotation-min-sdk-version 32", 2347 expectedCertificate: "cert/new_cert", 2348 }, 2349 { 2350 name: "missing with AllowMissingDependencies", 2351 bp: ` 2352 android_app { 2353 name: "foo", 2354 srcs: ["a.java"], 2355 certificate: ":new_certificate", 2356 sdk_version: "current", 2357 } 2358 `, 2359 expectedCertificate: "out/soong/.intermediates/foo/android_common/missing", 2360 allowMissingDependencies: true, 2361 }, 2362 } 2363 2364 for _, test := range testCases { 2365 t.Run(test.name, func(t *testing.T) { 2366 result := android.GroupFixturePreparers( 2367 PrepareForTestWithJavaDefaultModules, 2368 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 2369 if test.certificateOverride != "" { 2370 variables.CertificateOverrides = []string{test.certificateOverride} 2371 } 2372 if test.allowMissingDependencies { 2373 variables.Allow_missing_dependencies = proptools.BoolPtr(true) 2374 } 2375 }), 2376 android.FixtureModifyContext(func(ctx *android.TestContext) { 2377 ctx.SetAllowMissingDependencies(test.allowMissingDependencies) 2378 }), 2379 ).RunTestWithBp(t, test.bp) 2380 2381 foo := result.ModuleForTests("foo", "android_common") 2382 2383 certificate := foo.Module().(*AndroidApp).certificate 2384 android.AssertPathRelativeToTopEquals(t, "certificates key", test.expectedCertificate+".pk8", certificate.Key) 2385 // The sign_target_files_apks and check_target_files_signatures 2386 // tools require that certificates have a .x509.pem extension. 2387 android.AssertPathRelativeToTopEquals(t, "certificates pem", test.expectedCertificate+".x509.pem", certificate.Pem) 2388 2389 signapk := foo.Output("foo.apk") 2390 if signapk.Rule != android.ErrorRule { 2391 signCertificateFlags := signapk.Args["certificates"] 2392 expectedFlags := certificate.Pem.String() + " " + certificate.Key.String() 2393 android.AssertStringEquals(t, "certificates flags", expectedFlags, signCertificateFlags) 2394 2395 certSigningFlags := signapk.Args["flags"] 2396 android.AssertStringEquals(t, "cert signing flags", test.expectedCertSigningFlags, certSigningFlags) 2397 } 2398 }) 2399 } 2400} 2401 2402func TestRequestV4SigningFlag(t *testing.T) { 2403 testCases := []struct { 2404 name string 2405 bp string 2406 expected string 2407 }{ 2408 { 2409 name: "default", 2410 bp: ` 2411 android_app { 2412 name: "foo", 2413 srcs: ["a.java"], 2414 sdk_version: "current", 2415 } 2416 `, 2417 expected: "", 2418 }, 2419 { 2420 name: "default", 2421 bp: ` 2422 android_app { 2423 name: "foo", 2424 srcs: ["a.java"], 2425 sdk_version: "current", 2426 v4_signature: false, 2427 } 2428 `, 2429 expected: "", 2430 }, 2431 { 2432 name: "module certificate property", 2433 bp: ` 2434 android_app { 2435 name: "foo", 2436 srcs: ["a.java"], 2437 sdk_version: "current", 2438 v4_signature: true, 2439 } 2440 `, 2441 expected: "--enable-v4", 2442 }, 2443 } 2444 2445 for _, test := range testCases { 2446 t.Run(test.name, func(t *testing.T) { 2447 result := android.GroupFixturePreparers( 2448 PrepareForTestWithJavaDefaultModules, 2449 ).RunTestWithBp(t, test.bp) 2450 2451 foo := result.ModuleForTests("foo", "android_common") 2452 2453 signapk := foo.Output("foo.apk") 2454 signFlags := signapk.Args["flags"] 2455 android.AssertStringEquals(t, "signing flags", test.expected, signFlags) 2456 }) 2457 } 2458} 2459 2460func TestPackageNameOverride(t *testing.T) { 2461 testCases := []struct { 2462 name string 2463 bp string 2464 packageNameOverride string 2465 expected []string 2466 }{ 2467 { 2468 name: "default", 2469 bp: ` 2470 android_app { 2471 name: "foo", 2472 srcs: ["a.java"], 2473 sdk_version: "current", 2474 } 2475 `, 2476 packageNameOverride: "", 2477 expected: []string{ 2478 "out/soong/.intermediates/foo/android_common/foo.apk", 2479 "out/soong/target/product/test_device/system/app/foo/foo.apk", 2480 }, 2481 }, 2482 { 2483 name: "overridden via PRODUCT_PACKAGE_NAME_OVERRIDES", 2484 bp: ` 2485 android_app { 2486 name: "foo", 2487 srcs: ["a.java"], 2488 sdk_version: "current", 2489 } 2490 `, 2491 packageNameOverride: "foo:bar", 2492 expected: []string{ 2493 // The package apk should be still be the original name for test dependencies. 2494 "out/soong/.intermediates/foo/android_common/bar.apk", 2495 "out/soong/target/product/test_device/system/app/bar/bar.apk", 2496 }, 2497 }, 2498 { 2499 name: "overridden via stem", 2500 bp: ` 2501 android_app { 2502 name: "foo", 2503 srcs: ["a.java"], 2504 sdk_version: "current", 2505 stem: "bar", 2506 } 2507 `, 2508 packageNameOverride: "", 2509 expected: []string{ 2510 "out/soong/.intermediates/foo/android_common/bar.apk", 2511 "out/soong/target/product/test_device/system/app/bar/bar.apk", 2512 }, 2513 }, 2514 } 2515 2516 for _, test := range testCases { 2517 t.Run(test.name, func(t *testing.T) { 2518 result := android.GroupFixturePreparers( 2519 PrepareForTestWithJavaDefaultModules, 2520 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 2521 if test.packageNameOverride != "" { 2522 variables.PackageNameOverrides = []string{test.packageNameOverride} 2523 } 2524 }), 2525 ).RunTestWithBp(t, test.bp) 2526 2527 foo := result.ModuleForTests("foo", "android_common") 2528 2529 outSoongDir := result.Config.SoongOutDir() 2530 2531 outputs := foo.AllOutputs() 2532 outputMap := make(map[string]bool) 2533 for _, o := range outputs { 2534 outputMap[android.StringPathRelativeToTop(outSoongDir, o)] = true 2535 } 2536 for _, e := range test.expected { 2537 if _, exist := outputMap[e]; !exist { 2538 t.Errorf("Can't find %q in output files.\nAll outputs:%v", e, outputs) 2539 } 2540 } 2541 }) 2542 } 2543} 2544 2545func TestInstrumentationTargetOverridden(t *testing.T) { 2546 bp := ` 2547 android_app { 2548 name: "foo", 2549 srcs: ["a.java"], 2550 sdk_version: "current", 2551 } 2552 2553 android_test { 2554 name: "bar", 2555 instrumentation_for: "foo", 2556 sdk_version: "current", 2557 } 2558 ` 2559 2560 result := android.GroupFixturePreparers( 2561 PrepareForTestWithJavaDefaultModules, 2562 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 2563 variables.ManifestPackageNameOverrides = []string{"foo:org.dandroid.bp"} 2564 }), 2565 ).RunTestWithBp(t, bp) 2566 2567 bar := result.ModuleForTests("bar", "android_common") 2568 res := bar.Output("package-res.apk") 2569 aapt2Flags := res.Args["flags"] 2570 e := "--rename-instrumentation-target-package org.dandroid.bp" 2571 if !strings.Contains(aapt2Flags, e) { 2572 t.Errorf("target package renaming flag, %q is missing in aapt2 link flags, %q", e, aapt2Flags) 2573 } 2574} 2575 2576func TestOverrideAndroidApp(t *testing.T) { 2577 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp( 2578 t, ` 2579 android_app { 2580 name: "foo", 2581 srcs: ["a.java"], 2582 certificate: "expiredkey", 2583 overrides: ["qux"], 2584 sdk_version: "current", 2585 } 2586 2587 override_android_app { 2588 name: "bar", 2589 base: "foo", 2590 certificate: ":new_certificate", 2591 lineage: "lineage.bin", 2592 rotationMinSdkVersion: "32", 2593 logging_parent: "bah", 2594 } 2595 2596 android_app_certificate { 2597 name: "new_certificate", 2598 certificate: "cert/new_cert", 2599 } 2600 2601 override_android_app { 2602 name: "baz", 2603 base: "foo", 2604 package_name: "org.dandroid.bp", 2605 } 2606 2607 override_android_app { 2608 name: "baz_no_rename_resources", 2609 base: "foo", 2610 package_name: "org.dandroid.bp", 2611 rename_resources_package: false, 2612 } 2613 2614 android_app { 2615 name: "foo_no_rename_resources", 2616 srcs: ["a.java"], 2617 certificate: "expiredkey", 2618 overrides: ["qux"], 2619 rename_resources_package: false, 2620 sdk_version: "current", 2621 } 2622 2623 override_android_app { 2624 name: "baz_base_no_rename_resources", 2625 base: "foo_no_rename_resources", 2626 package_name: "org.dandroid.bp", 2627 } 2628 2629 override_android_app { 2630 name: "baz_override_base_rename_resources", 2631 base: "foo_no_rename_resources", 2632 package_name: "org.dandroid.bp", 2633 rename_resources_package: true, 2634 } 2635 `) 2636 2637 expectedVariants := []struct { 2638 name string 2639 moduleName string 2640 variantName string 2641 apkName string 2642 apkPath string 2643 certFlag string 2644 certSigningFlags string 2645 overrides []string 2646 packageFlag string 2647 renameResources bool 2648 logging_parent string 2649 }{ 2650 { 2651 name: "foo", 2652 moduleName: "foo", 2653 variantName: "android_common", 2654 apkPath: "out/soong/target/product/test_device/system/app/foo/foo.apk", 2655 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", 2656 certSigningFlags: "", 2657 overrides: []string{"qux"}, 2658 packageFlag: "", 2659 renameResources: false, 2660 logging_parent: "", 2661 }, 2662 { 2663 name: "foo", 2664 moduleName: "bar", 2665 variantName: "android_common_bar", 2666 apkPath: "out/soong/target/product/test_device/system/app/bar/bar.apk", 2667 certFlag: "cert/new_cert.x509.pem cert/new_cert.pk8", 2668 certSigningFlags: "--lineage lineage.bin --rotation-min-sdk-version 32", 2669 overrides: []string{"qux", "foo"}, 2670 packageFlag: "", 2671 renameResources: false, 2672 logging_parent: "bah", 2673 }, 2674 { 2675 name: "foo", 2676 moduleName: "baz", 2677 variantName: "android_common_baz", 2678 apkPath: "out/soong/target/product/test_device/system/app/baz/baz.apk", 2679 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", 2680 certSigningFlags: "", 2681 overrides: []string{"qux", "foo"}, 2682 packageFlag: "org.dandroid.bp", 2683 renameResources: true, 2684 logging_parent: "", 2685 }, 2686 { 2687 name: "foo", 2688 moduleName: "baz_no_rename_resources", 2689 variantName: "android_common_baz_no_rename_resources", 2690 apkPath: "out/soong/target/product/test_device/system/app/baz_no_rename_resources/baz_no_rename_resources.apk", 2691 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", 2692 certSigningFlags: "", 2693 overrides: []string{"qux", "foo"}, 2694 packageFlag: "org.dandroid.bp", 2695 renameResources: false, 2696 logging_parent: "", 2697 }, 2698 { 2699 name: "foo_no_rename_resources", 2700 moduleName: "baz_base_no_rename_resources", 2701 variantName: "android_common_baz_base_no_rename_resources", 2702 apkPath: "out/soong/target/product/test_device/system/app/baz_base_no_rename_resources/baz_base_no_rename_resources.apk", 2703 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", 2704 certSigningFlags: "", 2705 overrides: []string{"qux", "foo_no_rename_resources"}, 2706 packageFlag: "org.dandroid.bp", 2707 renameResources: false, 2708 logging_parent: "", 2709 }, 2710 { 2711 name: "foo_no_rename_resources", 2712 moduleName: "baz_override_base_rename_resources", 2713 variantName: "android_common_baz_override_base_rename_resources", 2714 apkPath: "out/soong/target/product/test_device/system/app/baz_override_base_rename_resources/baz_override_base_rename_resources.apk", 2715 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", 2716 certSigningFlags: "", 2717 overrides: []string{"qux", "foo_no_rename_resources"}, 2718 packageFlag: "org.dandroid.bp", 2719 renameResources: true, 2720 logging_parent: "", 2721 }, 2722 } 2723 for _, expected := range expectedVariants { 2724 variant := result.ModuleForTests(expected.name, expected.variantName) 2725 2726 // Check the final apk name 2727 variant.Output(expected.apkPath) 2728 2729 // Check the certificate paths 2730 signapk := variant.Output(expected.moduleName + ".apk") 2731 certFlag := signapk.Args["certificates"] 2732 android.AssertStringEquals(t, "certificates flags", expected.certFlag, certFlag) 2733 2734 // Check the cert signing flags 2735 certSigningFlags := signapk.Args["flags"] 2736 android.AssertStringEquals(t, "cert signing flags", expected.certSigningFlags, certSigningFlags) 2737 2738 // Check if the overrides field values are correctly aggregated. 2739 mod := variant.Module().(*AndroidApp) 2740 android.AssertDeepEquals(t, "overrides property", expected.overrides, mod.overridableAppProperties.Overrides) 2741 2742 // Test Overridable property: Logging_parent 2743 logging_parent := mod.aapt.LoggingParent 2744 android.AssertStringEquals(t, "overrides property value for logging parent", expected.logging_parent, logging_parent) 2745 2746 // Check the package renaming flag, if exists. 2747 res := variant.Output("package-res.apk") 2748 aapt2Flags := res.Args["flags"] 2749 checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag) 2750 expectedPackage := expected.packageFlag 2751 if !expected.renameResources { 2752 expectedPackage = "" 2753 } 2754 checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expectedPackage) 2755 } 2756} 2757 2758func TestOverrideAndroidAppOverrides(t *testing.T) { 2759 ctx, _ := testJava( 2760 t, ` 2761 android_app { 2762 name: "foo", 2763 srcs: ["a.java"], 2764 sdk_version: "current", 2765 overrides: ["qux"] 2766 } 2767 2768 android_app { 2769 name: "bar", 2770 srcs: ["b.java"], 2771 sdk_version: "current", 2772 overrides: ["foo"] 2773 } 2774 2775 override_android_app { 2776 name: "foo_override", 2777 base: "foo", 2778 overrides: ["bar"] 2779 } 2780 `) 2781 2782 expectedVariants := []struct { 2783 name string 2784 moduleName string 2785 variantName string 2786 overrides []string 2787 }{ 2788 { 2789 name: "foo", 2790 moduleName: "foo", 2791 variantName: "android_common", 2792 overrides: []string{"qux"}, 2793 }, 2794 { 2795 name: "bar", 2796 moduleName: "bar", 2797 variantName: "android_common", 2798 overrides: []string{"foo"}, 2799 }, 2800 { 2801 name: "foo", 2802 moduleName: "foo_override", 2803 variantName: "android_common_foo_override", 2804 overrides: []string{"bar", "foo"}, 2805 }, 2806 } 2807 for _, expected := range expectedVariants { 2808 variant := ctx.ModuleForTests(expected.name, expected.variantName) 2809 2810 // Check if the overrides field values are correctly aggregated. 2811 mod := variant.Module().(*AndroidApp) 2812 android.AssertDeepEquals(t, "overrides property", expected.overrides, mod.overridableAppProperties.Overrides) 2813 } 2814} 2815 2816func TestOverrideAndroidAppWithPrebuilt(t *testing.T) { 2817 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp( 2818 t, ` 2819 android_app { 2820 name: "foo", 2821 srcs: ["a.java"], 2822 sdk_version: "current", 2823 } 2824 2825 override_android_app { 2826 name: "bar", 2827 base: "foo", 2828 } 2829 2830 android_app_import { 2831 name: "bar", 2832 prefer: true, 2833 apk: "bar.apk", 2834 presigned: true, 2835 } 2836 `) 2837 2838 // An app that has an override that also has a prebuilt should not be hidden. 2839 foo := result.ModuleForTests("foo", "android_common") 2840 if foo.Module().IsHideFromMake() { 2841 t.Errorf("expected foo to have HideFromMake false") 2842 } 2843 2844 // An override that also has a prebuilt should be hidden. 2845 barOverride := result.ModuleForTests("foo", "android_common_bar") 2846 if !barOverride.Module().IsHideFromMake() { 2847 t.Errorf("expected bar override variant of foo to have HideFromMake true") 2848 } 2849} 2850 2851func TestOverrideAndroidAppStem(t *testing.T) { 2852 ctx, _ := testJava(t, ` 2853 android_app { 2854 name: "foo", 2855 srcs: ["a.java"], 2856 sdk_version: "current", 2857 } 2858 override_android_app { 2859 name: "bar", 2860 base: "foo", 2861 } 2862 override_android_app { 2863 name: "baz", 2864 base: "foo", 2865 stem: "baz_stem", 2866 } 2867 android_app { 2868 name: "foo2", 2869 srcs: ["a.java"], 2870 sdk_version: "current", 2871 stem: "foo2_stem", 2872 } 2873 override_android_app { 2874 name: "bar2", 2875 base: "foo2", 2876 } 2877 override_android_app { 2878 name: "baz2", 2879 base: "foo2", 2880 stem: "baz2_stem", 2881 } 2882 `) 2883 for _, expected := range []struct { 2884 moduleName string 2885 variantName string 2886 apkPath string 2887 }{ 2888 { 2889 moduleName: "foo", 2890 variantName: "android_common", 2891 apkPath: "out/soong/target/product/test_device/system/app/foo/foo.apk", 2892 }, 2893 { 2894 moduleName: "foo", 2895 variantName: "android_common_bar", 2896 apkPath: "out/soong/target/product/test_device/system/app/bar/bar.apk", 2897 }, 2898 { 2899 moduleName: "foo", 2900 variantName: "android_common_baz", 2901 apkPath: "out/soong/target/product/test_device/system/app/baz_stem/baz_stem.apk", 2902 }, 2903 { 2904 moduleName: "foo2", 2905 variantName: "android_common", 2906 apkPath: "out/soong/target/product/test_device/system/app/foo2_stem/foo2_stem.apk", 2907 }, 2908 { 2909 moduleName: "foo2", 2910 variantName: "android_common_bar2", 2911 // Note that this may cause the duplicate output error. 2912 apkPath: "out/soong/target/product/test_device/system/app/foo2_stem/foo2_stem.apk", 2913 }, 2914 { 2915 moduleName: "foo2", 2916 variantName: "android_common_baz2", 2917 apkPath: "out/soong/target/product/test_device/system/app/baz2_stem/baz2_stem.apk", 2918 }, 2919 } { 2920 variant := ctx.ModuleForTests(expected.moduleName, expected.variantName) 2921 variant.Output(expected.apkPath) 2922 } 2923} 2924 2925func TestOverrideAndroidAppDependency(t *testing.T) { 2926 ctx, _ := testJava(t, ` 2927 android_app { 2928 name: "foo", 2929 srcs: ["a.java"], 2930 sdk_version: "current", 2931 } 2932 2933 override_android_app { 2934 name: "bar", 2935 base: "foo", 2936 package_name: "org.dandroid.bp", 2937 } 2938 2939 android_test { 2940 name: "baz", 2941 srcs: ["b.java"], 2942 instrumentation_for: "foo", 2943 } 2944 2945 android_test { 2946 name: "qux", 2947 srcs: ["b.java"], 2948 instrumentation_for: "bar", 2949 } 2950 `) 2951 2952 // Verify baz, which depends on the overridden module foo, has the correct classpath javac arg. 2953 javac := ctx.ModuleForTests("baz", "android_common").Rule("javac") 2954 fooTurbine := "out/soong/.intermediates/foo/android_common/turbine-combined/foo.jar" 2955 if !strings.Contains(javac.Args["classpath"], fooTurbine) { 2956 t.Errorf("baz classpath %v does not contain %q", javac.Args["classpath"], fooTurbine) 2957 } 2958 2959 // Verify qux, which depends on the overriding module bar, has the correct classpath javac arg. 2960 javac = ctx.ModuleForTests("qux", "android_common").Rule("javac") 2961 barTurbine := "out/soong/.intermediates/foo/android_common_bar/turbine-combined/foo.jar" 2962 if !strings.Contains(javac.Args["classpath"], barTurbine) { 2963 t.Errorf("qux classpath %v does not contain %q", javac.Args["classpath"], barTurbine) 2964 } 2965} 2966 2967func TestOverrideAndroidTest(t *testing.T) { 2968 ctx, _ := testJava(t, ` 2969 android_app { 2970 name: "foo", 2971 srcs: ["a.java"], 2972 package_name: "com.android.foo", 2973 sdk_version: "current", 2974 } 2975 2976 override_android_app { 2977 name: "bar", 2978 base: "foo", 2979 package_name: "com.android.bar", 2980 } 2981 2982 android_test { 2983 name: "foo_test", 2984 srcs: ["b.java"], 2985 instrumentation_for: "foo", 2986 } 2987 2988 override_android_test { 2989 name: "bar_test", 2990 base: "foo_test", 2991 package_name: "com.android.bar.test", 2992 instrumentation_for: "bar", 2993 instrumentation_target_package: "com.android.bar", 2994 } 2995 `) 2996 2997 expectedVariants := []struct { 2998 moduleName string 2999 variantName string 3000 apkPath string 3001 overrides []string 3002 targetVariant string 3003 packageFlag string 3004 targetPackageFlag string 3005 }{ 3006 { 3007 variantName: "android_common", 3008 apkPath: "/target/product/test_device/testcases/foo_test/arm64/foo_test.apk", 3009 overrides: nil, 3010 targetVariant: "android_common", 3011 packageFlag: "", 3012 targetPackageFlag: "", 3013 }, 3014 { 3015 variantName: "android_common_bar_test", 3016 apkPath: "/target/product/test_device/testcases/bar_test/arm64/bar_test.apk", 3017 overrides: []string{"foo_test"}, 3018 targetVariant: "android_common_bar", 3019 packageFlag: "com.android.bar.test", 3020 targetPackageFlag: "com.android.bar", 3021 }, 3022 } 3023 for _, expected := range expectedVariants { 3024 variant := ctx.ModuleForTests("foo_test", expected.variantName) 3025 3026 // Check the final apk name 3027 variant.Output("out/soong" + expected.apkPath) 3028 3029 // Check if the overrides field values are correctly aggregated. 3030 mod := variant.Module().(*AndroidTest) 3031 if !reflect.DeepEqual(expected.overrides, mod.overridableAppProperties.Overrides) { 3032 t.Errorf("Incorrect overrides property value, expected: %q, got: %q", 3033 expected.overrides, mod.overridableAppProperties.Overrides) 3034 } 3035 3036 // Check if javac classpath has the correct jar file path. This checks instrumentation_for overrides. 3037 javac := variant.Rule("javac") 3038 turbine := filepath.Join("out", "soong", ".intermediates", "foo", expected.targetVariant, "turbine-combined", "foo.jar") 3039 if !strings.Contains(javac.Args["classpath"], turbine) { 3040 t.Errorf("classpath %q does not contain %q", javac.Args["classpath"], turbine) 3041 } 3042 3043 // Check aapt2 flags. 3044 res := variant.Output("package-res.apk") 3045 aapt2Flags := res.Args["flags"] 3046 checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag) 3047 checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expected.packageFlag) 3048 checkAapt2LinkFlag(t, aapt2Flags, "rename-instrumentation-target-package", expected.targetPackageFlag) 3049 } 3050} 3051 3052func TestAndroidTest_FixTestConfig(t *testing.T) { 3053 ctx, _ := testJava(t, ` 3054 android_app { 3055 name: "foo", 3056 srcs: ["a.java"], 3057 package_name: "com.android.foo", 3058 sdk_version: "current", 3059 } 3060 3061 android_test { 3062 name: "foo_test", 3063 srcs: ["b.java"], 3064 instrumentation_for: "foo", 3065 } 3066 3067 android_test { 3068 name: "bar_test", 3069 srcs: ["b.java"], 3070 package_name: "com.android.bar.test", 3071 instrumentation_for: "foo", 3072 mainline_package_name: "com.android.bar", 3073 } 3074 3075 override_android_test { 3076 name: "baz_test", 3077 base: "foo_test", 3078 package_name: "com.android.baz.test", 3079 mainline_package_name: "com.android.baz", 3080 } 3081 `) 3082 3083 testCases := []struct { 3084 moduleName string 3085 variantName string 3086 expectedFlags []string 3087 }{ 3088 { 3089 moduleName: "foo_test", 3090 variantName: "android_common", 3091 }, 3092 { 3093 moduleName: "bar_test", 3094 variantName: "android_common", 3095 expectedFlags: []string{ 3096 "--manifest out/soong/.intermediates/bar_test/android_common/manifest_fixer/AndroidManifest.xml", 3097 "--package-name com.android.bar.test", 3098 "--mainline-package-name com.android.bar", 3099 }, 3100 }, 3101 { 3102 moduleName: "foo_test", 3103 variantName: "android_common_baz_test", 3104 expectedFlags: []string{ 3105 "--manifest out/soong/.intermediates/foo_test/android_common_baz_test/manifest_fixer/AndroidManifest.xml", 3106 "--package-name com.android.baz.test", 3107 "--test-file-name baz_test.apk", 3108 "out/soong/.intermediates/foo_test/android_common_baz_test/test_config_fixer/AndroidTest.xml", 3109 "--mainline-package-name com.android.baz", 3110 }, 3111 }, 3112 } 3113 3114 for _, test := range testCases { 3115 variant := ctx.ModuleForTests(test.moduleName, test.variantName) 3116 params := variant.MaybeOutput("test_config_fixer/AndroidTest.xml") 3117 3118 if len(test.expectedFlags) > 0 { 3119 if params.Rule == nil { 3120 t.Errorf("test_config_fixer was expected to run, but didn't") 3121 } else { 3122 for _, flag := range test.expectedFlags { 3123 if !strings.Contains(params.RuleParams.Command, flag) { 3124 t.Errorf("Flag %q was not found in command: %q", flag, params.RuleParams.Command) 3125 } 3126 } 3127 } 3128 } else { 3129 if params.Rule != nil { 3130 t.Errorf("test_config_fixer was not expected to run, but did: %q", params.RuleParams.Command) 3131 } 3132 } 3133 } 3134} 3135 3136func TestInstrumentationTargetPrebuilt(t *testing.T) { 3137 bp := ` 3138 android_app_import { 3139 name: "foo", 3140 apk: "foo.apk", 3141 presigned: true, 3142 } 3143 3144 android_test { 3145 name: "bar", 3146 srcs: ["a.java"], 3147 instrumentation_for: "foo", 3148 sdk_version: "current", 3149 } 3150 ` 3151 3152 android.GroupFixturePreparers( 3153 PrepareForTestWithJavaDefaultModules, 3154 ).ExtendWithErrorHandler( 3155 android.FixtureExpectsAtLeastOneErrorMatchingPattern( 3156 "instrumentation_for: dependency \"foo\" of type \"android_app_import\" does not provide JavaInfo so is unsuitable for use with this property")). 3157 RunTestWithBp(t, bp) 3158} 3159 3160func TestStl(t *testing.T) { 3161 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+` 3162 cc_library { 3163 name: "libjni", 3164 sdk_version: "current", 3165 stl: "c++_shared", 3166 } 3167 3168 android_test { 3169 name: "stl", 3170 jni_libs: ["libjni"], 3171 compile_multilib: "both", 3172 sdk_version: "current", 3173 stl: "c++_shared", 3174 } 3175 3176 android_test { 3177 name: "system", 3178 jni_libs: ["libjni"], 3179 compile_multilib: "both", 3180 sdk_version: "current", 3181 } 3182 `) 3183 3184 testCases := []struct { 3185 name string 3186 jnis []string 3187 }{ 3188 {"stl", 3189 []string{ 3190 "libjni.so", 3191 "libc++_shared.so", 3192 }, 3193 }, 3194 {"system", 3195 []string{ 3196 "libjni.so", 3197 }, 3198 }, 3199 } 3200 3201 for _, test := range testCases { 3202 t.Run(test.name, func(t *testing.T) { 3203 app := ctx.ModuleForTests(test.name, "android_common") 3204 jniLibZip := app.Output("jnilibs.zip") 3205 var jnis []string 3206 args := strings.Fields(jniLibZip.Args["jarArgs"]) 3207 for i := 0; i < len(args); i++ { 3208 if args[i] == "-f" { 3209 jnis = append(jnis, args[i+1]) 3210 i += 1 3211 } 3212 } 3213 jnisJoined := strings.Join(jnis, " ") 3214 for _, jni := range test.jnis { 3215 if !strings.Contains(jnisJoined, jni) { 3216 t.Errorf("missing jni %q in %q", jni, jnis) 3217 } 3218 } 3219 }) 3220 } 3221} 3222 3223func TestUsesLibraries(t *testing.T) { 3224 bp := ` 3225 java_sdk_library { 3226 name: "foo", 3227 srcs: ["a.java"], 3228 api_packages: ["foo"], 3229 sdk_version: "current", 3230 } 3231 3232 java_sdk_library { 3233 name: "qux", 3234 srcs: ["a.java"], 3235 api_packages: ["qux"], 3236 sdk_version: "current", 3237 } 3238 3239 java_sdk_library { 3240 name: "quuz", 3241 srcs: ["a.java"], 3242 api_packages: ["quuz"], 3243 sdk_version: "current", 3244 } 3245 3246 java_sdk_library { 3247 name: "fred", 3248 srcs: ["a.java"], 3249 api_packages: ["fred"], 3250 sdk_version: "current", 3251 } 3252 3253 java_sdk_library { 3254 name: "bar", 3255 srcs: ["a.java"], 3256 api_packages: ["bar"], 3257 sdk_version: "current", 3258 } 3259 3260 java_sdk_library { 3261 name: "runtime-library", 3262 srcs: ["a.java"], 3263 sdk_version: "current", 3264 } 3265 3266 java_library { 3267 name: "static-runtime-helper", 3268 srcs: ["a.java"], 3269 libs: ["runtime-library.impl"], 3270 sdk_version: "current", 3271 } 3272 3273 java_library { 3274 name: "runtime-required-x", 3275 srcs: ["a.java"], 3276 installable: true, 3277 sdk_version: "current", 3278 } 3279 3280 java_library { 3281 name: "runtime-optional-x", 3282 srcs: ["a.java"], 3283 installable: true, 3284 sdk_version: "current", 3285 } 3286 3287 android_library { 3288 name: "static-x", 3289 uses_libs: ["runtime-required-x"], 3290 optional_uses_libs: ["runtime-optional-x"], 3291 sdk_version: "current", 3292 } 3293 3294 java_library { 3295 name: "runtime-required-y", 3296 srcs: ["a.java"], 3297 installable: true, 3298 sdk_version: "current", 3299 } 3300 3301 java_library { 3302 name: "runtime-optional-y", 3303 srcs: ["a.java"], 3304 installable: true, 3305 sdk_version: "current", 3306 } 3307 3308 java_library { 3309 name: "static-y", 3310 srcs: ["a.java"], 3311 uses_libs: ["runtime-required-y"], 3312 optional_uses_libs: [ 3313 "runtime-optional-y", 3314 "missing-lib-a", 3315 ], 3316 sdk_version: "current", 3317 } 3318 3319 // A library that has to use "provides_uses_lib", because: 3320 // - it is not an SDK library 3321 // - its library name is different from its module name 3322 java_library { 3323 name: "non-sdk-lib", 3324 provides_uses_lib: "com.non.sdk.lib", 3325 installable: true, 3326 srcs: ["a.java"], 3327 } 3328 3329 android_app { 3330 name: "app", 3331 srcs: ["a.java"], 3332 libs: [ 3333 "qux.impl", 3334 "quuz.stubs" 3335 ], 3336 static_libs: [ 3337 "static-runtime-helper", 3338 // statically linked component libraries should not pull their SDK libraries, 3339 // so "fred" should not be added to class loader context 3340 "fred.stubs", 3341 "static-x", 3342 "static-y", 3343 ], 3344 uses_libs: [ 3345 "foo", 3346 "non-sdk-lib" 3347 ], 3348 sdk_version: "current", 3349 optional_uses_libs: [ 3350 "bar", 3351 "missing-lib-b", 3352 ], 3353 } 3354 3355 android_app_import { 3356 name: "prebuilt", 3357 apk: "prebuilts/apk/app.apk", 3358 certificate: "platform", 3359 uses_libs: [ 3360 "foo", 3361 "non-sdk-lib", 3362 "android.test.runner" 3363 ], 3364 optional_uses_libs: [ 3365 "bar", 3366 "missing-lib-b", 3367 ], 3368 } 3369 ` 3370 3371 result := android.GroupFixturePreparers( 3372 prepareForJavaTest, 3373 PrepareForTestWithJavaSdkLibraryFiles, 3374 FixtureWithLastReleaseApis("runtime-library", "foo", "quuz", "qux", "bar", "fred"), 3375 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 3376 variables.BuildWarningBadOptionalUsesLibsAllowlist = []string{"app", "prebuilt"} 3377 }), 3378 ).RunTestWithBp(t, bp) 3379 3380 app := result.ModuleForTests("app", "android_common") 3381 prebuilt := result.ModuleForTests("prebuilt", "android_common") 3382 3383 // Test that implicit dependencies on java_sdk_library instances are passed to the manifest. 3384 // These also include explicit `uses_libs`/`optional_uses_libs` entries, as they may be 3385 // propagated from dependencies. 3386 actualManifestFixerArgs := app.Output("manifest_fixer/AndroidManifest.xml").Args["args"] 3387 expectManifestFixerArgs := `--extract-native-libs=true ` + 3388 `--uses-library foo ` + 3389 `--uses-library com.non.sdk.lib ` + 3390 `--uses-library qux ` + 3391 `--uses-library quuz ` + 3392 `--uses-library runtime-library ` + 3393 `--uses-library runtime-required-x ` + 3394 `--uses-library runtime-required-y ` + 3395 `--optional-uses-library bar ` + 3396 `--optional-uses-library runtime-optional-x ` + 3397 `--optional-uses-library runtime-optional-y` 3398 android.AssertStringDoesContain(t, "manifest_fixer args", actualManifestFixerArgs, expectManifestFixerArgs) 3399 3400 // Test that all libraries are verified (library order matters). 3401 verifyCmd := app.Rule("verify_uses_libraries").RuleParams.Command 3402 verifyArgs := `--uses-library foo ` + 3403 `--uses-library com.non.sdk.lib ` + 3404 `--uses-library qux ` + 3405 `--uses-library quuz ` + 3406 `--uses-library runtime-library ` + 3407 `--uses-library runtime-required-x ` + 3408 `--uses-library runtime-required-y ` + 3409 `--optional-uses-library bar ` + 3410 `--optional-uses-library runtime-optional-x ` + 3411 `--optional-uses-library runtime-optional-y ` + 3412 `--missing-optional-uses-library missing-lib-b ` + 3413 `--missing-optional-uses-library missing-lib-a` 3414 android.AssertStringDoesContain(t, "verify cmd args", verifyCmd, verifyArgs) 3415 3416 // Test that all libraries are verified for an APK (library order matters). 3417 verifyApkCmd := prebuilt.Rule("verify_uses_libraries").RuleParams.Command 3418 verifyApkArgs := `--uses-library foo ` + 3419 `--uses-library com.non.sdk.lib ` + 3420 `--uses-library android.test.runner ` + 3421 `--optional-uses-library bar ` + 3422 `--missing-optional-uses-library missing-lib-b ` 3423 android.AssertStringDoesContain(t, "verify apk cmd args", verifyApkCmd, verifyApkArgs) 3424 3425 // Test that necessary args are passed for constructing CLC in Ninja phase. 3426 cmd := app.Rule("dexpreopt").RuleParams.Command 3427 android.AssertStringDoesContain(t, "dexpreopt app cmd context", cmd, "--context-json=") 3428 android.AssertStringDoesContain(t, "dexpreopt app cmd product_packages", cmd, 3429 "--product-packages=out/soong/.intermediates/app/android_common/dexpreopt/app/product_packages.txt") 3430} 3431 3432func TestDexpreoptBcp(t *testing.T) { 3433 bp := ` 3434 java_sdk_library { 3435 name: "foo", 3436 srcs: ["a.java"], 3437 api_packages: ["foo"], 3438 sdk_version: "current", 3439 } 3440 3441 java_sdk_library { 3442 name: "bar", 3443 srcs: ["a.java"], 3444 api_packages: ["bar"], 3445 permitted_packages: ["bar"], 3446 sdk_version: "current", 3447 } 3448 3449 android_app { 3450 name: "app", 3451 srcs: ["a.java"], 3452 sdk_version: "current", 3453 } 3454 ` 3455 3456 testCases := []struct { 3457 name string 3458 with bool 3459 expect string 3460 }{ 3461 { 3462 name: "with updatable bcp", 3463 with: true, 3464 expect: "/system/framework/foo.jar:/system/framework/bar.jar", 3465 }, 3466 { 3467 name: "without updatable bcp", 3468 with: false, 3469 expect: "/system/framework/foo.jar", 3470 }, 3471 } 3472 3473 for _, test := range testCases { 3474 t.Run(test.name, func(t *testing.T) { 3475 result := android.GroupFixturePreparers( 3476 prepareForJavaTest, 3477 PrepareForTestWithJavaSdkLibraryFiles, 3478 FixtureWithLastReleaseApis("runtime-library", "foo", "bar"), 3479 dexpreopt.FixtureSetBootJars("platform:foo"), 3480 dexpreopt.FixtureSetApexBootJars("platform:bar"), 3481 dexpreopt.FixtureSetPreoptWithUpdatableBcp(test.with), 3482 ).RunTestWithBp(t, bp) 3483 3484 app := result.ModuleForTests("app", "android_common") 3485 cmd := app.Rule("dexpreopt").RuleParams.Command 3486 bcp := " -Xbootclasspath-locations:" + test.expect + " " // space at the end matters 3487 android.AssertStringDoesContain(t, "dexpreopt app bcp", cmd, bcp) 3488 }) 3489 } 3490} 3491 3492func TestCodelessApp(t *testing.T) { 3493 testCases := []struct { 3494 name string 3495 bp string 3496 noCode bool 3497 }{ 3498 { 3499 name: "normal", 3500 bp: ` 3501 android_app { 3502 name: "foo", 3503 srcs: ["a.java"], 3504 sdk_version: "current", 3505 } 3506 `, 3507 noCode: false, 3508 }, 3509 { 3510 name: "app without sources", 3511 bp: ` 3512 android_app { 3513 name: "foo", 3514 sdk_version: "current", 3515 } 3516 `, 3517 noCode: true, 3518 }, 3519 { 3520 name: "app with libraries", 3521 bp: ` 3522 android_app { 3523 name: "foo", 3524 static_libs: ["lib"], 3525 sdk_version: "current", 3526 } 3527 3528 java_library { 3529 name: "lib", 3530 srcs: ["a.java"], 3531 sdk_version: "current", 3532 } 3533 `, 3534 noCode: false, 3535 }, 3536 { 3537 name: "app with sourceless libraries", 3538 bp: ` 3539 android_app { 3540 name: "foo", 3541 static_libs: ["lib"], 3542 sdk_version: "current", 3543 } 3544 3545 java_library { 3546 name: "lib", 3547 sdk_version: "current", 3548 } 3549 `, 3550 // TODO(jungjw): this should probably be true 3551 noCode: false, 3552 }, 3553 } 3554 3555 for _, test := range testCases { 3556 t.Run(test.name, func(t *testing.T) { 3557 ctx := testApp(t, test.bp) 3558 3559 foo := ctx.ModuleForTests("foo", "android_common") 3560 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"] 3561 if strings.Contains(manifestFixerArgs, "--has-no-code") != test.noCode { 3562 t.Errorf("unexpected manifest_fixer args: %q", manifestFixerArgs) 3563 } 3564 }) 3565 } 3566} 3567 3568func TestUncompressDex(t *testing.T) { 3569 testCases := []struct { 3570 name string 3571 bp string 3572 3573 uncompressedPlatform bool 3574 uncompressedUnbundled bool 3575 }{ 3576 { 3577 name: "normal", 3578 bp: ` 3579 android_app { 3580 name: "foo", 3581 srcs: ["a.java"], 3582 sdk_version: "current", 3583 } 3584 `, 3585 uncompressedPlatform: true, 3586 uncompressedUnbundled: false, 3587 }, 3588 { 3589 name: "use_embedded_dex", 3590 bp: ` 3591 android_app { 3592 name: "foo", 3593 use_embedded_dex: true, 3594 srcs: ["a.java"], 3595 sdk_version: "current", 3596 } 3597 `, 3598 uncompressedPlatform: true, 3599 uncompressedUnbundled: true, 3600 }, 3601 { 3602 name: "privileged", 3603 bp: ` 3604 android_app { 3605 name: "foo", 3606 privileged: true, 3607 srcs: ["a.java"], 3608 sdk_version: "current", 3609 } 3610 `, 3611 uncompressedPlatform: true, 3612 uncompressedUnbundled: true, 3613 }, 3614 { 3615 name: "normal_uncompress_dex_true", 3616 bp: ` 3617 android_app { 3618 name: "foo", 3619 srcs: ["a.java"], 3620 sdk_version: "current", 3621 uncompress_dex: true, 3622 } 3623 `, 3624 uncompressedPlatform: true, 3625 uncompressedUnbundled: true, 3626 }, 3627 { 3628 name: "normal_uncompress_dex_false", 3629 bp: ` 3630 android_app { 3631 name: "foo", 3632 srcs: ["a.java"], 3633 sdk_version: "current", 3634 uncompress_dex: false, 3635 } 3636 `, 3637 uncompressedPlatform: false, 3638 uncompressedUnbundled: false, 3639 }, 3640 } 3641 3642 test := func(t *testing.T, bp string, want bool, unbundled bool) { 3643 t.Helper() 3644 3645 result := android.GroupFixturePreparers( 3646 prepareForJavaTest, 3647 PrepareForTestWithPrebuiltsOfCurrentApi, 3648 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 3649 if unbundled { 3650 variables.Unbundled_build = proptools.BoolPtr(true) 3651 variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true) 3652 } 3653 }), 3654 ).RunTestWithBp(t, bp) 3655 3656 foo := result.ModuleForTests("foo", "android_common") 3657 dex := foo.Rule("r8") 3658 uncompressedInDexJar := strings.Contains(dex.Args["zipFlags"], "-L 0") 3659 aligned := foo.MaybeRule("zipalign").Rule != nil 3660 3661 android.AssertBoolEquals(t, "uncompressed in dex", want, uncompressedInDexJar) 3662 3663 android.AssertBoolEquals(t, "aligne", want, aligned) 3664 } 3665 3666 for _, tt := range testCases { 3667 t.Run(tt.name, func(t *testing.T) { 3668 t.Run("platform", func(t *testing.T) { 3669 test(t, tt.bp, tt.uncompressedPlatform, false) 3670 }) 3671 t.Run("unbundled", func(t *testing.T) { 3672 test(t, tt.bp, tt.uncompressedUnbundled, true) 3673 }) 3674 }) 3675 } 3676} 3677 3678func checkAapt2LinkFlag(t *testing.T, aapt2Flags, flagName, expectedValue string) { 3679 if expectedValue != "" { 3680 expectedFlag := "--" + flagName + " " + expectedValue 3681 if !strings.Contains(aapt2Flags, expectedFlag) { 3682 t.Errorf("%q is missing in aapt2 link flags, %q", expectedFlag, aapt2Flags) 3683 } 3684 } else { 3685 unexpectedFlag := "--" + flagName 3686 if strings.Contains(aapt2Flags, unexpectedFlag) { 3687 t.Errorf("unexpected flag, %q is found in aapt2 link flags, %q", unexpectedFlag, aapt2Flags) 3688 } 3689 } 3690} 3691 3692func TestExportedProguardFlagFiles(t *testing.T) { 3693 ctx, _ := testJava(t, ` 3694 android_app { 3695 name: "foo", 3696 sdk_version: "current", 3697 static_libs: [ 3698 "lib1", 3699 "lib3", 3700 ], 3701 } 3702 3703 android_library { 3704 name: "lib1", 3705 sdk_version: "current", 3706 optimize: { 3707 proguard_flags_files: ["lib1proguard.cfg"], 3708 }, 3709 static_libs: ["lib2"], 3710 } 3711 3712 android_library { 3713 name: "lib2", 3714 sdk_version: "current", 3715 optimize: { 3716 proguard_flags_files: ["lib2proguard.cfg"], 3717 } 3718 } 3719 3720 android_library_import { 3721 name: "lib3", 3722 sdk_version: "current", 3723 aars: ["lib3.aar"], 3724 static_libs: ["lib4"], 3725 } 3726 3727 android_library { 3728 name: "lib4", 3729 sdk_version: "current", 3730 optimize: { 3731 proguard_flags_files: ["lib4proguard.cfg"], 3732 } 3733 } 3734 3735 3736 `) 3737 3738 m := ctx.ModuleForTests("foo", "android_common") 3739 r8 := m.Rule("java.r8") 3740 implicits := r8.Implicits.RelativeToTop().Strings() 3741 android.AssertStringListContains(t, "r8 implicits", implicits, "lib1proguard.cfg") 3742 android.AssertStringListContains(t, "r8 implicits", implicits, "lib2proguard.cfg") 3743 android.AssertStringListContains(t, "r8 implicits", implicits, "lib4proguard.cfg") 3744 android.AssertStringListContains(t, "r8 implicits", implicits, "out/soong/.intermediates/lib3/android_common/aar/proguard.txt") 3745 3746 flags := r8.Args["r8Flags"] 3747 android.AssertStringDoesContain(t, "r8 flags", flags, "-include lib1proguard.cfg") 3748 android.AssertStringDoesContain(t, "r8 flags", flags, "-include lib2proguard.cfg") 3749 android.AssertStringDoesContain(t, "r8 flags", flags, "-include lib4proguard.cfg") 3750 android.AssertStringDoesContain(t, "r8 flags", flags, "-include out/soong/.intermediates/lib3/android_common/aar/proguard.txt") 3751} 3752 3753func TestTargetSdkVersionManifestFixer(t *testing.T) { 3754 platform_sdk_codename := "Tiramisu" 3755 platform_sdk_version := 33 3756 testCases := []struct { 3757 name string 3758 targetSdkVersionInBp string 3759 targetSdkVersionExpected string 3760 unbundledBuild bool 3761 platformSdkFinal bool 3762 }{ 3763 { 3764 name: "Non-Unbundled build: Android.bp has targetSdkVersion", 3765 targetSdkVersionInBp: "30", 3766 targetSdkVersionExpected: "30", 3767 unbundledBuild: false, 3768 }, 3769 { 3770 name: "Unbundled build: Android.bp has targetSdkVersion", 3771 targetSdkVersionInBp: "30", 3772 targetSdkVersionExpected: "30", 3773 unbundledBuild: true, 3774 }, 3775 { 3776 name: "Non-Unbundled build: Android.bp has targetSdkVersion equal to platform_sdk_codename", 3777 targetSdkVersionInBp: platform_sdk_codename, 3778 targetSdkVersionExpected: platform_sdk_codename, 3779 unbundledBuild: false, 3780 }, 3781 { 3782 name: "Unbundled build: Android.bp has targetSdkVersion equal to platform_sdk_codename", 3783 targetSdkVersionInBp: platform_sdk_codename, 3784 targetSdkVersionExpected: "10000", 3785 unbundledBuild: true, 3786 }, 3787 3788 { 3789 name: "Non-Unbundled build: Android.bp has no targetSdkVersion", 3790 targetSdkVersionExpected: platform_sdk_codename, 3791 unbundledBuild: false, 3792 }, 3793 { 3794 name: "Unbundled build: Android.bp has no targetSdkVersion", 3795 targetSdkVersionExpected: "10000", 3796 unbundledBuild: true, 3797 }, 3798 { 3799 name: "Bundled build in REL branches", 3800 targetSdkVersionExpected: "33", 3801 unbundledBuild: false, 3802 platformSdkFinal: true, 3803 }, 3804 } 3805 for _, testCase := range testCases { 3806 targetSdkVersionTemplate := "" 3807 if testCase.targetSdkVersionInBp != "" { 3808 targetSdkVersionTemplate = fmt.Sprintf(`target_sdk_version: "%s",`, testCase.targetSdkVersionInBp) 3809 } 3810 bp := fmt.Sprintf(` 3811 android_app { 3812 name: "foo", 3813 sdk_version: "current", 3814 %s 3815 } 3816 `, targetSdkVersionTemplate) 3817 fixture := android.GroupFixturePreparers( 3818 prepareForJavaTest, 3819 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 3820 if testCase.platformSdkFinal { 3821 variables.Platform_sdk_final = proptools.BoolPtr(true) 3822 } 3823 // explicitly set platform_sdk_codename to make the test deterministic 3824 variables.Platform_sdk_codename = &platform_sdk_codename 3825 variables.Platform_sdk_version = &platform_sdk_version 3826 variables.Platform_version_active_codenames = []string{platform_sdk_codename} 3827 // create a non-empty list if unbundledBuild==true 3828 if testCase.unbundledBuild { 3829 variables.Unbundled_build_apps = []string{"apex_a", "apex_b"} 3830 } 3831 }), 3832 ) 3833 3834 result := fixture.RunTestWithBp(t, bp) 3835 foo := result.ModuleForTests("foo", "android_common") 3836 3837 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"] 3838 android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected) 3839 } 3840} 3841 3842func TestDefaultAppTargetSdkVersionForUpdatableModules(t *testing.T) { 3843 platform_sdk_codename := "Tiramisu" 3844 platform_sdk_version := 33 3845 testCases := []struct { 3846 name string 3847 platform_sdk_final bool 3848 targetSdkVersionInBp *string 3849 targetSdkVersionExpected *string 3850 updatable bool 3851 }{ 3852 { 3853 name: "Non-Updatable Module: Android.bp has older targetSdkVersion", 3854 targetSdkVersionInBp: proptools.StringPtr("29"), 3855 targetSdkVersionExpected: proptools.StringPtr("29"), 3856 updatable: false, 3857 }, 3858 { 3859 name: "Updatable Module: Android.bp has older targetSdkVersion", 3860 targetSdkVersionInBp: proptools.StringPtr("30"), 3861 targetSdkVersionExpected: proptools.StringPtr("30"), 3862 updatable: true, 3863 }, 3864 { 3865 name: "Updatable Module: Android.bp has no targetSdkVersion", 3866 targetSdkVersionExpected: proptools.StringPtr("10000"), 3867 updatable: true, 3868 }, 3869 { 3870 name: "[SDK finalised] Non-Updatable Module: Android.bp has older targetSdkVersion", 3871 platform_sdk_final: true, 3872 targetSdkVersionInBp: proptools.StringPtr("30"), 3873 targetSdkVersionExpected: proptools.StringPtr("30"), 3874 updatable: false, 3875 }, 3876 { 3877 name: "[SDK finalised] Updatable Module: Android.bp has older targetSdkVersion", 3878 platform_sdk_final: true, 3879 targetSdkVersionInBp: proptools.StringPtr("30"), 3880 targetSdkVersionExpected: proptools.StringPtr("30"), 3881 updatable: true, 3882 }, 3883 { 3884 name: "[SDK finalised] Updatable Module: Android.bp has targetSdkVersion as platform sdk codename", 3885 platform_sdk_final: true, 3886 targetSdkVersionInBp: proptools.StringPtr(platform_sdk_codename), 3887 targetSdkVersionExpected: proptools.StringPtr("33"), 3888 updatable: true, 3889 }, 3890 { 3891 name: "[SDK finalised] Updatable Module: Android.bp has no targetSdkVersion", 3892 platform_sdk_final: true, 3893 targetSdkVersionExpected: proptools.StringPtr("33"), 3894 updatable: true, 3895 }, 3896 } 3897 for _, testCase := range testCases { 3898 targetSdkVersionTemplate := "" 3899 if testCase.targetSdkVersionInBp != nil { 3900 targetSdkVersionTemplate = fmt.Sprintf(`target_sdk_version: "%s",`, *testCase.targetSdkVersionInBp) 3901 } 3902 bp := fmt.Sprintf(` 3903 android_app { 3904 name: "foo", 3905 sdk_version: "current", 3906 min_sdk_version: "29", 3907 %s 3908 updatable: %t, 3909 enforce_default_target_sdk_version: %t 3910 } 3911 `, targetSdkVersionTemplate, testCase.updatable, testCase.updatable) // enforce default target sdk version if app is updatable 3912 3913 fixture := android.GroupFixturePreparers( 3914 PrepareForTestWithJavaDefaultModules, 3915 android.PrepareForTestWithAllowMissingDependencies, 3916 android.PrepareForTestWithAndroidMk, 3917 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 3918 // explicitly set following platform variables to make the test deterministic 3919 variables.Platform_sdk_final = &testCase.platform_sdk_final 3920 variables.Platform_sdk_version = &platform_sdk_version 3921 variables.Platform_sdk_codename = &platform_sdk_codename 3922 variables.Platform_version_active_codenames = []string{platform_sdk_codename} 3923 variables.Unbundled_build = proptools.BoolPtr(true) 3924 variables.Unbundled_build_apps = []string{"sampleModule"} 3925 }), 3926 ) 3927 3928 result := fixture.RunTestWithBp(t, bp) 3929 foo := result.ModuleForTests("foo", "android_common") 3930 3931 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"] 3932 android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+*testCase.targetSdkVersionExpected) 3933 } 3934} 3935 3936func TestEnforceDefaultAppTargetSdkVersionFlag(t *testing.T) { 3937 platform_sdk_codename := "Tiramisu" 3938 platform_sdk_version := 33 3939 testCases := []struct { 3940 name string 3941 enforceDefaultTargetSdkVersion bool 3942 expectedError string 3943 platform_sdk_final bool 3944 targetSdkVersionInBp string 3945 targetSdkVersionExpected string 3946 updatable bool 3947 }{ 3948 { 3949 name: "Not enforcing Target SDK Version: Android.bp has older targetSdkVersion", 3950 enforceDefaultTargetSdkVersion: false, 3951 targetSdkVersionInBp: "29", 3952 targetSdkVersionExpected: "29", 3953 updatable: false, 3954 }, 3955 { 3956 name: "[SDK finalised] Enforce Target SDK Version: Android.bp has current targetSdkVersion", 3957 enforceDefaultTargetSdkVersion: true, 3958 platform_sdk_final: true, 3959 targetSdkVersionInBp: "current", 3960 targetSdkVersionExpected: "33", 3961 updatable: true, 3962 }, 3963 { 3964 name: "Enforce Target SDK Version: Android.bp has current targetSdkVersion", 3965 enforceDefaultTargetSdkVersion: true, 3966 platform_sdk_final: false, 3967 targetSdkVersionInBp: "current", 3968 targetSdkVersionExpected: "10000", 3969 updatable: false, 3970 }, 3971 { 3972 name: "Not enforcing Target SDK Version for Updatable app", 3973 enforceDefaultTargetSdkVersion: false, 3974 expectedError: "Updatable apps must enforce default target sdk version", 3975 targetSdkVersionInBp: "29", 3976 targetSdkVersionExpected: "29", 3977 updatable: true, 3978 }, 3979 } 3980 for _, testCase := range testCases { 3981 errExpected := testCase.expectedError != "" 3982 bp := fmt.Sprintf(` 3983 android_app { 3984 name: "foo", 3985 enforce_default_target_sdk_version: %t, 3986 sdk_version: "current", 3987 min_sdk_version: "29", 3988 target_sdk_version: "%v", 3989 updatable: %t 3990 } 3991 `, testCase.enforceDefaultTargetSdkVersion, testCase.targetSdkVersionInBp, testCase.updatable) 3992 3993 fixture := android.GroupFixturePreparers( 3994 PrepareForTestWithJavaDefaultModules, 3995 android.PrepareForTestWithAllowMissingDependencies, 3996 android.PrepareForTestWithAndroidMk, 3997 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 3998 // explicitly set following platform variables to make the test deterministic 3999 variables.Platform_sdk_final = &testCase.platform_sdk_final 4000 variables.Platform_sdk_version = &platform_sdk_version 4001 variables.Platform_sdk_codename = &platform_sdk_codename 4002 variables.Unbundled_build = proptools.BoolPtr(true) 4003 variables.Unbundled_build_apps = []string{"sampleModule"} 4004 }), 4005 ) 4006 4007 errorHandler := android.FixtureExpectsNoErrors 4008 if errExpected { 4009 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.expectedError) 4010 } 4011 result := fixture.ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, bp) 4012 4013 if !errExpected { 4014 foo := result.ModuleForTests("foo", "android_common") 4015 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"] 4016 android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected) 4017 } 4018 } 4019} 4020 4021func TestEnforceDefaultAppTargetSdkVersionFlagForTests(t *testing.T) { 4022 platform_sdk_codename := "Tiramisu" 4023 platform_sdk_version := 33 4024 testCases := []struct { 4025 name string 4026 enforceDefaultTargetSdkVersion bool 4027 expectedError string 4028 platform_sdk_final bool 4029 targetSdkVersionInBp string 4030 targetSdkVersionExpected string 4031 }{ 4032 { 4033 name: "Not enforcing Target SDK Version: Android.bp has older targetSdkVersion", 4034 enforceDefaultTargetSdkVersion: false, 4035 targetSdkVersionInBp: "29", 4036 targetSdkVersionExpected: "29", 4037 }, 4038 { 4039 name: "[SDK finalised] Enforce Target SDK Version: Android.bp has current targetSdkVersion", 4040 enforceDefaultTargetSdkVersion: true, 4041 platform_sdk_final: true, 4042 targetSdkVersionInBp: "current", 4043 targetSdkVersionExpected: "33", 4044 }, 4045 { 4046 name: "Enforce Target SDK Version: Android.bp has current targetSdkVersion", 4047 enforceDefaultTargetSdkVersion: true, 4048 platform_sdk_final: false, 4049 targetSdkVersionInBp: "current", 4050 targetSdkVersionExpected: "10000", 4051 }, 4052 } 4053 for _, testCase := range testCases { 4054 errExpected := testCase.expectedError != "" 4055 bp := fmt.Sprintf(` 4056 android_test { 4057 name: "foo", 4058 enforce_default_target_sdk_version: %t, 4059 min_sdk_version: "29", 4060 target_sdk_version: "%v", 4061 } 4062 `, testCase.enforceDefaultTargetSdkVersion, testCase.targetSdkVersionInBp) 4063 4064 fixture := android.GroupFixturePreparers( 4065 PrepareForTestWithJavaDefaultModules, 4066 android.PrepareForTestWithAllowMissingDependencies, 4067 android.PrepareForTestWithAndroidMk, 4068 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 4069 // explicitly set following platform variables to make the test deterministic 4070 variables.Platform_sdk_final = &testCase.platform_sdk_final 4071 variables.Platform_sdk_version = &platform_sdk_version 4072 variables.Platform_sdk_codename = &platform_sdk_codename 4073 variables.Unbundled_build = proptools.BoolPtr(true) 4074 variables.Unbundled_build_apps = []string{"sampleModule"} 4075 }), 4076 ) 4077 4078 errorHandler := android.FixtureExpectsNoErrors 4079 if errExpected { 4080 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.expectedError) 4081 } 4082 result := fixture.ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, bp) 4083 4084 if !errExpected { 4085 foo := result.ModuleForTests("foo", "android_common") 4086 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"] 4087 android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected) 4088 } 4089 } 4090} 4091 4092func TestAppMissingCertificateAllowMissingDependencies(t *testing.T) { 4093 result := android.GroupFixturePreparers( 4094 PrepareForTestWithJavaDefaultModules, 4095 android.PrepareForTestWithAllowMissingDependencies, 4096 android.PrepareForTestWithAndroidMk, 4097 ).RunTestWithBp(t, ` 4098 android_app { 4099 name: "foo", 4100 srcs: ["a.java"], 4101 certificate: ":missing_certificate", 4102 sdk_version: "current", 4103 } 4104 4105 android_app { 4106 name: "bar", 4107 srcs: ["a.java"], 4108 certificate: ":missing_certificate", 4109 product_specific: true, 4110 sdk_version: "current", 4111 }`) 4112 4113 foo := result.ModuleForTests("foo", "android_common") 4114 fooApk := foo.Output("foo.apk") 4115 if fooApk.Rule != android.ErrorRule { 4116 t.Fatalf("expected ErrorRule for foo.apk, got %s", fooApk.Rule.String()) 4117 } 4118 android.AssertStringDoesContain(t, "expected error rule message", fooApk.Args["error"], "missing dependencies: missing_certificate\n") 4119} 4120 4121func TestAppIncludesJniPackages(t *testing.T) { 4122 ctx := android.GroupFixturePreparers( 4123 PrepareForTestWithJavaDefaultModules, 4124 ).RunTestWithBp(t, ` 4125 android_library_import { 4126 name: "aary-nodeps", 4127 aars: ["aary.aar"], 4128 extract_jni: true, 4129 } 4130 4131 android_library { 4132 name: "aary-lib", 4133 sdk_version: "current", 4134 min_sdk_version: "21", 4135 static_libs: ["aary-nodeps"], 4136 } 4137 4138 android_app { 4139 name: "aary-lib-dep", 4140 sdk_version: "current", 4141 min_sdk_version: "21", 4142 manifest: "AndroidManifest.xml", 4143 static_libs: ["aary-lib"], 4144 use_embedded_native_libs: true, 4145 } 4146 4147 android_app { 4148 name: "aary-import-dep", 4149 sdk_version: "current", 4150 min_sdk_version: "21", 4151 manifest: "AndroidManifest.xml", 4152 static_libs: ["aary-nodeps"], 4153 use_embedded_native_libs: true, 4154 } 4155 4156 android_app { 4157 name: "aary-no-use-embedded", 4158 sdk_version: "current", 4159 min_sdk_version: "21", 4160 manifest: "AndroidManifest.xml", 4161 static_libs: ["aary-nodeps"], 4162 }`) 4163 4164 testCases := []struct { 4165 name string 4166 hasPackage bool 4167 }{ 4168 { 4169 name: "aary-import-dep", 4170 hasPackage: true, 4171 }, 4172 { 4173 name: "aary-lib-dep", 4174 hasPackage: true, 4175 }, 4176 { 4177 name: "aary-no-use-embedded", 4178 hasPackage: false, 4179 }, 4180 } 4181 4182 for _, tc := range testCases { 4183 t.Run(tc.name, func(t *testing.T) { 4184 app := ctx.ModuleForTests(tc.name, "android_common") 4185 4186 outputFile := "jnilibs.zip" 4187 jniOutputLibZip := app.MaybeOutput(outputFile) 4188 if jniOutputLibZip.Rule == nil && !tc.hasPackage { 4189 return 4190 } 4191 4192 jniPackage := "arm64-v8a_jni.zip" 4193 inputs := jniOutputLibZip.Inputs 4194 foundPackage := false 4195 for i := 0; i < len(inputs); i++ { 4196 if strings.Contains(inputs[i].String(), jniPackage) { 4197 foundPackage = true 4198 } 4199 } 4200 if foundPackage != tc.hasPackage { 4201 t.Errorf("expected to find %v in %v inputs; inputs = %v", jniPackage, outputFile, inputs) 4202 } 4203 }) 4204 } 4205} 4206 4207func TestTargetSdkVersionMtsTests(t *testing.T) { 4208 platformSdkCodename := "Tiramisu" 4209 android_test := "android_test" 4210 android_test_helper_app := "android_test_helper_app" 4211 bpTemplate := ` 4212 %v { 4213 name: "mytest", 4214 min_sdk_version: "34", 4215 target_sdk_version: "%v", 4216 test_suites: ["othersuite", "%v"], 4217 } 4218 ` 4219 testCases := []struct { 4220 desc string 4221 moduleType string 4222 targetSdkVersionInBp string 4223 targetSdkVersionExpected string 4224 testSuites string 4225 }{ 4226 { 4227 desc: "Non-MTS android_test_apps targeting current should not be upgraded to 10000", 4228 moduleType: android_test, 4229 targetSdkVersionInBp: "current", 4230 targetSdkVersionExpected: platformSdkCodename, 4231 testSuites: "non-mts-suite", 4232 }, 4233 { 4234 desc: "MTS android_test_apps targeting released sdks should not be upgraded to 10000", 4235 moduleType: android_test, 4236 targetSdkVersionInBp: "29", 4237 targetSdkVersionExpected: "29", 4238 testSuites: "mts-suite", 4239 }, 4240 { 4241 desc: "MTS android_test_apps targeting current should be upgraded to 10000", 4242 moduleType: android_test, 4243 targetSdkVersionInBp: "current", 4244 targetSdkVersionExpected: "10000", 4245 testSuites: "mts-suite", 4246 }, 4247 { 4248 desc: "MTS android_test_helper_apps targeting current should be upgraded to 10000", 4249 moduleType: android_test_helper_app, 4250 targetSdkVersionInBp: "current", 4251 targetSdkVersionExpected: "10000", 4252 testSuites: "mts-suite", 4253 }, 4254 } 4255 fixture := android.GroupFixturePreparers( 4256 prepareForJavaTest, 4257 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 4258 variables.Platform_sdk_codename = &platformSdkCodename 4259 variables.Platform_version_active_codenames = []string{platformSdkCodename} 4260 }), 4261 ) 4262 for _, testCase := range testCases { 4263 result := fixture.RunTestWithBp(t, fmt.Sprintf(bpTemplate, testCase.moduleType, testCase.targetSdkVersionInBp, testCase.testSuites)) 4264 mytest := result.ModuleForTests("mytest", "android_common") 4265 manifestFixerArgs := mytest.Output("manifest_fixer/AndroidManifest.xml").Args["args"] 4266 android.AssertStringDoesContain(t, testCase.desc, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected) 4267 } 4268} 4269 4270func TestPrivappAllowlist(t *testing.T) { 4271 testJavaError(t, "privileged must be set in order to use privapp_allowlist", ` 4272 android_app { 4273 name: "foo", 4274 srcs: ["a.java"], 4275 privapp_allowlist: "perms.xml", 4276 } 4277 `) 4278 4279 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp( 4280 t, 4281 ` 4282 android_app { 4283 name: "foo", 4284 srcs: ["a.java"], 4285 privapp_allowlist: "privapp_allowlist_com.android.foo.xml", 4286 privileged: true, 4287 sdk_version: "current", 4288 } 4289 override_android_app { 4290 name: "bar", 4291 base: "foo", 4292 package_name: "com.google.android.foo", 4293 } 4294 `, 4295 ) 4296 app := result.ModuleForTests("foo", "android_common") 4297 overrideApp := result.ModuleForTests("foo", "android_common_bar") 4298 4299 // verify that privapp allowlist is created for override apps 4300 overrideApp.Output("out/soong/.intermediates/foo/android_common_bar/privapp_allowlist_com.google.android.foo.xml") 4301 expectedAllowlistInput := "privapp_allowlist_com.android.foo.xml" 4302 overrideActualAllowlistInput := overrideApp.Rule("modifyAllowlist").Input.String() 4303 if expectedAllowlistInput != overrideActualAllowlistInput { 4304 t.Errorf("expected override allowlist to be %q; got %q", expectedAllowlistInput, overrideActualAllowlistInput) 4305 } 4306 4307 // verify that permissions are copied to device 4308 app.Output("out/soong/target/product/test_device/system/etc/permissions/foo.xml") 4309 overrideApp.Output("out/soong/target/product/test_device/system/etc/permissions/bar.xml") 4310} 4311 4312func TestPrivappAllowlistAndroidMk(t *testing.T) { 4313 result := android.GroupFixturePreparers( 4314 PrepareForTestWithJavaDefaultModules, 4315 android.PrepareForTestWithAndroidMk, 4316 ).RunTestWithBp( 4317 t, 4318 ` 4319 android_app { 4320 name: "foo", 4321 srcs: ["a.java"], 4322 privapp_allowlist: "privapp_allowlist_com.android.foo.xml", 4323 privileged: true, 4324 sdk_version: "current", 4325 } 4326 override_android_app { 4327 name: "bar", 4328 base: "foo", 4329 package_name: "com.google.android.foo", 4330 } 4331 `, 4332 ) 4333 baseApp := result.ModuleForTests("foo", "android_common") 4334 overrideApp := result.ModuleForTests("foo", "android_common_bar") 4335 4336 baseAndroidApp := baseApp.Module().(*AndroidApp) 4337 baseEntries := android.AndroidMkEntriesForTest(t, result.TestContext, baseAndroidApp)[0] 4338 android.AssertStringMatches( 4339 t, 4340 "androidmk has incorrect LOCAL_SOONG_INSTALLED_MODULE; expected to find foo.apk", 4341 baseEntries.EntryMap["LOCAL_SOONG_INSTALLED_MODULE"][0], 4342 "\\S+foo.apk", 4343 ) 4344 android.AssertStringMatches( 4345 t, 4346 "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include foo.apk", 4347 baseEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0], 4348 "\\S+foo.apk", 4349 ) 4350 android.AssertStringMatches( 4351 t, 4352 "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include app", 4353 baseEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0], 4354 "\\S+foo.apk:\\S+/target/product/test_device/system/priv-app/foo/foo.apk", 4355 ) 4356 android.AssertStringMatches( 4357 t, 4358 "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include privapp_allowlist", 4359 baseEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0], 4360 "privapp_allowlist_com.android.foo.xml:\\S+/target/product/test_device/system/etc/permissions/foo.xml", 4361 ) 4362 4363 overrideAndroidApp := overrideApp.Module().(*AndroidApp) 4364 overrideEntries := android.AndroidMkEntriesForTest(t, result.TestContext, overrideAndroidApp)[0] 4365 android.AssertStringMatches( 4366 t, 4367 "androidmk has incorrect LOCAL_SOONG_INSTALLED_MODULE; expected to find bar.apk", 4368 overrideEntries.EntryMap["LOCAL_SOONG_INSTALLED_MODULE"][0], 4369 "\\S+bar.apk", 4370 ) 4371 android.AssertStringMatches( 4372 t, 4373 "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include bar.apk", 4374 overrideEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0], 4375 "\\S+bar.apk", 4376 ) 4377 android.AssertStringMatches( 4378 t, 4379 "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include app", 4380 overrideEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0], 4381 "\\S+bar.apk:\\S+/target/product/test_device/system/priv-app/bar/bar.apk", 4382 ) 4383 android.AssertStringMatches( 4384 t, 4385 "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include privapp_allowlist", 4386 overrideEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0], 4387 "\\S+soong/.intermediates/foo/android_common_bar/privapp_allowlist_com.google.android.foo.xml:\\S+/target/product/test_device/system/etc/permissions/bar.xml", 4388 ) 4389} 4390 4391func TestAppFlagsPackages(t *testing.T) { 4392 ctx := android.GroupFixturePreparers( 4393 prepareForJavaTest, 4394 android.FixtureMergeMockFs( 4395 map[string][]byte{ 4396 "res/layout/layout.xml": nil, 4397 "res/values/strings.xml": nil, 4398 "res/values-en-rUS/strings.xml": nil, 4399 }, 4400 ), 4401 ).RunTestWithBp(t, ` 4402 android_app { 4403 name: "foo", 4404 srcs: ["a.java"], 4405 sdk_version: "current", 4406 flags_packages: [ 4407 "bar", 4408 "baz", 4409 ], 4410 } 4411 aconfig_declarations { 4412 name: "bar", 4413 package: "com.example.package.bar", 4414 container: "com.android.foo", 4415 srcs: [ 4416 "bar.aconfig", 4417 ], 4418 } 4419 aconfig_declarations { 4420 name: "baz", 4421 package: "com.example.package.baz", 4422 container: "com.android.foo", 4423 srcs: [ 4424 "baz.aconfig", 4425 ], 4426 } 4427 `) 4428 4429 foo := ctx.ModuleForTests("foo", "android_common") 4430 4431 // android_app module depends on aconfig_declarations listed in flags_packages 4432 android.AssertBoolEquals(t, "foo expected to depend on bar", true, 4433 CheckModuleHasDependency(t, ctx.TestContext, "foo", "android_common", "bar")) 4434 4435 android.AssertBoolEquals(t, "foo expected to depend on baz", true, 4436 CheckModuleHasDependency(t, ctx.TestContext, "foo", "android_common", "baz")) 4437 4438 aapt2LinkRule := foo.Rule("android/soong/java.aapt2Link") 4439 linkInFlags := aapt2LinkRule.Args["inFlags"] 4440 android.AssertStringDoesContain(t, 4441 "aapt2 link command expected to pass feature flags arguments", 4442 linkInFlags, 4443 "--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt", 4444 ) 4445 4446 aapt2CompileRule := foo.Rule("android/soong/java.aapt2Compile") 4447 compileFlags := aapt2CompileRule.Args["cFlags"] 4448 android.AssertStringDoesContain(t, 4449 "aapt2 compile command expected to pass feature flags arguments", 4450 compileFlags, 4451 "--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt", 4452 ) 4453} 4454 4455func TestAppFlagsPackagesPropagation(t *testing.T) { 4456 ctx := testApp(t, ` 4457 aconfig_declarations { 4458 name: "foo", 4459 package: "com.example.package.foo", 4460 container: "com.android.foo", 4461 srcs: [ 4462 "foo.aconfig", 4463 ], 4464 } 4465 aconfig_declarations { 4466 name: "bar", 4467 package: "com.example.package.bar", 4468 container: "com.android.bar", 4469 srcs: [ 4470 "bar.aconfig", 4471 ], 4472 } 4473 aconfig_declarations { 4474 name: "baz", 4475 package: "com.example.package.baz", 4476 container: "com.android.baz", 4477 srcs: [ 4478 "baz.aconfig", 4479 ], 4480 } 4481 android_library { 4482 name: "foo_lib", 4483 srcs: ["a.java"], 4484 sdk_version: "current", 4485 flags_packages: [ 4486 "foo", 4487 ], 4488 } 4489 android_library { 4490 name: "bar_lib", 4491 srcs: ["a.java"], 4492 sdk_version: "current", 4493 flags_packages: [ 4494 "bar", 4495 ], 4496 } 4497 android_app { 4498 name: "baz_app", 4499 srcs: ["a.java"], 4500 sdk_version: "current", 4501 flags_packages: [ 4502 "baz", 4503 ], 4504 static_libs: [ 4505 "bar_lib", 4506 ], 4507 libs: [ 4508 "foo_lib", 4509 ], 4510 } 4511 `) 4512 4513 bazApp := ctx.ModuleForTests("baz_app", "android_common") 4514 4515 // android_app module depends on aconfig_declarations listed in flags_packages 4516 // and that of static libs, but not libs 4517 aapt2LinkRule := bazApp.Rule("android/soong/java.aapt2Link") 4518 linkInFlags := aapt2LinkRule.Args["inFlags"] 4519 android.AssertStringDoesContain(t, 4520 "aapt2 link command expected to pass feature flags arguments of flags_packages and that of its static libs", 4521 linkInFlags, 4522 "--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt", 4523 ) 4524 android.AssertStringDoesNotContain(t, 4525 "aapt2 link command expected to not pass feature flags arguments of flags_packages of its libs", 4526 linkInFlags, 4527 "--feature-flags @out/soong/.intermediates/foo/intermediate.txt", 4528 ) 4529} 4530 4531// Test that dexpreopt is disabled if an optional_uses_libs exists, but does not provide an implementation. 4532func TestNoDexpreoptOptionalUsesLibDoesNotHaveImpl(t *testing.T) { 4533 bp := ` 4534 java_sdk_library_import { 4535 name: "sdklib_noimpl", 4536 public: { 4537 jars: ["stub.jar"], 4538 }, 4539 } 4540 android_app { 4541 name: "app", 4542 srcs: ["a.java"], 4543 sdk_version: "current", 4544 optional_uses_libs: [ 4545 "sdklib_noimpl", 4546 ], 4547 } 4548 ` 4549 result := prepareForJavaTest.RunTestWithBp(t, bp) 4550 dexpreopt := result.ModuleForTests("app", "android_common").MaybeRule("dexpreopt").Rule 4551 android.AssertBoolEquals(t, "dexpreopt should be disabled if optional_uses_libs does not have an implementation", true, dexpreopt == nil) 4552} 4553 4554func TestTestOnlyApp(t *testing.T) { 4555 t.Parallel() 4556 ctx := android.GroupFixturePreparers( 4557 prepareForJavaTest, 4558 ).RunTestWithBp(t, ` 4559 // These should be test-only 4560 android_test { 4561 name: "android-test", 4562 } 4563 android_test_helper_app { 4564 name: "helper-app", 4565 } 4566 override_android_test { 4567 name: "override-test", 4568 base: "android-app", 4569 } 4570 // And these should not be 4571 android_app { 4572 name: "android-app", 4573 srcs: ["b.java"], 4574 sdk_version: "current", 4575 } 4576 `) 4577 4578 expectedTestOnly := []string{ 4579 "android-test", 4580 "helper-app", 4581 "override-test", 4582 } 4583 4584 expectedTopLevel := []string{ 4585 "android-test", 4586 "override-test", 4587 } 4588 4589 assertTestOnlyAndTopLevel(t, ctx, expectedTestOnly, expectedTopLevel) 4590} 4591 4592func TestAppStem(t *testing.T) { 4593 ctx := testApp(t, ` 4594 android_app { 4595 name: "foo", 4596 srcs: ["a.java"], 4597 stem: "foo-new", 4598 sdk_version: "current", 4599 }`) 4600 4601 foo := ctx.ModuleForTests("foo", "android_common") 4602 4603 outputs := fmt.Sprint(foo.AllOutputs()) 4604 if !strings.Contains(outputs, "foo-new.apk") { 4605 t.Errorf("Module output does not contain expected apk %s", "foo-new.apk") 4606 } 4607} 4608 4609func TestAppMinSdkVersionOverride(t *testing.T) { 4610 result := android.GroupFixturePreparers( 4611 PrepareForTestWithJavaDefaultModules, 4612 ).RunTestWithBp(t, ` 4613 android_app { 4614 name: "com.android.foo", 4615 srcs: ["a.java"], 4616 sdk_version: "current", 4617 min_sdk_version: "31", 4618 updatable: true, 4619 } 4620 override_android_app { 4621 name: "com.android.go.foo", 4622 base: "com.android.foo", 4623 min_sdk_version: "33", 4624 } 4625 `) 4626 foo := result.ModuleForTests("com.android.foo", "android_common").Rule("manifestFixer") 4627 fooOverride := result.ModuleForTests("com.android.foo", "android_common_com.android.go.foo").Rule("manifestFixer") 4628 4629 android.AssertStringDoesContain(t, 4630 "com.android.foo: expected manifest fixer to set minSdkVersion to T", 4631 foo.BuildParams.Args["args"], 4632 "--minSdkVersion 31", 4633 ) 4634 android.AssertStringDoesContain(t, 4635 "com.android.go.foo: expected manifest fixer to set minSdkVersion to T", 4636 fooOverride.BuildParams.Args["args"], 4637 "--minSdkVersion 33", 4638 ) 4639 4640} 4641 4642func TestNotApplyDefaultUpdatableModuleVersion(t *testing.T) { 4643 result := android.GroupFixturePreparers( 4644 PrepareForTestWithJavaDefaultModules, 4645 ).RunTestWithBp(t, ` 4646 android_app { 4647 name: "com.android.foo", 4648 srcs: ["a.java"], 4649 sdk_version: "current", 4650 min_sdk_version: "31", 4651 } 4652 `) 4653 foo := result.ModuleForTests("com.android.foo", "android_common").Rule("manifestFixer") 4654 android.AssertStringDoesNotContain(t, 4655 "com.android.foo: expected manifest fixer to not set override-placeholder-version", 4656 foo.BuildParams.Args["args"], 4657 "--override-placeholder-version", 4658 ) 4659} 4660 4661func TestNotApplyOverrideApexManifestDefaultVersion(t *testing.T) { 4662 result := android.GroupFixturePreparers( 4663 PrepareForTestWithJavaDefaultModules, 4664 android.FixtureMergeEnv(map[string]string{ 4665 "OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION": "1234", 4666 }), 4667 ).RunTestWithBp(t, ` 4668 android_app { 4669 name: "com.android.foo", 4670 srcs: ["a.java"], 4671 sdk_version: "current", 4672 min_sdk_version: "31", 4673 } 4674 `) 4675 foo := result.ModuleForTests("com.android.foo", "android_common").Rule("manifestFixer") 4676 android.AssertStringDoesNotContain(t, 4677 "com.android.foo: expected manifest fixer to not set override-placeholder-version", 4678 foo.BuildParams.Args["args"], 4679 "--override-placeholder-version", 4680 ) 4681} 4682 4683func TestResourcesWithFlagDirectories(t *testing.T) { 4684 result := android.GroupFixturePreparers( 4685 PrepareForTestWithJavaDefaultModules, 4686 android.FixtureMergeMockFs(android.MockFS{ 4687 "res/flag(test.package.flag1)/values/bools.xml": nil, 4688 "res/flag(!test.package.flag2)/values/bools.xml": nil, 4689 "res/flag(test.package.flag1)/values-config/strings_google_services.xml": nil, 4690 "res/flags(test.package.flag1)/values/strings.xml": nil, 4691 }), 4692 ).RunTestWithBp(t, ` 4693 android_library { 4694 name: "foo", 4695 srcs: ["a.java"], 4696 use_resource_processor: true, 4697 resource_dirs: [ 4698 "res", 4699 ], 4700 } 4701 `) 4702 fooModule := result.ModuleForTests("foo", "android_common") 4703 compileOutputPaths := fooModule.Rule("aapt2Compile").Outputs.Strings() 4704 4705 android.AssertStringListContains( 4706 t, 4707 "Expected to generate flag path", 4708 compileOutputPaths, 4709 "out/soong/.intermediates/foo/android_common/aapt2/res/values_bools.(test.package.flag1).arsc.flat", 4710 ) 4711 android.AssertStringListContains( 4712 t, 4713 "Expected to generate flag path with ! prefix in name", 4714 compileOutputPaths, 4715 "out/soong/.intermediates/foo/android_common/aapt2/res/values_bools.(!test.package.flag2).arsc.flat", 4716 ) 4717 android.AssertStringListContains( 4718 t, 4719 "Expected to generate flag path with configs", 4720 compileOutputPaths, 4721 "out/soong/.intermediates/foo/android_common/aapt2/res/values-config_strings_google_services.(test.package.flag1).arsc.flat", 4722 ) 4723 android.AssertStringListDoesNotContain( 4724 t, 4725 "Expected to not generate flag path with non-flag(flag_name) pattern", 4726 compileOutputPaths, 4727 "out/soong/.intermediates/foo/android_common/aapt2/res/values_strings.(test.package.flag1).arsc.flat", 4728 ) 4729} 4730 4731func TestAutogeneratedStaticRro(t *testing.T) { 4732 t.Parallel() 4733 bp := ` 4734android_app { 4735 name: "foo", 4736 srcs: ["foo.java"], 4737 platform_apis: true, 4738} 4739override_android_app { 4740 name: "override_foo", 4741 base: "foo", 4742} 4743` 4744 testCases := []struct { 4745 desc string 4746 preparer android.FixturePreparer 4747 overlayApkExpected bool 4748 }{ 4749 { 4750 desc: "No DEVICE_PACKAGE_OVERLAYS, no overlay .apk file", 4751 overlayApkExpected: false, 4752 }, 4753 { 4754 desc: "DEVICE_PACKAGE_OVERLAYS exists, but the directory is empty", 4755 overlayApkExpected: false, 4756 preparer: android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 4757 variables.DeviceResourceOverlays = []string{"device/company/test_product"} 4758 }), 4759 }, 4760 { 4761 desc: "DEVICE_PACKAGE_OVERLAYS exists, directory is non-empty, but does not contain a matching resource dir", 4762 overlayApkExpected: false, 4763 preparer: android.GroupFixturePreparers( 4764 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 4765 variables.DeviceResourceOverlays = []string{"device/company/test_product"} 4766 }), 4767 android.MockFS{ 4768 "res/foo.xml": nil, 4769 "device/company/test_product/different_res/foo.xml": nil, // different dir 4770 }.AddToFixture(), 4771 ), 4772 }, 4773 { 4774 desc: "DEVICE_PACKAGE_OVERLAYS and the directory contain a matching resource dir", 4775 overlayApkExpected: true, 4776 preparer: android.GroupFixturePreparers( 4777 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 4778 variables.DeviceResourceOverlays = []string{"device/company/test_product"} 4779 }), 4780 android.MockFS{ 4781 "res/foo.xml": nil, 4782 "device/company/test_product/res/foo.xml": nil, 4783 }.AddToFixture(), 4784 ), 4785 }, 4786 } 4787 for _, tc := range testCases { 4788 result := android.GroupFixturePreparers( 4789 PrepareForTestWithJavaDefaultModules, 4790 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 4791 variables.EnforceRROTargets = []string{"*"} 4792 }), 4793 android.OptionalFixturePreparer(tc.preparer), 4794 ).RunTestWithBp(t, bp) 4795 vendorOverlayApk := result.ModuleForTests("foo__test_product__auto_generated_rro_vendor", "android_arm64_armv8-a").MaybeOutput("foo__test_product__auto_generated_rro_vendor.apk") 4796 android.AssertBoolEquals(t, tc.desc, tc.overlayApkExpected, vendorOverlayApk.Rule != nil) 4797 overrideVendorOverlayApk := result.ModuleForTests("override_foo__test_product__auto_generated_rro_vendor", "android_arm64_armv8-a").MaybeOutput("override_foo__test_product__auto_generated_rro_vendor.apk") 4798 android.AssertBoolEquals(t, tc.desc, tc.overlayApkExpected, overrideVendorOverlayApk.Rule != nil) 4799 } 4800} 4801 4802func TestNoAutogeneratedStaticRroForDisabledOverrideApps(t *testing.T) { 4803 t.Parallel() 4804 bp := ` 4805soong_config_module_type { 4806 name: "my_custom_override_android_app", 4807 module_type: "override_android_app", 4808 config_namespace: "my_namespace", 4809 value_variables: ["my_app_enabled"], 4810 properties: ["enabled"], 4811} 4812soong_config_bool_variable { 4813 name: "my_app_enabled", 4814} 4815android_app { 4816 name: "foo", 4817 srcs: ["foo.java"], 4818 platform_apis: true, 4819} 4820my_custom_override_android_app { 4821 name: "override_foo", 4822 base: "foo", 4823 soong_config_variables: { 4824 my_app_enabled: { 4825 enabled: true, 4826 conditions_default: { 4827 enabled: false 4828 }, 4829 }, 4830 } 4831} 4832` 4833 testCases := []struct { 4834 desc string 4835 preparer android.FixturePreparer 4836 overlayApkExpected bool 4837 }{ 4838 { 4839 desc: "my_app_enabled is empty", 4840 overlayApkExpected: false, 4841 }, 4842 { 4843 desc: "my_app_enabled is true", 4844 overlayApkExpected: true, 4845 preparer: android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 4846 variables.VendorVars = map[string]map[string]string{ 4847 "my_namespace": { 4848 "my_app_enabled": "true", 4849 }, 4850 } 4851 }), 4852 }, 4853 } 4854 for _, tc := range testCases { 4855 result := android.GroupFixturePreparers( 4856 PrepareForTestWithJavaDefaultModules, 4857 android.PrepareForTestWithSoongConfigModuleBuildComponents, 4858 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 4859 variables.EnforceRROTargets = []string{"*"} 4860 }), 4861 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 4862 variables.DeviceResourceOverlays = []string{"device/company/test_product"} 4863 }), 4864 android.MockFS{ 4865 "res/foo.xml": nil, 4866 "device/company/test_product/res/foo.xml": nil, 4867 }.AddToFixture(), 4868 android.OptionalFixturePreparer(tc.preparer), 4869 ).RunTestWithBp(t, bp) 4870 overrideVendorOverlayApk := result.ModuleForTests("override_foo__test_product__auto_generated_rro_vendor", "android_arm64_armv8-a").Module().(*AutogenRuntimeResourceOverlay) 4871 android.AssertBoolEquals(t, tc.desc, tc.overlayApkExpected, overrideVendorOverlayApk.exportPackage != nil) 4872 } 4873} 4874