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