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("partialLd").Output 447 expectedCrtEnd := ctx.ModuleForTests("crtend_so", 448 "android_arm64_armv8-a_sdk_29").Rule("partialLd").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 TestResourceDirs(t *testing.T) { 523 testCases := []struct { 524 name string 525 prop string 526 resources []string 527 }{ 528 { 529 name: "no resource_dirs", 530 prop: "", 531 resources: []string{"res/res/values/strings.xml"}, 532 }, 533 { 534 name: "resource_dirs", 535 prop: `resource_dirs: ["res"]`, 536 resources: []string{"res/res/values/strings.xml"}, 537 }, 538 { 539 name: "empty resource_dirs", 540 prop: `resource_dirs: []`, 541 resources: nil, 542 }, 543 } 544 545 fs := android.MockFS{ 546 "res/res/values/strings.xml": nil, 547 } 548 549 bp := ` 550 android_app { 551 name: "foo", 552 sdk_version: "current", 553 %s 554 } 555 ` 556 557 for _, testCase := range testCases { 558 t.Run(testCase.name, func(t *testing.T) { 559 result := android.GroupFixturePreparers( 560 PrepareForTestWithJavaDefaultModules, 561 PrepareForTestWithOverlayBuildComponents, 562 fs.AddToFixture(), 563 ).RunTestWithBp(t, fmt.Sprintf(bp, testCase.prop)) 564 565 module := result.ModuleForTests("foo", "android_common") 566 resourceList := module.MaybeOutput("aapt2/res.list") 567 568 var resources []string 569 if resourceList.Rule != nil { 570 for _, compiledResource := range resourceList.Inputs.Strings() { 571 resources = append(resources, module.Output(compiledResource).Inputs.Strings()...) 572 } 573 } 574 575 android.AssertDeepEquals(t, "resource files", testCase.resources, resources) 576 }) 577 } 578} 579 580func TestLibraryAssets(t *testing.T) { 581 bp := ` 582 android_app { 583 name: "foo", 584 sdk_version: "current", 585 static_libs: ["lib1", "lib2", "lib3"], 586 } 587 588 android_library { 589 name: "lib1", 590 sdk_version: "current", 591 asset_dirs: ["assets_a"], 592 } 593 594 android_library { 595 name: "lib2", 596 sdk_version: "current", 597 } 598 599 android_library { 600 name: "lib3", 601 sdk_version: "current", 602 static_libs: ["lib4"], 603 } 604 605 android_library { 606 name: "lib4", 607 sdk_version: "current", 608 asset_dirs: ["assets_b"], 609 } 610 ` 611 612 testCases := []struct { 613 name string 614 assetFlag string 615 assetPackages []string 616 }{ 617 { 618 name: "foo", 619 // lib1 has its own asset. lib3 doesn't have any, but provides lib4's transitively. 620 assetPackages: []string{ 621 "out/soong/.intermediates/foo/android_common/aapt2/package-res.apk", 622 "out/soong/.intermediates/lib1/android_common/assets.zip", 623 "out/soong/.intermediates/lib3/android_common/assets.zip", 624 }, 625 }, 626 { 627 name: "lib1", 628 assetFlag: "-A assets_a", 629 }, 630 { 631 name: "lib2", 632 }, 633 { 634 name: "lib3", 635 assetPackages: []string{ 636 "out/soong/.intermediates/lib3/android_common/aapt2/package-res.apk", 637 "out/soong/.intermediates/lib4/android_common/assets.zip", 638 }, 639 }, 640 { 641 name: "lib4", 642 assetFlag: "-A assets_b", 643 }, 644 } 645 ctx := testApp(t, bp) 646 647 for _, test := range testCases { 648 t.Run(test.name, func(t *testing.T) { 649 m := ctx.ModuleForTests(test.name, "android_common") 650 651 // Check asset flag in aapt2 link flags 652 var aapt2link android.TestingBuildParams 653 if len(test.assetPackages) > 0 { 654 aapt2link = m.Output("aapt2/package-res.apk") 655 } else { 656 aapt2link = m.Output("package-res.apk") 657 } 658 aapt2link = aapt2link 659 aapt2Flags := aapt2link.Args["flags"] 660 if test.assetFlag != "" { 661 android.AssertStringDoesContain(t, "asset flag", aapt2Flags, test.assetFlag) 662 } else { 663 android.AssertStringDoesNotContain(t, "aapt2 link flags", aapt2Flags, " -A ") 664 } 665 666 // Check asset merge rule. 667 if len(test.assetPackages) > 0 { 668 mergeAssets := m.Output("package-res.apk") 669 android.AssertPathsRelativeToTopEquals(t, "mergeAssets inputs", test.assetPackages, mergeAssets.Inputs) 670 } 671 }) 672 } 673} 674 675func TestAppJavaResources(t *testing.T) { 676 bp := ` 677 android_app { 678 name: "foo", 679 sdk_version: "current", 680 java_resources: ["resources/a"], 681 srcs: ["a.java"], 682 } 683 684 android_app { 685 name: "bar", 686 sdk_version: "current", 687 java_resources: ["resources/a"], 688 } 689 ` 690 691 ctx := testApp(t, bp) 692 693 foo := ctx.ModuleForTests("foo", "android_common") 694 fooResources := foo.Output("res/foo.jar") 695 fooDexJar := foo.Output("dex-withres/foo.jar") 696 fooDexJarAligned := foo.Output("dex-withres-aligned/foo.jar") 697 fooApk := foo.Rule("combineApk") 698 699 if g, w := fooDexJar.Inputs.Strings(), fooResources.Output.String(); !android.InList(w, g) { 700 t.Errorf("expected resource jar %q in foo dex jar inputs %q", w, g) 701 } 702 703 if g, w := fooDexJarAligned.Input.String(), fooDexJar.Output.String(); g != w { 704 t.Errorf("expected dex jar %q in foo aligned dex jar inputs %q", w, g) 705 } 706 707 if g, w := fooApk.Inputs.Strings(), fooDexJarAligned.Output.String(); !android.InList(w, g) { 708 t.Errorf("expected aligned dex jar %q in foo apk inputs %q", w, g) 709 } 710 711 bar := ctx.ModuleForTests("bar", "android_common") 712 barResources := bar.Output("res/bar.jar") 713 barApk := bar.Rule("combineApk") 714 715 if g, w := barApk.Inputs.Strings(), barResources.Output.String(); !android.InList(w, g) { 716 t.Errorf("expected resources jar %q in bar apk inputs %q", w, g) 717 } 718} 719 720func TestAndroidResources(t *testing.T) { 721 testCases := []struct { 722 name string 723 enforceRROTargets []string 724 enforceRROExcludedOverlays []string 725 resourceFiles map[string][]string 726 overlayFiles map[string][]string 727 rroDirs map[string][]string 728 }{ 729 { 730 name: "no RRO", 731 enforceRROTargets: nil, 732 enforceRROExcludedOverlays: nil, 733 resourceFiles: map[string][]string{ 734 "foo": nil, 735 "bar": {"bar/res/res/values/strings.xml"}, 736 "lib": nil, 737 "lib2": {"lib2/res/res/values/strings.xml"}, 738 }, 739 overlayFiles: map[string][]string{ 740 "foo": { 741 "out/soong/.intermediates/lib2/android_common/package-res.apk", 742 "out/soong/.intermediates/lib/android_common/package-res.apk", 743 "out/soong/.intermediates/lib3/android_common/package-res.apk", 744 "foo/res/res/values/strings.xml", 745 "device/vendor/blah/static_overlay/foo/res/values/strings.xml", 746 "device/vendor/blah/overlay/foo/res/values/strings.xml", 747 "product/vendor/blah/overlay/foo/res/values/strings.xml", 748 }, 749 "bar": { 750 "device/vendor/blah/static_overlay/bar/res/values/strings.xml", 751 "device/vendor/blah/overlay/bar/res/values/strings.xml", 752 }, 753 "lib": { 754 "out/soong/.intermediates/lib2/android_common/package-res.apk", 755 "lib/res/res/values/strings.xml", 756 "device/vendor/blah/overlay/lib/res/values/strings.xml", 757 }, 758 }, 759 rroDirs: map[string][]string{ 760 "foo": nil, 761 "bar": nil, 762 }, 763 }, 764 { 765 name: "enforce RRO on foo", 766 enforceRROTargets: []string{"foo"}, 767 enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"}, 768 resourceFiles: map[string][]string{ 769 "foo": nil, 770 "bar": {"bar/res/res/values/strings.xml"}, 771 "lib": nil, 772 "lib2": {"lib2/res/res/values/strings.xml"}, 773 }, 774 overlayFiles: map[string][]string{ 775 "foo": { 776 "out/soong/.intermediates/lib2/android_common/package-res.apk", 777 "out/soong/.intermediates/lib/android_common/package-res.apk", 778 "out/soong/.intermediates/lib3/android_common/package-res.apk", 779 "foo/res/res/values/strings.xml", 780 "device/vendor/blah/static_overlay/foo/res/values/strings.xml", 781 }, 782 "bar": { 783 "device/vendor/blah/static_overlay/bar/res/values/strings.xml", 784 "device/vendor/blah/overlay/bar/res/values/strings.xml", 785 }, 786 "lib": { 787 "out/soong/.intermediates/lib2/android_common/package-res.apk", 788 "lib/res/res/values/strings.xml", 789 }, 790 }, 791 792 rroDirs: map[string][]string{ 793 "foo": { 794 "device:device/vendor/blah/overlay/foo/res", 795 "product:product/vendor/blah/overlay/foo/res", 796 "device:device/vendor/blah/overlay/lib/res", 797 }, 798 "bar": nil, 799 "lib": {"device:device/vendor/blah/overlay/lib/res"}, 800 }, 801 }, 802 { 803 name: "enforce RRO on all", 804 enforceRROTargets: []string{"*"}, 805 enforceRROExcludedOverlays: []string{ 806 // Excluding specific apps/res directories also allowed. 807 "device/vendor/blah/static_overlay/foo", 808 "device/vendor/blah/static_overlay/bar/res", 809 }, 810 resourceFiles: map[string][]string{ 811 "foo": nil, 812 "bar": {"bar/res/res/values/strings.xml"}, 813 "lib": nil, 814 "lib2": {"lib2/res/res/values/strings.xml"}, 815 }, 816 overlayFiles: map[string][]string{ 817 "foo": { 818 "out/soong/.intermediates/lib2/android_common/package-res.apk", 819 "out/soong/.intermediates/lib/android_common/package-res.apk", 820 "out/soong/.intermediates/lib3/android_common/package-res.apk", 821 "foo/res/res/values/strings.xml", 822 "device/vendor/blah/static_overlay/foo/res/values/strings.xml", 823 }, 824 "bar": {"device/vendor/blah/static_overlay/bar/res/values/strings.xml"}, 825 "lib": { 826 "out/soong/.intermediates/lib2/android_common/package-res.apk", 827 "lib/res/res/values/strings.xml", 828 }, 829 }, 830 rroDirs: map[string][]string{ 831 "foo": { 832 "device:device/vendor/blah/overlay/foo/res", 833 "product:product/vendor/blah/overlay/foo/res", 834 // Lib dep comes after the direct deps 835 "device:device/vendor/blah/overlay/lib/res", 836 }, 837 "bar": {"device:device/vendor/blah/overlay/bar/res"}, 838 "lib": {"device:device/vendor/blah/overlay/lib/res"}, 839 }, 840 }, 841 } 842 843 deviceResourceOverlays := []string{ 844 "device/vendor/blah/overlay", 845 "device/vendor/blah/overlay2", 846 "device/vendor/blah/static_overlay", 847 } 848 849 productResourceOverlays := []string{ 850 "product/vendor/blah/overlay", 851 } 852 853 fs := android.MockFS{ 854 "foo/res/res/values/strings.xml": nil, 855 "bar/res/res/values/strings.xml": nil, 856 "lib/res/res/values/strings.xml": nil, 857 "lib2/res/res/values/strings.xml": nil, 858 "device/vendor/blah/overlay/foo/res/values/strings.xml": nil, 859 "device/vendor/blah/overlay/bar/res/values/strings.xml": nil, 860 "device/vendor/blah/overlay/lib/res/values/strings.xml": nil, 861 "device/vendor/blah/static_overlay/foo/res/values/strings.xml": nil, 862 "device/vendor/blah/static_overlay/bar/res/values/strings.xml": nil, 863 "device/vendor/blah/overlay2/res/values/strings.xml": nil, 864 "product/vendor/blah/overlay/foo/res/values/strings.xml": nil, 865 } 866 867 bp := ` 868 android_app { 869 name: "foo", 870 sdk_version: "current", 871 resource_dirs: ["foo/res"], 872 static_libs: ["lib", "lib3"], 873 } 874 875 android_app { 876 name: "bar", 877 sdk_version: "current", 878 resource_dirs: ["bar/res"], 879 } 880 881 android_library { 882 name: "lib", 883 sdk_version: "current", 884 resource_dirs: ["lib/res"], 885 static_libs: ["lib2"], 886 } 887 888 android_library { 889 name: "lib2", 890 sdk_version: "current", 891 resource_dirs: ["lib2/res"], 892 } 893 894 // This library has the same resources as lib (should not lead to dupe RROs) 895 android_library { 896 name: "lib3", 897 sdk_version: "current", 898 resource_dirs: ["lib/res"] 899 } 900 ` 901 902 for _, testCase := range testCases { 903 t.Run(testCase.name, func(t *testing.T) { 904 result := android.GroupFixturePreparers( 905 PrepareForTestWithJavaDefaultModules, 906 PrepareForTestWithOverlayBuildComponents, 907 fs.AddToFixture(), 908 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 909 variables.DeviceResourceOverlays = deviceResourceOverlays 910 variables.ProductResourceOverlays = productResourceOverlays 911 if testCase.enforceRROTargets != nil { 912 variables.EnforceRROTargets = testCase.enforceRROTargets 913 } 914 if testCase.enforceRROExcludedOverlays != nil { 915 variables.EnforceRROExcludedOverlays = testCase.enforceRROExcludedOverlays 916 } 917 }), 918 ).RunTestWithBp(t, bp) 919 920 resourceListToFiles := func(module android.TestingModule, list []string) (files []string) { 921 for _, o := range list { 922 res := module.MaybeOutput(o) 923 if res.Rule != nil { 924 // If the overlay is compiled as part of this module (i.e. a .arsc.flat file), 925 // verify the inputs to the .arsc.flat rule. 926 files = append(files, res.Inputs.Strings()...) 927 } else { 928 // Otherwise, verify the full path to the output of the other module 929 files = append(files, o) 930 } 931 } 932 return files 933 } 934 935 getResources := func(moduleName string) (resourceFiles, overlayFiles, rroDirs []string) { 936 module := result.ModuleForTests(moduleName, "android_common") 937 resourceList := module.MaybeOutput("aapt2/res.list") 938 if resourceList.Rule != nil { 939 resourceFiles = resourceListToFiles(module, android.PathsRelativeToTop(resourceList.Inputs)) 940 } 941 overlayList := module.MaybeOutput("aapt2/overlay.list") 942 if overlayList.Rule != nil { 943 overlayFiles = resourceListToFiles(module, android.PathsRelativeToTop(overlayList.Inputs)) 944 } 945 946 for _, d := range module.Module().(AndroidLibraryDependency).ExportedRRODirs() { 947 var prefix string 948 if d.overlayType == device { 949 prefix = "device:" 950 } else if d.overlayType == product { 951 prefix = "product:" 952 } else { 953 t.Fatalf("Unexpected overlayType %d", d.overlayType) 954 } 955 rroDirs = append(rroDirs, prefix+android.PathRelativeToTop(d.path)) 956 } 957 958 return resourceFiles, overlayFiles, rroDirs 959 } 960 961 modules := []string{"foo", "bar", "lib", "lib2"} 962 for _, module := range modules { 963 resourceFiles, overlayFiles, rroDirs := getResources(module) 964 965 if !reflect.DeepEqual(resourceFiles, testCase.resourceFiles[module]) { 966 t.Errorf("expected %s resource files:\n %#v\n got:\n %#v", 967 module, testCase.resourceFiles[module], resourceFiles) 968 } 969 if !reflect.DeepEqual(overlayFiles, testCase.overlayFiles[module]) { 970 t.Errorf("expected %s overlay files:\n %#v\n got:\n %#v", 971 module, testCase.overlayFiles[module], overlayFiles) 972 } 973 if !reflect.DeepEqual(rroDirs, testCase.rroDirs[module]) { 974 t.Errorf("expected %s rroDirs: %#v\n got:\n %#v", 975 module, testCase.rroDirs[module], rroDirs) 976 } 977 } 978 }) 979 } 980} 981 982func checkSdkVersion(t *testing.T, result *android.TestResult, expectedSdkVersion string) { 983 foo := result.ModuleForTests("foo", "android_common") 984 link := foo.Output("package-res.apk") 985 linkFlags := strings.Split(link.Args["flags"], " ") 986 min := android.IndexList("--min-sdk-version", linkFlags) 987 target := android.IndexList("--target-sdk-version", linkFlags) 988 989 if min == -1 || target == -1 || min == len(linkFlags)-1 || target == len(linkFlags)-1 { 990 t.Fatalf("missing --min-sdk-version or --target-sdk-version in link flags: %q", linkFlags) 991 } 992 993 gotMinSdkVersion := linkFlags[min+1] 994 gotTargetSdkVersion := linkFlags[target+1] 995 996 android.AssertStringEquals(t, "incorrect --min-sdk-version", expectedSdkVersion, gotMinSdkVersion) 997 998 android.AssertStringEquals(t, "incorrect --target-sdk-version", expectedSdkVersion, gotTargetSdkVersion) 999} 1000 1001func TestAppSdkVersion(t *testing.T) { 1002 testCases := []struct { 1003 name string 1004 sdkVersion string 1005 platformSdkInt int 1006 platformSdkCodename string 1007 platformSdkFinal bool 1008 minSdkVersionBp string 1009 expectedMinSdkVersion string 1010 platformApis bool 1011 activeCodenames []string 1012 }{ 1013 { 1014 name: "current final SDK", 1015 sdkVersion: "current", 1016 platformSdkInt: 27, 1017 platformSdkCodename: "REL", 1018 platformSdkFinal: true, 1019 expectedMinSdkVersion: "27", 1020 }, 1021 { 1022 name: "current non-final SDK", 1023 sdkVersion: "current", 1024 platformSdkInt: 27, 1025 platformSdkCodename: "OMR1", 1026 platformSdkFinal: false, 1027 expectedMinSdkVersion: "OMR1", 1028 activeCodenames: []string{"OMR1"}, 1029 }, 1030 { 1031 name: "default final SDK", 1032 sdkVersion: "", 1033 platformApis: true, 1034 platformSdkInt: 27, 1035 platformSdkCodename: "REL", 1036 platformSdkFinal: true, 1037 expectedMinSdkVersion: "27", 1038 }, 1039 { 1040 name: "default non-final SDK", 1041 sdkVersion: "", 1042 platformApis: true, 1043 platformSdkInt: 27, 1044 platformSdkCodename: "OMR1", 1045 platformSdkFinal: false, 1046 expectedMinSdkVersion: "OMR1", 1047 activeCodenames: []string{"OMR1"}, 1048 }, 1049 { 1050 name: "14", 1051 sdkVersion: "14", 1052 expectedMinSdkVersion: "14", 1053 platformSdkCodename: "S", 1054 activeCodenames: []string{"S"}, 1055 }, 1056 { 1057 name: "two active SDKs", 1058 sdkVersion: "module_current", 1059 minSdkVersionBp: "UpsideDownCake", 1060 expectedMinSdkVersion: "UpsideDownCake", // And not VanillaIceCream 1061 platformSdkCodename: "VanillaIceCream", 1062 activeCodenames: []string{"UpsideDownCake", "VanillaIceCream"}, 1063 }, 1064 } 1065 1066 for _, moduleType := range []string{"android_app", "android_library"} { 1067 for _, test := range testCases { 1068 t.Run(moduleType+" "+test.name, func(t *testing.T) { 1069 platformApiProp := "" 1070 if test.platformApis { 1071 platformApiProp = "platform_apis: true," 1072 } 1073 minSdkVersionProp := "" 1074 if test.minSdkVersionBp != "" { 1075 minSdkVersionProp = fmt.Sprintf(` min_sdk_version: "%s",`, test.minSdkVersionBp) 1076 } 1077 bp := fmt.Sprintf(`%s { 1078 name: "foo", 1079 srcs: ["a.java"], 1080 sdk_version: "%s", 1081 %s 1082 %s 1083 }`, moduleType, test.sdkVersion, platformApiProp, minSdkVersionProp) 1084 1085 result := android.GroupFixturePreparers( 1086 prepareForJavaTest, 1087 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1088 variables.Platform_sdk_version = &test.platformSdkInt 1089 variables.Platform_sdk_codename = &test.platformSdkCodename 1090 variables.Platform_version_active_codenames = test.activeCodenames 1091 variables.Platform_sdk_final = &test.platformSdkFinal 1092 }), 1093 FixtureWithPrebuiltApis(map[string][]string{ 1094 "14": {"foo"}, 1095 }), 1096 ).RunTestWithBp(t, bp) 1097 1098 checkSdkVersion(t, result, test.expectedMinSdkVersion) 1099 }) 1100 } 1101 } 1102} 1103 1104func TestVendorAppSdkVersion(t *testing.T) { 1105 testCases := []struct { 1106 name string 1107 sdkVersion string 1108 platformSdkInt int 1109 platformSdkCodename string 1110 platformSdkFinal bool 1111 deviceCurrentApiLevelForVendorModules string 1112 expectedMinSdkVersion string 1113 }{ 1114 { 1115 name: "current final SDK", 1116 sdkVersion: "current", 1117 platformSdkInt: 29, 1118 platformSdkCodename: "REL", 1119 platformSdkFinal: true, 1120 deviceCurrentApiLevelForVendorModules: "29", 1121 expectedMinSdkVersion: "29", 1122 }, 1123 { 1124 name: "current final SDK", 1125 sdkVersion: "current", 1126 platformSdkInt: 29, 1127 platformSdkCodename: "REL", 1128 platformSdkFinal: true, 1129 deviceCurrentApiLevelForVendorModules: "28", 1130 expectedMinSdkVersion: "28", 1131 }, 1132 { 1133 name: "current final SDK", 1134 sdkVersion: "current", 1135 platformSdkInt: 29, 1136 platformSdkCodename: "Q", 1137 platformSdkFinal: false, 1138 deviceCurrentApiLevelForVendorModules: "28", 1139 expectedMinSdkVersion: "28", 1140 }, 1141 } 1142 1143 for _, moduleType := range []string{"android_app", "android_library"} { 1144 for _, sdkKind := range []string{"", "system_"} { 1145 for _, test := range testCases { 1146 t.Run(moduleType+" "+test.name, func(t *testing.T) { 1147 bp := fmt.Sprintf(`%s { 1148 name: "foo", 1149 srcs: ["a.java"], 1150 sdk_version: "%s%s", 1151 vendor: true, 1152 }`, moduleType, sdkKind, test.sdkVersion) 1153 1154 result := android.GroupFixturePreparers( 1155 prepareForJavaTest, 1156 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1157 variables.Platform_sdk_version = &test.platformSdkInt 1158 variables.Platform_sdk_codename = &test.platformSdkCodename 1159 variables.Platform_sdk_final = &test.platformSdkFinal 1160 variables.DeviceCurrentApiLevelForVendorModules = &test.deviceCurrentApiLevelForVendorModules 1161 variables.DeviceSystemSdkVersions = []string{"28", "29"} 1162 }), 1163 FixtureWithPrebuiltApis(map[string][]string{ 1164 "28": {"foo"}, 1165 "29": {"foo"}, 1166 "current": {"foo"}, 1167 }), 1168 ).RunTestWithBp(t, bp) 1169 1170 checkSdkVersion(t, result, test.expectedMinSdkVersion) 1171 }) 1172 } 1173 } 1174 } 1175} 1176 1177func TestJNIABI(t *testing.T) { 1178 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+` 1179 cc_library { 1180 name: "libjni", 1181 system_shared_libs: [], 1182 sdk_version: "current", 1183 stl: "none", 1184 } 1185 1186 android_test { 1187 name: "test", 1188 sdk_version: "core_platform", 1189 jni_libs: ["libjni"], 1190 } 1191 1192 android_test { 1193 name: "test_first", 1194 sdk_version: "core_platform", 1195 compile_multilib: "first", 1196 jni_libs: ["libjni"], 1197 } 1198 1199 android_test { 1200 name: "test_both", 1201 sdk_version: "core_platform", 1202 compile_multilib: "both", 1203 jni_libs: ["libjni"], 1204 } 1205 1206 android_test { 1207 name: "test_32", 1208 sdk_version: "core_platform", 1209 compile_multilib: "32", 1210 jni_libs: ["libjni"], 1211 } 1212 1213 android_test { 1214 name: "test_64", 1215 sdk_version: "core_platform", 1216 compile_multilib: "64", 1217 jni_libs: ["libjni"], 1218 } 1219 `) 1220 1221 testCases := []struct { 1222 name string 1223 abis []string 1224 }{ 1225 {"test", []string{"arm64-v8a"}}, 1226 {"test_first", []string{"arm64-v8a"}}, 1227 {"test_both", []string{"arm64-v8a", "armeabi-v7a"}}, 1228 {"test_32", []string{"armeabi-v7a"}}, 1229 {"test_64", []string{"arm64-v8a"}}, 1230 } 1231 1232 for _, test := range testCases { 1233 t.Run(test.name, func(t *testing.T) { 1234 app := ctx.ModuleForTests(test.name, "android_common") 1235 jniLibZip := app.Output(jniJarOutputPathString) 1236 var abis []string 1237 args := strings.Fields(jniLibZip.Args["jarArgs"]) 1238 for i := 0; i < len(args); i++ { 1239 if args[i] == "-P" { 1240 abis = append(abis, filepath.Base(args[i+1])) 1241 i++ 1242 } 1243 } 1244 if !reflect.DeepEqual(abis, test.abis) { 1245 t.Errorf("want abis %v, got %v", test.abis, abis) 1246 } 1247 }) 1248 } 1249} 1250 1251func TestAppSdkVersionByPartition(t *testing.T) { 1252 testJavaError(t, "sdk_version must have a value when the module is located at vendor or product", ` 1253 android_app { 1254 name: "foo", 1255 srcs: ["a.java"], 1256 vendor: true, 1257 platform_apis: true, 1258 } 1259 `) 1260 1261 testJava(t, ` 1262 android_app { 1263 name: "bar", 1264 srcs: ["b.java"], 1265 platform_apis: true, 1266 } 1267 `) 1268 1269 for _, enforce := range []bool{true, false} { 1270 bp := ` 1271 android_app { 1272 name: "foo", 1273 srcs: ["a.java"], 1274 product_specific: true, 1275 platform_apis: true, 1276 } 1277 ` 1278 1279 errorHandler := android.FixtureExpectsNoErrors 1280 if enforce { 1281 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern("sdk_version must have a value when the module is located at vendor or product") 1282 } 1283 1284 android.GroupFixturePreparers( 1285 PrepareForTestWithJavaDefaultModules, 1286 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1287 variables.EnforceProductPartitionInterface = proptools.BoolPtr(enforce) 1288 }), 1289 ). 1290 ExtendWithErrorHandler(errorHandler). 1291 RunTestWithBp(t, bp) 1292 } 1293} 1294 1295func TestJNIPackaging(t *testing.T) { 1296 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+` 1297 cc_library { 1298 name: "libjni", 1299 system_shared_libs: [], 1300 stl: "none", 1301 sdk_version: "current", 1302 } 1303 1304 android_app { 1305 name: "app", 1306 jni_libs: ["libjni"], 1307 sdk_version: "current", 1308 } 1309 1310 android_app { 1311 name: "app_noembed", 1312 jni_libs: ["libjni"], 1313 use_embedded_native_libs: false, 1314 sdk_version: "current", 1315 } 1316 1317 android_app { 1318 name: "app_embed", 1319 jni_libs: ["libjni"], 1320 use_embedded_native_libs: true, 1321 sdk_version: "current", 1322 } 1323 1324 android_test { 1325 name: "test", 1326 sdk_version: "current", 1327 jni_libs: ["libjni"], 1328 } 1329 1330 android_test { 1331 name: "test_noembed", 1332 sdk_version: "current", 1333 jni_libs: ["libjni"], 1334 use_embedded_native_libs: false, 1335 } 1336 1337 android_test_helper_app { 1338 name: "test_helper", 1339 sdk_version: "current", 1340 jni_libs: ["libjni"], 1341 } 1342 1343 android_test_helper_app { 1344 name: "test_helper_noembed", 1345 sdk_version: "current", 1346 jni_libs: ["libjni"], 1347 use_embedded_native_libs: false, 1348 } 1349 `) 1350 1351 testCases := []struct { 1352 name string 1353 packaged bool 1354 compressed bool 1355 }{ 1356 {"app", false, false}, 1357 {"app_noembed", false, false}, 1358 {"app_embed", true, false}, 1359 {"test", true, false}, 1360 {"test_noembed", true, true}, 1361 {"test_helper", true, false}, 1362 {"test_helper_noembed", true, true}, 1363 } 1364 1365 for _, test := range testCases { 1366 t.Run(test.name, func(t *testing.T) { 1367 app := ctx.ModuleForTests(test.name, "android_common") 1368 jniLibZip := app.MaybeOutput(jniJarOutputPathString) 1369 if g, w := (jniLibZip.Rule != nil), test.packaged; g != w { 1370 t.Errorf("expected jni packaged %v, got %v", w, g) 1371 } 1372 1373 if jniLibZip.Rule != nil { 1374 if g, w := !strings.Contains(jniLibZip.Args["jarArgs"], "-L 0"), test.compressed; g != w { 1375 t.Errorf("expected jni compressed %v, got %v", w, g) 1376 } 1377 1378 if !strings.Contains(jniLibZip.Implicits[0].String(), "_sdk_") { 1379 t.Errorf("expected input %q to use sdk variant", jniLibZip.Implicits[0].String()) 1380 } 1381 } 1382 }) 1383 } 1384} 1385 1386func TestJNISDK(t *testing.T) { 1387 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+` 1388 cc_library { 1389 name: "libjni", 1390 system_shared_libs: [], 1391 stl: "none", 1392 sdk_version: "current", 1393 } 1394 1395 android_test { 1396 name: "app_platform", 1397 jni_libs: ["libjni"], 1398 platform_apis: true, 1399 } 1400 1401 android_test { 1402 name: "app_sdk", 1403 jni_libs: ["libjni"], 1404 sdk_version: "current", 1405 } 1406 1407 android_test { 1408 name: "app_force_platform", 1409 jni_libs: ["libjni"], 1410 sdk_version: "current", 1411 jni_uses_platform_apis: true, 1412 } 1413 1414 android_test { 1415 name: "app_force_sdk", 1416 jni_libs: ["libjni"], 1417 platform_apis: true, 1418 jni_uses_sdk_apis: true, 1419 } 1420 1421 cc_library { 1422 name: "libvendorjni", 1423 system_shared_libs: [], 1424 stl: "none", 1425 vendor: true, 1426 } 1427 1428 android_test { 1429 name: "app_vendor", 1430 jni_libs: ["libvendorjni"], 1431 sdk_version: "current", 1432 vendor: true, 1433 } 1434 `) 1435 1436 testCases := []struct { 1437 name string 1438 sdkJNI bool 1439 vendorJNI bool 1440 }{ 1441 {name: "app_platform"}, 1442 {name: "app_sdk", sdkJNI: true}, 1443 {name: "app_force_platform"}, 1444 {name: "app_force_sdk", sdkJNI: true}, 1445 {name: "app_vendor", vendorJNI: true}, 1446 } 1447 1448 platformJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_shared"). 1449 Output("libjni.so").Output.String() 1450 sdkJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared"). 1451 Output("libjni.so").Output.String() 1452 vendorJNI := ctx.ModuleForTests("libvendorjni", "android_arm64_armv8-a_shared"). 1453 Output("libvendorjni.so").Output.String() 1454 1455 for _, test := range testCases { 1456 t.Run(test.name, func(t *testing.T) { 1457 app := ctx.ModuleForTests(test.name, "android_common") 1458 1459 jniLibZip := app.MaybeOutput(jniJarOutputPathString) 1460 if len(jniLibZip.Implicits) != 1 { 1461 t.Fatalf("expected exactly one jni library, got %q", jniLibZip.Implicits.Strings()) 1462 } 1463 gotJNI := jniLibZip.Implicits[0].String() 1464 1465 if test.sdkJNI { 1466 if gotJNI != sdkJNI { 1467 t.Errorf("expected SDK JNI library %q, got %q", sdkJNI, gotJNI) 1468 } 1469 } else if test.vendorJNI { 1470 if gotJNI != vendorJNI { 1471 t.Errorf("expected platform JNI library %q, got %q", vendorJNI, gotJNI) 1472 } 1473 } else { 1474 if gotJNI != platformJNI { 1475 t.Errorf("expected platform JNI library %q, got %q", platformJNI, gotJNI) 1476 } 1477 } 1478 }) 1479 } 1480 1481 t.Run("jni_uses_platform_apis_error", func(t *testing.T) { 1482 testJavaError(t, `jni_uses_platform_apis: can only be set for modules that set sdk_version`, ` 1483 android_test { 1484 name: "app_platform", 1485 platform_apis: true, 1486 jni_uses_platform_apis: true, 1487 } 1488 `) 1489 }) 1490 1491 t.Run("jni_uses_sdk_apis_error", func(t *testing.T) { 1492 testJavaError(t, `jni_uses_sdk_apis: can only be set for modules that do not set sdk_version`, ` 1493 android_test { 1494 name: "app_sdk", 1495 sdk_version: "current", 1496 jni_uses_sdk_apis: true, 1497 } 1498 `) 1499 }) 1500 1501} 1502 1503func TestCertificates(t *testing.T) { 1504 testCases := []struct { 1505 name string 1506 bp string 1507 allowMissingDependencies bool 1508 certificateOverride string 1509 expectedCertSigningFlags string 1510 expectedCertificate string 1511 }{ 1512 { 1513 name: "default", 1514 bp: ` 1515 android_app { 1516 name: "foo", 1517 srcs: ["a.java"], 1518 sdk_version: "current", 1519 } 1520 `, 1521 certificateOverride: "", 1522 expectedCertSigningFlags: "", 1523 expectedCertificate: "build/make/target/product/security/testkey", 1524 }, 1525 { 1526 name: "module certificate property", 1527 bp: ` 1528 android_app { 1529 name: "foo", 1530 srcs: ["a.java"], 1531 certificate: ":new_certificate", 1532 sdk_version: "current", 1533 } 1534 1535 android_app_certificate { 1536 name: "new_certificate", 1537 certificate: "cert/new_cert", 1538 } 1539 `, 1540 certificateOverride: "", 1541 expectedCertSigningFlags: "", 1542 expectedCertificate: "cert/new_cert", 1543 }, 1544 { 1545 name: "path certificate property", 1546 bp: ` 1547 android_app { 1548 name: "foo", 1549 srcs: ["a.java"], 1550 certificate: "expiredkey", 1551 sdk_version: "current", 1552 } 1553 `, 1554 certificateOverride: "", 1555 expectedCertSigningFlags: "", 1556 expectedCertificate: "build/make/target/product/security/expiredkey", 1557 }, 1558 { 1559 name: "certificate overrides", 1560 bp: ` 1561 android_app { 1562 name: "foo", 1563 srcs: ["a.java"], 1564 certificate: "expiredkey", 1565 sdk_version: "current", 1566 } 1567 1568 android_app_certificate { 1569 name: "new_certificate", 1570 certificate: "cert/new_cert", 1571 } 1572 `, 1573 certificateOverride: "foo:new_certificate", 1574 expectedCertSigningFlags: "", 1575 expectedCertificate: "cert/new_cert", 1576 }, 1577 { 1578 name: "certificate signing flags", 1579 bp: ` 1580 android_app { 1581 name: "foo", 1582 srcs: ["a.java"], 1583 certificate: ":new_certificate", 1584 lineage: "lineage.bin", 1585 rotationMinSdkVersion: "32", 1586 sdk_version: "current", 1587 } 1588 1589 android_app_certificate { 1590 name: "new_certificate", 1591 certificate: "cert/new_cert", 1592 } 1593 `, 1594 certificateOverride: "", 1595 expectedCertSigningFlags: "--lineage lineage.bin --rotation-min-sdk-version 32", 1596 expectedCertificate: "cert/new_cert", 1597 }, 1598 { 1599 name: "cert signing flags from filegroup", 1600 bp: ` 1601 android_app { 1602 name: "foo", 1603 srcs: ["a.java"], 1604 certificate: ":new_certificate", 1605 lineage: ":lineage_bin", 1606 rotationMinSdkVersion: "32", 1607 sdk_version: "current", 1608 } 1609 1610 android_app_certificate { 1611 name: "new_certificate", 1612 certificate: "cert/new_cert", 1613 } 1614 1615 filegroup { 1616 name: "lineage_bin", 1617 srcs: ["lineage.bin"], 1618 } 1619 `, 1620 certificateOverride: "", 1621 expectedCertSigningFlags: "--lineage lineage.bin --rotation-min-sdk-version 32", 1622 expectedCertificate: "cert/new_cert", 1623 }, 1624 { 1625 name: "missing with AllowMissingDependencies", 1626 bp: ` 1627 android_app { 1628 name: "foo", 1629 srcs: ["a.java"], 1630 certificate: ":new_certificate", 1631 sdk_version: "current", 1632 } 1633 `, 1634 expectedCertificate: "out/soong/.intermediates/foo/android_common/missing", 1635 allowMissingDependencies: true, 1636 }, 1637 } 1638 1639 for _, test := range testCases { 1640 t.Run(test.name, func(t *testing.T) { 1641 result := android.GroupFixturePreparers( 1642 PrepareForTestWithJavaDefaultModules, 1643 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1644 if test.certificateOverride != "" { 1645 variables.CertificateOverrides = []string{test.certificateOverride} 1646 } 1647 if test.allowMissingDependencies { 1648 variables.Allow_missing_dependencies = proptools.BoolPtr(true) 1649 } 1650 }), 1651 android.FixtureModifyContext(func(ctx *android.TestContext) { 1652 ctx.SetAllowMissingDependencies(test.allowMissingDependencies) 1653 }), 1654 ).RunTestWithBp(t, test.bp) 1655 1656 foo := result.ModuleForTests("foo", "android_common") 1657 1658 certificate := foo.Module().(*AndroidApp).certificate 1659 android.AssertPathRelativeToTopEquals(t, "certificates key", test.expectedCertificate+".pk8", certificate.Key) 1660 // The sign_target_files_apks and check_target_files_signatures 1661 // tools require that certificates have a .x509.pem extension. 1662 android.AssertPathRelativeToTopEquals(t, "certificates pem", test.expectedCertificate+".x509.pem", certificate.Pem) 1663 1664 signapk := foo.Output("foo.apk") 1665 if signapk.Rule != android.ErrorRule { 1666 signCertificateFlags := signapk.Args["certificates"] 1667 expectedFlags := certificate.Pem.String() + " " + certificate.Key.String() 1668 android.AssertStringEquals(t, "certificates flags", expectedFlags, signCertificateFlags) 1669 1670 certSigningFlags := signapk.Args["flags"] 1671 android.AssertStringEquals(t, "cert signing flags", test.expectedCertSigningFlags, certSigningFlags) 1672 } 1673 }) 1674 } 1675} 1676 1677func TestRequestV4SigningFlag(t *testing.T) { 1678 testCases := []struct { 1679 name string 1680 bp string 1681 expected string 1682 }{ 1683 { 1684 name: "default", 1685 bp: ` 1686 android_app { 1687 name: "foo", 1688 srcs: ["a.java"], 1689 sdk_version: "current", 1690 } 1691 `, 1692 expected: "", 1693 }, 1694 { 1695 name: "default", 1696 bp: ` 1697 android_app { 1698 name: "foo", 1699 srcs: ["a.java"], 1700 sdk_version: "current", 1701 v4_signature: false, 1702 } 1703 `, 1704 expected: "", 1705 }, 1706 { 1707 name: "module certificate property", 1708 bp: ` 1709 android_app { 1710 name: "foo", 1711 srcs: ["a.java"], 1712 sdk_version: "current", 1713 v4_signature: true, 1714 } 1715 `, 1716 expected: "--enable-v4", 1717 }, 1718 } 1719 1720 for _, test := range testCases { 1721 t.Run(test.name, func(t *testing.T) { 1722 result := android.GroupFixturePreparers( 1723 PrepareForTestWithJavaDefaultModules, 1724 ).RunTestWithBp(t, test.bp) 1725 1726 foo := result.ModuleForTests("foo", "android_common") 1727 1728 signapk := foo.Output("foo.apk") 1729 signFlags := signapk.Args["flags"] 1730 android.AssertStringEquals(t, "signing flags", test.expected, signFlags) 1731 }) 1732 } 1733} 1734 1735func TestPackageNameOverride(t *testing.T) { 1736 testCases := []struct { 1737 name string 1738 bp string 1739 packageNameOverride string 1740 expected []string 1741 }{ 1742 { 1743 name: "default", 1744 bp: ` 1745 android_app { 1746 name: "foo", 1747 srcs: ["a.java"], 1748 sdk_version: "current", 1749 } 1750 `, 1751 packageNameOverride: "", 1752 expected: []string{ 1753 "out/soong/.intermediates/foo/android_common/foo.apk", 1754 "out/soong/target/product/test_device/system/app/foo/foo.apk", 1755 }, 1756 }, 1757 { 1758 name: "overridden via PRODUCT_PACKAGE_NAME_OVERRIDES", 1759 bp: ` 1760 android_app { 1761 name: "foo", 1762 srcs: ["a.java"], 1763 sdk_version: "current", 1764 } 1765 `, 1766 packageNameOverride: "foo:bar", 1767 expected: []string{ 1768 // The package apk should be still be the original name for test dependencies. 1769 "out/soong/.intermediates/foo/android_common/bar.apk", 1770 "out/soong/target/product/test_device/system/app/bar/bar.apk", 1771 }, 1772 }, 1773 { 1774 name: "overridden via stem", 1775 bp: ` 1776 android_app { 1777 name: "foo", 1778 srcs: ["a.java"], 1779 sdk_version: "current", 1780 stem: "bar", 1781 } 1782 `, 1783 packageNameOverride: "", 1784 expected: []string{ 1785 "out/soong/.intermediates/foo/android_common/bar.apk", 1786 "out/soong/target/product/test_device/system/app/bar/bar.apk", 1787 }, 1788 }, 1789 } 1790 1791 for _, test := range testCases { 1792 t.Run(test.name, func(t *testing.T) { 1793 result := android.GroupFixturePreparers( 1794 PrepareForTestWithJavaDefaultModules, 1795 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1796 if test.packageNameOverride != "" { 1797 variables.PackageNameOverrides = []string{test.packageNameOverride} 1798 } 1799 }), 1800 ).RunTestWithBp(t, test.bp) 1801 1802 foo := result.ModuleForTests("foo", "android_common") 1803 1804 outSoongDir := result.Config.SoongOutDir() 1805 1806 outputs := foo.AllOutputs() 1807 outputMap := make(map[string]bool) 1808 for _, o := range outputs { 1809 outputMap[android.StringPathRelativeToTop(outSoongDir, o)] = true 1810 } 1811 for _, e := range test.expected { 1812 if _, exist := outputMap[e]; !exist { 1813 t.Errorf("Can't find %q in output files.\nAll outputs:%v", e, outputs) 1814 } 1815 } 1816 }) 1817 } 1818} 1819 1820func TestInstrumentationTargetOverridden(t *testing.T) { 1821 bp := ` 1822 android_app { 1823 name: "foo", 1824 srcs: ["a.java"], 1825 sdk_version: "current", 1826 } 1827 1828 android_test { 1829 name: "bar", 1830 instrumentation_for: "foo", 1831 sdk_version: "current", 1832 } 1833 ` 1834 1835 result := android.GroupFixturePreparers( 1836 PrepareForTestWithJavaDefaultModules, 1837 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1838 variables.ManifestPackageNameOverrides = []string{"foo:org.dandroid.bp"} 1839 }), 1840 ).RunTestWithBp(t, bp) 1841 1842 bar := result.ModuleForTests("bar", "android_common") 1843 res := bar.Output("package-res.apk") 1844 aapt2Flags := res.Args["flags"] 1845 e := "--rename-instrumentation-target-package org.dandroid.bp" 1846 if !strings.Contains(aapt2Flags, e) { 1847 t.Errorf("target package renaming flag, %q is missing in aapt2 link flags, %q", e, aapt2Flags) 1848 } 1849} 1850 1851func TestOverrideAndroidApp(t *testing.T) { 1852 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp( 1853 t, ` 1854 android_app { 1855 name: "foo", 1856 srcs: ["a.java"], 1857 certificate: "expiredkey", 1858 overrides: ["qux"], 1859 sdk_version: "current", 1860 } 1861 1862 override_android_app { 1863 name: "bar", 1864 base: "foo", 1865 certificate: ":new_certificate", 1866 lineage: "lineage.bin", 1867 rotationMinSdkVersion: "32", 1868 logging_parent: "bah", 1869 } 1870 1871 android_app_certificate { 1872 name: "new_certificate", 1873 certificate: "cert/new_cert", 1874 } 1875 1876 override_android_app { 1877 name: "baz", 1878 base: "foo", 1879 package_name: "org.dandroid.bp", 1880 } 1881 1882 override_android_app { 1883 name: "baz_no_rename_resources", 1884 base: "foo", 1885 package_name: "org.dandroid.bp", 1886 rename_resources_package: false, 1887 } 1888 1889 android_app { 1890 name: "foo_no_rename_resources", 1891 srcs: ["a.java"], 1892 certificate: "expiredkey", 1893 overrides: ["qux"], 1894 rename_resources_package: false, 1895 sdk_version: "current", 1896 } 1897 1898 override_android_app { 1899 name: "baz_base_no_rename_resources", 1900 base: "foo_no_rename_resources", 1901 package_name: "org.dandroid.bp", 1902 } 1903 1904 override_android_app { 1905 name: "baz_override_base_rename_resources", 1906 base: "foo_no_rename_resources", 1907 package_name: "org.dandroid.bp", 1908 rename_resources_package: true, 1909 } 1910 `) 1911 1912 expectedVariants := []struct { 1913 name string 1914 moduleName string 1915 variantName string 1916 apkName string 1917 apkPath string 1918 certFlag string 1919 certSigningFlags string 1920 overrides []string 1921 packageFlag string 1922 renameResources bool 1923 logging_parent string 1924 }{ 1925 { 1926 name: "foo", 1927 moduleName: "foo", 1928 variantName: "android_common", 1929 apkPath: "out/soong/target/product/test_device/system/app/foo/foo.apk", 1930 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", 1931 certSigningFlags: "", 1932 overrides: []string{"qux"}, 1933 packageFlag: "", 1934 renameResources: false, 1935 logging_parent: "", 1936 }, 1937 { 1938 name: "foo", 1939 moduleName: "bar", 1940 variantName: "android_common_bar", 1941 apkPath: "out/soong/target/product/test_device/system/app/bar/bar.apk", 1942 certFlag: "cert/new_cert.x509.pem cert/new_cert.pk8", 1943 certSigningFlags: "--lineage lineage.bin --rotation-min-sdk-version 32", 1944 overrides: []string{"qux", "foo"}, 1945 packageFlag: "", 1946 renameResources: false, 1947 logging_parent: "bah", 1948 }, 1949 { 1950 name: "foo", 1951 moduleName: "baz", 1952 variantName: "android_common_baz", 1953 apkPath: "out/soong/target/product/test_device/system/app/baz/baz.apk", 1954 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", 1955 certSigningFlags: "", 1956 overrides: []string{"qux", "foo"}, 1957 packageFlag: "org.dandroid.bp", 1958 renameResources: true, 1959 logging_parent: "", 1960 }, 1961 { 1962 name: "foo", 1963 moduleName: "baz_no_rename_resources", 1964 variantName: "android_common_baz_no_rename_resources", 1965 apkPath: "out/soong/target/product/test_device/system/app/baz_no_rename_resources/baz_no_rename_resources.apk", 1966 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", 1967 certSigningFlags: "", 1968 overrides: []string{"qux", "foo"}, 1969 packageFlag: "org.dandroid.bp", 1970 renameResources: false, 1971 logging_parent: "", 1972 }, 1973 { 1974 name: "foo_no_rename_resources", 1975 moduleName: "baz_base_no_rename_resources", 1976 variantName: "android_common_baz_base_no_rename_resources", 1977 apkPath: "out/soong/target/product/test_device/system/app/baz_base_no_rename_resources/baz_base_no_rename_resources.apk", 1978 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", 1979 certSigningFlags: "", 1980 overrides: []string{"qux", "foo_no_rename_resources"}, 1981 packageFlag: "org.dandroid.bp", 1982 renameResources: false, 1983 logging_parent: "", 1984 }, 1985 { 1986 name: "foo_no_rename_resources", 1987 moduleName: "baz_override_base_rename_resources", 1988 variantName: "android_common_baz_override_base_rename_resources", 1989 apkPath: "out/soong/target/product/test_device/system/app/baz_override_base_rename_resources/baz_override_base_rename_resources.apk", 1990 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", 1991 certSigningFlags: "", 1992 overrides: []string{"qux", "foo_no_rename_resources"}, 1993 packageFlag: "org.dandroid.bp", 1994 renameResources: true, 1995 logging_parent: "", 1996 }, 1997 } 1998 for _, expected := range expectedVariants { 1999 variant := result.ModuleForTests(expected.name, expected.variantName) 2000 2001 // Check the final apk name 2002 variant.Output(expected.apkPath) 2003 2004 // Check the certificate paths 2005 signapk := variant.Output(expected.moduleName + ".apk") 2006 certFlag := signapk.Args["certificates"] 2007 android.AssertStringEquals(t, "certificates flags", expected.certFlag, certFlag) 2008 2009 // Check the cert signing flags 2010 certSigningFlags := signapk.Args["flags"] 2011 android.AssertStringEquals(t, "cert signing flags", expected.certSigningFlags, certSigningFlags) 2012 2013 // Check if the overrides field values are correctly aggregated. 2014 mod := variant.Module().(*AndroidApp) 2015 android.AssertDeepEquals(t, "overrides property", expected.overrides, mod.overridableAppProperties.Overrides) 2016 2017 // Test Overridable property: Logging_parent 2018 logging_parent := mod.aapt.LoggingParent 2019 android.AssertStringEquals(t, "overrides property value for logging parent", expected.logging_parent, logging_parent) 2020 2021 // Check the package renaming flag, if exists. 2022 res := variant.Output("package-res.apk") 2023 aapt2Flags := res.Args["flags"] 2024 checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag) 2025 expectedPackage := expected.packageFlag 2026 if !expected.renameResources { 2027 expectedPackage = "" 2028 } 2029 checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expectedPackage) 2030 } 2031} 2032 2033func TestOverrideAndroidAppOverrides(t *testing.T) { 2034 ctx, _ := testJava( 2035 t, ` 2036 android_app { 2037 name: "foo", 2038 srcs: ["a.java"], 2039 sdk_version: "current", 2040 overrides: ["qux"] 2041 } 2042 2043 android_app { 2044 name: "bar", 2045 srcs: ["b.java"], 2046 sdk_version: "current", 2047 overrides: ["foo"] 2048 } 2049 2050 override_android_app { 2051 name: "foo_override", 2052 base: "foo", 2053 overrides: ["bar"] 2054 } 2055 `) 2056 2057 expectedVariants := []struct { 2058 name string 2059 moduleName string 2060 variantName string 2061 overrides []string 2062 }{ 2063 { 2064 name: "foo", 2065 moduleName: "foo", 2066 variantName: "android_common", 2067 overrides: []string{"qux"}, 2068 }, 2069 { 2070 name: "bar", 2071 moduleName: "bar", 2072 variantName: "android_common", 2073 overrides: []string{"foo"}, 2074 }, 2075 { 2076 name: "foo", 2077 moduleName: "foo_override", 2078 variantName: "android_common_foo_override", 2079 overrides: []string{"bar", "foo"}, 2080 }, 2081 } 2082 for _, expected := range expectedVariants { 2083 variant := ctx.ModuleForTests(expected.name, expected.variantName) 2084 2085 // Check if the overrides field values are correctly aggregated. 2086 mod := variant.Module().(*AndroidApp) 2087 android.AssertDeepEquals(t, "overrides property", expected.overrides, mod.overridableAppProperties.Overrides) 2088 } 2089} 2090 2091func TestOverrideAndroidAppWithPrebuilt(t *testing.T) { 2092 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp( 2093 t, ` 2094 android_app { 2095 name: "foo", 2096 srcs: ["a.java"], 2097 sdk_version: "current", 2098 } 2099 2100 override_android_app { 2101 name: "bar", 2102 base: "foo", 2103 } 2104 2105 android_app_import { 2106 name: "bar", 2107 prefer: true, 2108 apk: "bar.apk", 2109 presigned: true, 2110 } 2111 `) 2112 2113 // An app that has an override that also has a prebuilt should not be hidden. 2114 foo := result.ModuleForTests("foo", "android_common") 2115 if foo.Module().IsHideFromMake() { 2116 t.Errorf("expected foo to have HideFromMake false") 2117 } 2118 2119 // An override that also has a prebuilt should be hidden. 2120 barOverride := result.ModuleForTests("foo", "android_common_bar") 2121 if !barOverride.Module().IsHideFromMake() { 2122 t.Errorf("expected bar override variant of foo to have HideFromMake true") 2123 } 2124} 2125 2126func TestOverrideAndroidAppStem(t *testing.T) { 2127 ctx, _ := testJava(t, ` 2128 android_app { 2129 name: "foo", 2130 srcs: ["a.java"], 2131 sdk_version: "current", 2132 } 2133 override_android_app { 2134 name: "bar", 2135 base: "foo", 2136 } 2137 override_android_app { 2138 name: "baz", 2139 base: "foo", 2140 stem: "baz_stem", 2141 } 2142 android_app { 2143 name: "foo2", 2144 srcs: ["a.java"], 2145 sdk_version: "current", 2146 stem: "foo2_stem", 2147 } 2148 override_android_app { 2149 name: "bar2", 2150 base: "foo2", 2151 } 2152 override_android_app { 2153 name: "baz2", 2154 base: "foo2", 2155 stem: "baz2_stem", 2156 } 2157 `) 2158 for _, expected := range []struct { 2159 moduleName string 2160 variantName string 2161 apkPath string 2162 }{ 2163 { 2164 moduleName: "foo", 2165 variantName: "android_common", 2166 apkPath: "out/soong/target/product/test_device/system/app/foo/foo.apk", 2167 }, 2168 { 2169 moduleName: "foo", 2170 variantName: "android_common_bar", 2171 apkPath: "out/soong/target/product/test_device/system/app/bar/bar.apk", 2172 }, 2173 { 2174 moduleName: "foo", 2175 variantName: "android_common_baz", 2176 apkPath: "out/soong/target/product/test_device/system/app/baz_stem/baz_stem.apk", 2177 }, 2178 { 2179 moduleName: "foo2", 2180 variantName: "android_common", 2181 apkPath: "out/soong/target/product/test_device/system/app/foo2_stem/foo2_stem.apk", 2182 }, 2183 { 2184 moduleName: "foo2", 2185 variantName: "android_common_bar2", 2186 // Note that this may cause the duplicate output error. 2187 apkPath: "out/soong/target/product/test_device/system/app/foo2_stem/foo2_stem.apk", 2188 }, 2189 { 2190 moduleName: "foo2", 2191 variantName: "android_common_baz2", 2192 apkPath: "out/soong/target/product/test_device/system/app/baz2_stem/baz2_stem.apk", 2193 }, 2194 } { 2195 variant := ctx.ModuleForTests(expected.moduleName, expected.variantName) 2196 variant.Output(expected.apkPath) 2197 } 2198} 2199 2200func TestOverrideAndroidAppDependency(t *testing.T) { 2201 ctx, _ := testJava(t, ` 2202 android_app { 2203 name: "foo", 2204 srcs: ["a.java"], 2205 sdk_version: "current", 2206 } 2207 2208 override_android_app { 2209 name: "bar", 2210 base: "foo", 2211 package_name: "org.dandroid.bp", 2212 } 2213 2214 android_test { 2215 name: "baz", 2216 srcs: ["b.java"], 2217 instrumentation_for: "foo", 2218 } 2219 2220 android_test { 2221 name: "qux", 2222 srcs: ["b.java"], 2223 instrumentation_for: "bar", 2224 } 2225 `) 2226 2227 // Verify baz, which depends on the overridden module foo, has the correct classpath javac arg. 2228 javac := ctx.ModuleForTests("baz", "android_common").Rule("javac") 2229 fooTurbine := "out/soong/.intermediates/foo/android_common/turbine-combined/foo.jar" 2230 if !strings.Contains(javac.Args["classpath"], fooTurbine) { 2231 t.Errorf("baz classpath %v does not contain %q", javac.Args["classpath"], fooTurbine) 2232 } 2233 2234 // Verify qux, which depends on the overriding module bar, has the correct classpath javac arg. 2235 javac = ctx.ModuleForTests("qux", "android_common").Rule("javac") 2236 barTurbine := "out/soong/.intermediates/foo/android_common_bar/turbine-combined/foo.jar" 2237 if !strings.Contains(javac.Args["classpath"], barTurbine) { 2238 t.Errorf("qux classpath %v does not contain %q", javac.Args["classpath"], barTurbine) 2239 } 2240} 2241 2242func TestOverrideAndroidTest(t *testing.T) { 2243 ctx, _ := testJava(t, ` 2244 android_app { 2245 name: "foo", 2246 srcs: ["a.java"], 2247 package_name: "com.android.foo", 2248 sdk_version: "current", 2249 } 2250 2251 override_android_app { 2252 name: "bar", 2253 base: "foo", 2254 package_name: "com.android.bar", 2255 } 2256 2257 android_test { 2258 name: "foo_test", 2259 srcs: ["b.java"], 2260 instrumentation_for: "foo", 2261 } 2262 2263 override_android_test { 2264 name: "bar_test", 2265 base: "foo_test", 2266 package_name: "com.android.bar.test", 2267 instrumentation_for: "bar", 2268 instrumentation_target_package: "com.android.bar", 2269 } 2270 `) 2271 2272 expectedVariants := []struct { 2273 moduleName string 2274 variantName string 2275 apkPath string 2276 overrides []string 2277 targetVariant string 2278 packageFlag string 2279 targetPackageFlag string 2280 }{ 2281 { 2282 variantName: "android_common", 2283 apkPath: "/target/product/test_device/testcases/foo_test/arm64/foo_test.apk", 2284 overrides: nil, 2285 targetVariant: "android_common", 2286 packageFlag: "", 2287 targetPackageFlag: "", 2288 }, 2289 { 2290 variantName: "android_common_bar_test", 2291 apkPath: "/target/product/test_device/testcases/bar_test/arm64/bar_test.apk", 2292 overrides: []string{"foo_test"}, 2293 targetVariant: "android_common_bar", 2294 packageFlag: "com.android.bar.test", 2295 targetPackageFlag: "com.android.bar", 2296 }, 2297 } 2298 for _, expected := range expectedVariants { 2299 variant := ctx.ModuleForTests("foo_test", expected.variantName) 2300 2301 // Check the final apk name 2302 variant.Output("out/soong" + expected.apkPath) 2303 2304 // Check if the overrides field values are correctly aggregated. 2305 mod := variant.Module().(*AndroidTest) 2306 if !reflect.DeepEqual(expected.overrides, mod.overridableAppProperties.Overrides) { 2307 t.Errorf("Incorrect overrides property value, expected: %q, got: %q", 2308 expected.overrides, mod.overridableAppProperties.Overrides) 2309 } 2310 2311 // Check if javac classpath has the correct jar file path. This checks instrumentation_for overrides. 2312 javac := variant.Rule("javac") 2313 turbine := filepath.Join("out", "soong", ".intermediates", "foo", expected.targetVariant, "turbine-combined", "foo.jar") 2314 if !strings.Contains(javac.Args["classpath"], turbine) { 2315 t.Errorf("classpath %q does not contain %q", javac.Args["classpath"], turbine) 2316 } 2317 2318 // Check aapt2 flags. 2319 res := variant.Output("package-res.apk") 2320 aapt2Flags := res.Args["flags"] 2321 checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag) 2322 checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expected.packageFlag) 2323 checkAapt2LinkFlag(t, aapt2Flags, "rename-instrumentation-target-package", expected.targetPackageFlag) 2324 } 2325} 2326 2327func TestAndroidTest_FixTestConfig(t *testing.T) { 2328 ctx, _ := testJava(t, ` 2329 android_app { 2330 name: "foo", 2331 srcs: ["a.java"], 2332 package_name: "com.android.foo", 2333 sdk_version: "current", 2334 } 2335 2336 android_test { 2337 name: "foo_test", 2338 srcs: ["b.java"], 2339 instrumentation_for: "foo", 2340 } 2341 2342 android_test { 2343 name: "bar_test", 2344 srcs: ["b.java"], 2345 package_name: "com.android.bar.test", 2346 instrumentation_for: "foo", 2347 mainline_package_name: "com.android.bar", 2348 } 2349 2350 override_android_test { 2351 name: "baz_test", 2352 base: "foo_test", 2353 package_name: "com.android.baz.test", 2354 mainline_package_name: "com.android.baz", 2355 } 2356 `) 2357 2358 testCases := []struct { 2359 moduleName string 2360 variantName string 2361 expectedFlags []string 2362 }{ 2363 { 2364 moduleName: "foo_test", 2365 variantName: "android_common", 2366 }, 2367 { 2368 moduleName: "bar_test", 2369 variantName: "android_common", 2370 expectedFlags: []string{ 2371 "--manifest out/soong/.intermediates/bar_test/android_common/manifest_fixer/AndroidManifest.xml", 2372 "--package-name com.android.bar.test", 2373 "--mainline-package-name com.android.bar", 2374 }, 2375 }, 2376 { 2377 moduleName: "foo_test", 2378 variantName: "android_common_baz_test", 2379 expectedFlags: []string{ 2380 "--manifest out/soong/.intermediates/foo_test/android_common_baz_test/manifest_fixer/AndroidManifest.xml", 2381 "--package-name com.android.baz.test", 2382 "--test-file-name baz_test.apk", 2383 "out/soong/.intermediates/foo_test/android_common_baz_test/test_config_fixer/AndroidTest.xml", 2384 "--mainline-package-name com.android.baz", 2385 }, 2386 }, 2387 } 2388 2389 for _, test := range testCases { 2390 variant := ctx.ModuleForTests(test.moduleName, test.variantName) 2391 params := variant.MaybeOutput("test_config_fixer/AndroidTest.xml") 2392 2393 if len(test.expectedFlags) > 0 { 2394 if params.Rule == nil { 2395 t.Errorf("test_config_fixer was expected to run, but didn't") 2396 } else { 2397 for _, flag := range test.expectedFlags { 2398 if !strings.Contains(params.RuleParams.Command, flag) { 2399 t.Errorf("Flag %q was not found in command: %q", flag, params.RuleParams.Command) 2400 } 2401 } 2402 } 2403 } else { 2404 if params.Rule != nil { 2405 t.Errorf("test_config_fixer was not expected to run, but did: %q", params.RuleParams.Command) 2406 } 2407 } 2408 } 2409} 2410 2411func TestInstrumentationTargetPrebuilt(t *testing.T) { 2412 bp := ` 2413 android_app_import { 2414 name: "foo", 2415 apk: "foo.apk", 2416 presigned: true, 2417 } 2418 2419 android_test { 2420 name: "bar", 2421 srcs: ["a.java"], 2422 instrumentation_for: "foo", 2423 sdk_version: "current", 2424 } 2425 ` 2426 2427 android.GroupFixturePreparers( 2428 PrepareForTestWithJavaDefaultModules, 2429 ).ExtendWithErrorHandler( 2430 android.FixtureExpectsAtLeastOneErrorMatchingPattern( 2431 "instrumentation_for: dependency \"foo\" of type \"android_app_import\" does not provide JavaInfo so is unsuitable for use with this property")). 2432 RunTestWithBp(t, bp) 2433} 2434 2435func TestStl(t *testing.T) { 2436 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+` 2437 cc_library { 2438 name: "libjni", 2439 sdk_version: "current", 2440 stl: "c++_shared", 2441 } 2442 2443 android_test { 2444 name: "stl", 2445 jni_libs: ["libjni"], 2446 compile_multilib: "both", 2447 sdk_version: "current", 2448 stl: "c++_shared", 2449 } 2450 2451 android_test { 2452 name: "system", 2453 jni_libs: ["libjni"], 2454 compile_multilib: "both", 2455 sdk_version: "current", 2456 } 2457 `) 2458 2459 testCases := []struct { 2460 name string 2461 jnis []string 2462 }{ 2463 {"stl", 2464 []string{ 2465 "libjni.so", 2466 "libc++_shared.so", 2467 }, 2468 }, 2469 {"system", 2470 []string{ 2471 "libjni.so", 2472 }, 2473 }, 2474 } 2475 2476 for _, test := range testCases { 2477 t.Run(test.name, func(t *testing.T) { 2478 app := ctx.ModuleForTests(test.name, "android_common") 2479 jniLibZip := app.Output(jniJarOutputPathString) 2480 var jnis []string 2481 args := strings.Fields(jniLibZip.Args["jarArgs"]) 2482 for i := 0; i < len(args); i++ { 2483 if args[i] == "-f" { 2484 jnis = append(jnis, args[i+1]) 2485 i += 1 2486 } 2487 } 2488 jnisJoined := strings.Join(jnis, " ") 2489 for _, jni := range test.jnis { 2490 if !strings.Contains(jnisJoined, jni) { 2491 t.Errorf("missing jni %q in %q", jni, jnis) 2492 } 2493 } 2494 }) 2495 } 2496} 2497 2498func TestUsesLibraries(t *testing.T) { 2499 bp := ` 2500 java_sdk_library { 2501 name: "foo", 2502 srcs: ["a.java"], 2503 api_packages: ["foo"], 2504 sdk_version: "current", 2505 } 2506 2507 java_sdk_library { 2508 name: "qux", 2509 srcs: ["a.java"], 2510 api_packages: ["qux"], 2511 sdk_version: "current", 2512 } 2513 2514 java_sdk_library { 2515 name: "quuz", 2516 srcs: ["a.java"], 2517 api_packages: ["quuz"], 2518 sdk_version: "current", 2519 } 2520 2521 java_sdk_library { 2522 name: "fred", 2523 srcs: ["a.java"], 2524 api_packages: ["fred"], 2525 sdk_version: "current", 2526 } 2527 2528 java_sdk_library { 2529 name: "bar", 2530 srcs: ["a.java"], 2531 api_packages: ["bar"], 2532 sdk_version: "current", 2533 } 2534 2535 java_sdk_library { 2536 name: "runtime-library", 2537 srcs: ["a.java"], 2538 sdk_version: "current", 2539 } 2540 2541 java_library { 2542 name: "static-runtime-helper", 2543 srcs: ["a.java"], 2544 libs: ["runtime-library"], 2545 sdk_version: "current", 2546 } 2547 2548 java_library { 2549 name: "runtime-required-x", 2550 srcs: ["a.java"], 2551 installable: true, 2552 sdk_version: "current", 2553 } 2554 2555 java_library { 2556 name: "runtime-optional-x", 2557 srcs: ["a.java"], 2558 installable: true, 2559 sdk_version: "current", 2560 } 2561 2562 android_library { 2563 name: "static-x", 2564 uses_libs: ["runtime-required-x"], 2565 optional_uses_libs: ["runtime-optional-x"], 2566 sdk_version: "current", 2567 } 2568 2569 java_library { 2570 name: "runtime-required-y", 2571 srcs: ["a.java"], 2572 installable: true, 2573 sdk_version: "current", 2574 } 2575 2576 java_library { 2577 name: "runtime-optional-y", 2578 srcs: ["a.java"], 2579 installable: true, 2580 sdk_version: "current", 2581 } 2582 2583 java_library { 2584 name: "static-y", 2585 srcs: ["a.java"], 2586 uses_libs: ["runtime-required-y"], 2587 optional_uses_libs: ["runtime-optional-y"], 2588 sdk_version: "current", 2589 } 2590 2591 // A library that has to use "provides_uses_lib", because: 2592 // - it is not an SDK library 2593 // - its library name is different from its module name 2594 java_library { 2595 name: "non-sdk-lib", 2596 provides_uses_lib: "com.non.sdk.lib", 2597 installable: true, 2598 srcs: ["a.java"], 2599 } 2600 2601 android_app { 2602 name: "app", 2603 srcs: ["a.java"], 2604 libs: [ 2605 "qux", 2606 "quuz.stubs" 2607 ], 2608 static_libs: [ 2609 "static-runtime-helper", 2610 // statically linked component libraries should not pull their SDK libraries, 2611 // so "fred" should not be added to class loader context 2612 "fred.stubs", 2613 "static-x", 2614 "static-y", 2615 ], 2616 uses_libs: [ 2617 "foo", 2618 "non-sdk-lib" 2619 ], 2620 sdk_version: "current", 2621 optional_uses_libs: [ 2622 "bar", 2623 "baz", 2624 ], 2625 } 2626 2627 android_app_import { 2628 name: "prebuilt", 2629 apk: "prebuilts/apk/app.apk", 2630 certificate: "platform", 2631 uses_libs: [ 2632 "foo", 2633 "non-sdk-lib", 2634 "android.test.runner" 2635 ], 2636 optional_uses_libs: [ 2637 "bar", 2638 "baz", 2639 ], 2640 } 2641 ` 2642 2643 result := android.GroupFixturePreparers( 2644 prepareForJavaTest, 2645 PrepareForTestWithJavaSdkLibraryFiles, 2646 FixtureWithLastReleaseApis("runtime-library", "foo", "quuz", "qux", "bar", "fred"), 2647 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 2648 variables.MissingUsesLibraries = []string{"baz"} 2649 }), 2650 ).RunTestWithBp(t, bp) 2651 2652 app := result.ModuleForTests("app", "android_common") 2653 prebuilt := result.ModuleForTests("prebuilt", "android_common") 2654 2655 // Test that implicit dependencies on java_sdk_library instances are passed to the manifest. 2656 // These also include explicit `uses_libs`/`optional_uses_libs` entries, as they may be 2657 // propagated from dependencies. 2658 actualManifestFixerArgs := app.Output("manifest_fixer/AndroidManifest.xml").Args["args"] 2659 expectManifestFixerArgs := `--extract-native-libs=true ` + 2660 `--uses-library qux ` + 2661 `--uses-library quuz ` + 2662 `--uses-library foo ` + 2663 `--uses-library com.non.sdk.lib ` + 2664 `--uses-library runtime-library ` + 2665 `--uses-library runtime-required-x ` + 2666 `--uses-library runtime-required-y ` + 2667 `--optional-uses-library bar ` + 2668 `--optional-uses-library runtime-optional-x ` + 2669 `--optional-uses-library runtime-optional-y` 2670 android.AssertStringDoesContain(t, "manifest_fixer args", actualManifestFixerArgs, expectManifestFixerArgs) 2671 2672 // Test that all libraries are verified (library order matters). 2673 verifyCmd := app.Rule("verify_uses_libraries").RuleParams.Command 2674 verifyArgs := `--uses-library foo ` + 2675 `--uses-library com.non.sdk.lib ` + 2676 `--uses-library qux ` + 2677 `--uses-library quuz ` + 2678 `--uses-library runtime-library ` + 2679 `--uses-library runtime-required-x ` + 2680 `--uses-library runtime-required-y ` + 2681 `--optional-uses-library bar ` + 2682 `--optional-uses-library baz ` + 2683 `--optional-uses-library runtime-optional-x ` + 2684 `--optional-uses-library runtime-optional-y ` 2685 android.AssertStringDoesContain(t, "verify cmd args", verifyCmd, verifyArgs) 2686 2687 // Test that all libraries are verified for an APK (library order matters). 2688 verifyApkCmd := prebuilt.Rule("verify_uses_libraries").RuleParams.Command 2689 verifyApkArgs := `--uses-library foo ` + 2690 `--uses-library com.non.sdk.lib ` + 2691 `--uses-library android.test.runner ` + 2692 `--optional-uses-library bar ` + 2693 `--optional-uses-library baz ` 2694 android.AssertStringDoesContain(t, "verify apk cmd args", verifyApkCmd, verifyApkArgs) 2695 2696 // Test that all present libraries are preopted, including implicit SDK dependencies, possibly stubs 2697 cmd := app.Rule("dexpreopt").RuleParams.Command 2698 w := `--target-context-for-sdk any ` + 2699 `PCL[/system/framework/qux.jar]#` + 2700 `PCL[/system/framework/quuz.jar]#` + 2701 `PCL[/system/framework/foo.jar]#` + 2702 `PCL[/system/framework/non-sdk-lib.jar]#` + 2703 `PCL[/system/framework/bar.jar]#` + 2704 `PCL[/system/framework/runtime-library.jar]#` + 2705 `PCL[/system/framework/runtime-required-x.jar]#` + 2706 `PCL[/system/framework/runtime-optional-x.jar]#` + 2707 `PCL[/system/framework/runtime-required-y.jar]#` + 2708 `PCL[/system/framework/runtime-optional-y.jar] ` 2709 android.AssertStringDoesContain(t, "dexpreopt app cmd args", cmd, w) 2710 2711 // Test conditional context for target SDK version 28. 2712 android.AssertStringDoesContain(t, "dexpreopt app cmd 28", cmd, 2713 `--target-context-for-sdk 28`+ 2714 ` PCL[/system/framework/org.apache.http.legacy.jar] `) 2715 2716 // Test conditional context for target SDK version 29. 2717 android.AssertStringDoesContain(t, "dexpreopt app cmd 29", cmd, 2718 `--target-context-for-sdk 29`+ 2719 ` PCL[/system/framework/android.hidl.manager-V1.0-java.jar]`+ 2720 `#PCL[/system/framework/android.hidl.base-V1.0-java.jar] `) 2721 2722 // Test conditional context for target SDK version 30. 2723 // "android.test.mock" is absent because "android.test.runner" is not used. 2724 android.AssertStringDoesContain(t, "dexpreopt app cmd 30", cmd, 2725 `--target-context-for-sdk 30`+ 2726 ` PCL[/system/framework/android.test.base.jar] `) 2727 2728 cmd = prebuilt.Rule("dexpreopt").RuleParams.Command 2729 android.AssertStringDoesContain(t, "dexpreopt prebuilt cmd", cmd, 2730 `--target-context-for-sdk any`+ 2731 ` PCL[/system/framework/foo.jar]`+ 2732 `#PCL[/system/framework/non-sdk-lib.jar]`+ 2733 `#PCL[/system/framework/android.test.runner.jar]`+ 2734 `#PCL[/system/framework/bar.jar] `) 2735 2736 // Test conditional context for target SDK version 30. 2737 // "android.test.mock" is present because "android.test.runner" is used. 2738 android.AssertStringDoesContain(t, "dexpreopt prebuilt cmd 30", cmd, 2739 `--target-context-for-sdk 30`+ 2740 ` PCL[/system/framework/android.test.base.jar]`+ 2741 `#PCL[/system/framework/android.test.mock.jar] `) 2742} 2743 2744func TestDexpreoptBcp(t *testing.T) { 2745 bp := ` 2746 java_sdk_library { 2747 name: "foo", 2748 srcs: ["a.java"], 2749 api_packages: ["foo"], 2750 sdk_version: "current", 2751 } 2752 2753 java_sdk_library { 2754 name: "bar", 2755 srcs: ["a.java"], 2756 api_packages: ["bar"], 2757 permitted_packages: ["bar"], 2758 sdk_version: "current", 2759 } 2760 2761 android_app { 2762 name: "app", 2763 srcs: ["a.java"], 2764 sdk_version: "current", 2765 } 2766 ` 2767 2768 testCases := []struct { 2769 name string 2770 with bool 2771 expect string 2772 }{ 2773 { 2774 name: "with updatable bcp", 2775 with: true, 2776 expect: "/system/framework/foo.jar:/system/framework/bar.jar", 2777 }, 2778 { 2779 name: "without updatable bcp", 2780 with: false, 2781 expect: "/system/framework/foo.jar", 2782 }, 2783 } 2784 2785 for _, test := range testCases { 2786 t.Run(test.name, func(t *testing.T) { 2787 result := android.GroupFixturePreparers( 2788 prepareForJavaTest, 2789 PrepareForTestWithJavaSdkLibraryFiles, 2790 FixtureWithLastReleaseApis("runtime-library", "foo", "bar"), 2791 dexpreopt.FixtureSetBootJars("platform:foo"), 2792 dexpreopt.FixtureSetApexBootJars("platform:bar"), 2793 dexpreopt.FixtureSetPreoptWithUpdatableBcp(test.with), 2794 ).RunTestWithBp(t, bp) 2795 2796 app := result.ModuleForTests("app", "android_common") 2797 cmd := app.Rule("dexpreopt").RuleParams.Command 2798 bcp := " -Xbootclasspath-locations:" + test.expect + " " // space at the end matters 2799 android.AssertStringDoesContain(t, "dexpreopt app bcp", cmd, bcp) 2800 }) 2801 } 2802} 2803 2804func TestCodelessApp(t *testing.T) { 2805 testCases := []struct { 2806 name string 2807 bp string 2808 noCode bool 2809 }{ 2810 { 2811 name: "normal", 2812 bp: ` 2813 android_app { 2814 name: "foo", 2815 srcs: ["a.java"], 2816 sdk_version: "current", 2817 } 2818 `, 2819 noCode: false, 2820 }, 2821 { 2822 name: "app without sources", 2823 bp: ` 2824 android_app { 2825 name: "foo", 2826 sdk_version: "current", 2827 } 2828 `, 2829 noCode: true, 2830 }, 2831 { 2832 name: "app with libraries", 2833 bp: ` 2834 android_app { 2835 name: "foo", 2836 static_libs: ["lib"], 2837 sdk_version: "current", 2838 } 2839 2840 java_library { 2841 name: "lib", 2842 srcs: ["a.java"], 2843 sdk_version: "current", 2844 } 2845 `, 2846 noCode: false, 2847 }, 2848 { 2849 name: "app with sourceless libraries", 2850 bp: ` 2851 android_app { 2852 name: "foo", 2853 static_libs: ["lib"], 2854 sdk_version: "current", 2855 } 2856 2857 java_library { 2858 name: "lib", 2859 sdk_version: "current", 2860 } 2861 `, 2862 // TODO(jungjw): this should probably be true 2863 noCode: false, 2864 }, 2865 } 2866 2867 for _, test := range testCases { 2868 t.Run(test.name, func(t *testing.T) { 2869 ctx := testApp(t, test.bp) 2870 2871 foo := ctx.ModuleForTests("foo", "android_common") 2872 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"] 2873 if strings.Contains(manifestFixerArgs, "--has-no-code") != test.noCode { 2874 t.Errorf("unexpected manifest_fixer args: %q", manifestFixerArgs) 2875 } 2876 }) 2877 } 2878} 2879 2880func TestUncompressDex(t *testing.T) { 2881 testCases := []struct { 2882 name string 2883 bp string 2884 2885 uncompressedPlatform bool 2886 uncompressedUnbundled bool 2887 }{ 2888 { 2889 name: "normal", 2890 bp: ` 2891 android_app { 2892 name: "foo", 2893 srcs: ["a.java"], 2894 sdk_version: "current", 2895 } 2896 `, 2897 uncompressedPlatform: true, 2898 uncompressedUnbundled: false, 2899 }, 2900 { 2901 name: "use_embedded_dex", 2902 bp: ` 2903 android_app { 2904 name: "foo", 2905 use_embedded_dex: true, 2906 srcs: ["a.java"], 2907 sdk_version: "current", 2908 } 2909 `, 2910 uncompressedPlatform: true, 2911 uncompressedUnbundled: true, 2912 }, 2913 { 2914 name: "privileged", 2915 bp: ` 2916 android_app { 2917 name: "foo", 2918 privileged: true, 2919 srcs: ["a.java"], 2920 sdk_version: "current", 2921 } 2922 `, 2923 uncompressedPlatform: true, 2924 uncompressedUnbundled: true, 2925 }, 2926 { 2927 name: "normal_uncompress_dex_true", 2928 bp: ` 2929 android_app { 2930 name: "foo", 2931 srcs: ["a.java"], 2932 sdk_version: "current", 2933 uncompress_dex: true, 2934 } 2935 `, 2936 uncompressedPlatform: true, 2937 uncompressedUnbundled: true, 2938 }, 2939 { 2940 name: "normal_uncompress_dex_false", 2941 bp: ` 2942 android_app { 2943 name: "foo", 2944 srcs: ["a.java"], 2945 sdk_version: "current", 2946 uncompress_dex: false, 2947 } 2948 `, 2949 uncompressedPlatform: false, 2950 uncompressedUnbundled: false, 2951 }, 2952 } 2953 2954 test := func(t *testing.T, bp string, want bool, unbundled bool) { 2955 t.Helper() 2956 2957 result := android.GroupFixturePreparers( 2958 prepareForJavaTest, 2959 PrepareForTestWithPrebuiltsOfCurrentApi, 2960 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 2961 if unbundled { 2962 variables.Unbundled_build = proptools.BoolPtr(true) 2963 variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true) 2964 } 2965 }), 2966 ).RunTestWithBp(t, bp) 2967 2968 foo := result.ModuleForTests("foo", "android_common") 2969 dex := foo.Rule("r8") 2970 uncompressedInDexJar := strings.Contains(dex.Args["zipFlags"], "-L 0") 2971 aligned := foo.MaybeRule("zipalign").Rule != nil 2972 2973 android.AssertBoolEquals(t, "uncompressed in dex", want, uncompressedInDexJar) 2974 2975 android.AssertBoolEquals(t, "aligne", want, aligned) 2976 } 2977 2978 for _, tt := range testCases { 2979 t.Run(tt.name, func(t *testing.T) { 2980 t.Run("platform", func(t *testing.T) { 2981 test(t, tt.bp, tt.uncompressedPlatform, false) 2982 }) 2983 t.Run("unbundled", func(t *testing.T) { 2984 test(t, tt.bp, tt.uncompressedUnbundled, true) 2985 }) 2986 }) 2987 } 2988} 2989 2990func checkAapt2LinkFlag(t *testing.T, aapt2Flags, flagName, expectedValue string) { 2991 if expectedValue != "" { 2992 expectedFlag := "--" + flagName + " " + expectedValue 2993 if !strings.Contains(aapt2Flags, expectedFlag) { 2994 t.Errorf("%q is missing in aapt2 link flags, %q", expectedFlag, aapt2Flags) 2995 } 2996 } else { 2997 unexpectedFlag := "--" + flagName 2998 if strings.Contains(aapt2Flags, unexpectedFlag) { 2999 t.Errorf("unexpected flag, %q is found in aapt2 link flags, %q", unexpectedFlag, aapt2Flags) 3000 } 3001 } 3002} 3003 3004func TestExportedProguardFlagFiles(t *testing.T) { 3005 ctx, _ := testJava(t, ` 3006 android_app { 3007 name: "foo", 3008 sdk_version: "current", 3009 static_libs: ["lib1"], 3010 } 3011 3012 android_library { 3013 name: "lib1", 3014 sdk_version: "current", 3015 optimize: { 3016 proguard_flags_files: ["lib1proguard.cfg"], 3017 } 3018 } 3019 `) 3020 3021 m := ctx.ModuleForTests("foo", "android_common") 3022 hasLib1Proguard := false 3023 for _, s := range m.Rule("java.r8").Implicits.Strings() { 3024 if s == "lib1proguard.cfg" { 3025 hasLib1Proguard = true 3026 break 3027 } 3028 } 3029 3030 if !hasLib1Proguard { 3031 t.Errorf("App does not use library proguard config") 3032 } 3033} 3034 3035func TestTargetSdkVersionManifestFixer(t *testing.T) { 3036 platform_sdk_codename := "Tiramisu" 3037 platform_sdk_version := 33 3038 testCases := []struct { 3039 name string 3040 targetSdkVersionInBp string 3041 targetSdkVersionExpected string 3042 unbundledBuild bool 3043 platformSdkFinal bool 3044 }{ 3045 { 3046 name: "Non-Unbundled build: Android.bp has targetSdkVersion", 3047 targetSdkVersionInBp: "30", 3048 targetSdkVersionExpected: "30", 3049 unbundledBuild: false, 3050 }, 3051 { 3052 name: "Unbundled build: Android.bp has targetSdkVersion", 3053 targetSdkVersionInBp: "30", 3054 targetSdkVersionExpected: "30", 3055 unbundledBuild: true, 3056 }, 3057 { 3058 name: "Non-Unbundled build: Android.bp has targetSdkVersion equal to platform_sdk_codename", 3059 targetSdkVersionInBp: platform_sdk_codename, 3060 targetSdkVersionExpected: platform_sdk_codename, 3061 unbundledBuild: false, 3062 }, 3063 { 3064 name: "Unbundled build: Android.bp has targetSdkVersion equal to platform_sdk_codename", 3065 targetSdkVersionInBp: platform_sdk_codename, 3066 targetSdkVersionExpected: "10000", 3067 unbundledBuild: true, 3068 }, 3069 3070 { 3071 name: "Non-Unbundled build: Android.bp has no targetSdkVersion", 3072 targetSdkVersionExpected: platform_sdk_codename, 3073 unbundledBuild: false, 3074 }, 3075 { 3076 name: "Unbundled build: Android.bp has no targetSdkVersion", 3077 targetSdkVersionExpected: "10000", 3078 unbundledBuild: true, 3079 }, 3080 { 3081 name: "Bundled build in REL branches", 3082 targetSdkVersionExpected: "33", 3083 unbundledBuild: false, 3084 platformSdkFinal: true, 3085 }, 3086 } 3087 for _, testCase := range testCases { 3088 targetSdkVersionTemplate := "" 3089 if testCase.targetSdkVersionInBp != "" { 3090 targetSdkVersionTemplate = fmt.Sprintf(`target_sdk_version: "%s",`, testCase.targetSdkVersionInBp) 3091 } 3092 bp := fmt.Sprintf(` 3093 android_app { 3094 name: "foo", 3095 sdk_version: "current", 3096 %s 3097 } 3098 `, targetSdkVersionTemplate) 3099 fixture := android.GroupFixturePreparers( 3100 prepareForJavaTest, 3101 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 3102 if testCase.platformSdkFinal { 3103 variables.Platform_sdk_final = proptools.BoolPtr(true) 3104 } 3105 // explicitly set platform_sdk_codename to make the test deterministic 3106 variables.Platform_sdk_codename = &platform_sdk_codename 3107 variables.Platform_sdk_version = &platform_sdk_version 3108 variables.Platform_version_active_codenames = []string{platform_sdk_codename} 3109 // create a non-empty list if unbundledBuild==true 3110 if testCase.unbundledBuild { 3111 variables.Unbundled_build_apps = []string{"apex_a", "apex_b"} 3112 } 3113 }), 3114 ) 3115 3116 result := fixture.RunTestWithBp(t, bp) 3117 foo := result.ModuleForTests("foo", "android_common") 3118 3119 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"] 3120 android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected) 3121 } 3122} 3123 3124func TestDefaultAppTargetSdkVersionForUpdatableModules(t *testing.T) { 3125 platform_sdk_codename := "Tiramisu" 3126 platform_sdk_version := 33 3127 testCases := []struct { 3128 name string 3129 platform_sdk_final bool 3130 targetSdkVersionInBp *string 3131 targetSdkVersionExpected *string 3132 updatable bool 3133 }{ 3134 { 3135 name: "Non-Updatable Module: Android.bp has older targetSdkVersion", 3136 targetSdkVersionInBp: proptools.StringPtr("29"), 3137 targetSdkVersionExpected: proptools.StringPtr("29"), 3138 updatable: false, 3139 }, 3140 { 3141 name: "Updatable Module: Android.bp has older targetSdkVersion", 3142 targetSdkVersionInBp: proptools.StringPtr("30"), 3143 targetSdkVersionExpected: proptools.StringPtr("30"), 3144 updatable: true, 3145 }, 3146 { 3147 name: "Updatable Module: Android.bp has no targetSdkVersion", 3148 targetSdkVersionExpected: proptools.StringPtr("10000"), 3149 updatable: true, 3150 }, 3151 { 3152 name: "[SDK finalised] Non-Updatable Module: Android.bp has older targetSdkVersion", 3153 platform_sdk_final: true, 3154 targetSdkVersionInBp: proptools.StringPtr("30"), 3155 targetSdkVersionExpected: proptools.StringPtr("30"), 3156 updatable: false, 3157 }, 3158 { 3159 name: "[SDK finalised] Updatable Module: Android.bp has older targetSdkVersion", 3160 platform_sdk_final: true, 3161 targetSdkVersionInBp: proptools.StringPtr("30"), 3162 targetSdkVersionExpected: proptools.StringPtr("30"), 3163 updatable: true, 3164 }, 3165 { 3166 name: "[SDK finalised] Updatable Module: Android.bp has targetSdkVersion as platform sdk codename", 3167 platform_sdk_final: true, 3168 targetSdkVersionInBp: proptools.StringPtr(platform_sdk_codename), 3169 targetSdkVersionExpected: proptools.StringPtr("33"), 3170 updatable: true, 3171 }, 3172 { 3173 name: "[SDK finalised] Updatable Module: Android.bp has no targetSdkVersion", 3174 platform_sdk_final: true, 3175 targetSdkVersionExpected: proptools.StringPtr("33"), 3176 updatable: true, 3177 }, 3178 } 3179 for _, testCase := range testCases { 3180 targetSdkVersionTemplate := "" 3181 if testCase.targetSdkVersionInBp != nil { 3182 targetSdkVersionTemplate = fmt.Sprintf(`target_sdk_version: "%s",`, *testCase.targetSdkVersionInBp) 3183 } 3184 bp := fmt.Sprintf(` 3185 android_app { 3186 name: "foo", 3187 sdk_version: "current", 3188 min_sdk_version: "29", 3189 %s 3190 updatable: %t, 3191 enforce_default_target_sdk_version: %t 3192 } 3193 `, targetSdkVersionTemplate, testCase.updatable, testCase.updatable) // enforce default target sdk version if app is updatable 3194 3195 fixture := android.GroupFixturePreparers( 3196 PrepareForTestWithJavaDefaultModules, 3197 android.PrepareForTestWithAllowMissingDependencies, 3198 android.PrepareForTestWithAndroidMk, 3199 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 3200 // explicitly set following platform variables to make the test deterministic 3201 variables.Platform_sdk_final = &testCase.platform_sdk_final 3202 variables.Platform_sdk_version = &platform_sdk_version 3203 variables.Platform_sdk_codename = &platform_sdk_codename 3204 variables.Platform_version_active_codenames = []string{platform_sdk_codename} 3205 variables.Unbundled_build = proptools.BoolPtr(true) 3206 variables.Unbundled_build_apps = []string{"sampleModule"} 3207 }), 3208 ) 3209 3210 result := fixture.RunTestWithBp(t, bp) 3211 foo := result.ModuleForTests("foo", "android_common") 3212 3213 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"] 3214 android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+*testCase.targetSdkVersionExpected) 3215 } 3216} 3217 3218func TestEnforceDefaultAppTargetSdkVersionFlag(t *testing.T) { 3219 platform_sdk_codename := "Tiramisu" 3220 platform_sdk_version := 33 3221 testCases := []struct { 3222 name string 3223 enforceDefaultTargetSdkVersion bool 3224 expectedError string 3225 platform_sdk_final bool 3226 targetSdkVersionInBp string 3227 targetSdkVersionExpected string 3228 updatable bool 3229 }{ 3230 { 3231 name: "Not enforcing Target SDK Version: Android.bp has older targetSdkVersion", 3232 enforceDefaultTargetSdkVersion: false, 3233 targetSdkVersionInBp: "29", 3234 targetSdkVersionExpected: "29", 3235 updatable: false, 3236 }, 3237 { 3238 name: "[SDK finalised] Enforce Target SDK Version: Android.bp has current targetSdkVersion", 3239 enforceDefaultTargetSdkVersion: true, 3240 platform_sdk_final: true, 3241 targetSdkVersionInBp: "current", 3242 targetSdkVersionExpected: "33", 3243 updatable: true, 3244 }, 3245 { 3246 name: "Enforce Target SDK Version: Android.bp has current targetSdkVersion", 3247 enforceDefaultTargetSdkVersion: true, 3248 platform_sdk_final: false, 3249 targetSdkVersionInBp: "current", 3250 targetSdkVersionExpected: "10000", 3251 updatable: false, 3252 }, 3253 { 3254 name: "Not enforcing Target SDK Version for Updatable app", 3255 enforceDefaultTargetSdkVersion: false, 3256 expectedError: "Updatable apps must enforce default target sdk version", 3257 targetSdkVersionInBp: "29", 3258 targetSdkVersionExpected: "29", 3259 updatable: true, 3260 }, 3261 } 3262 for _, testCase := range testCases { 3263 errExpected := testCase.expectedError != "" 3264 bp := fmt.Sprintf(` 3265 android_app { 3266 name: "foo", 3267 enforce_default_target_sdk_version: %t, 3268 sdk_version: "current", 3269 min_sdk_version: "29", 3270 target_sdk_version: "%v", 3271 updatable: %t 3272 } 3273 `, testCase.enforceDefaultTargetSdkVersion, testCase.targetSdkVersionInBp, testCase.updatable) 3274 3275 fixture := android.GroupFixturePreparers( 3276 PrepareForTestWithJavaDefaultModules, 3277 android.PrepareForTestWithAllowMissingDependencies, 3278 android.PrepareForTestWithAndroidMk, 3279 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 3280 // explicitly set following platform variables to make the test deterministic 3281 variables.Platform_sdk_final = &testCase.platform_sdk_final 3282 variables.Platform_sdk_version = &platform_sdk_version 3283 variables.Platform_sdk_codename = &platform_sdk_codename 3284 variables.Unbundled_build = proptools.BoolPtr(true) 3285 variables.Unbundled_build_apps = []string{"sampleModule"} 3286 }), 3287 ) 3288 3289 errorHandler := android.FixtureExpectsNoErrors 3290 if errExpected { 3291 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.expectedError) 3292 } 3293 result := fixture.ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, bp) 3294 3295 if !errExpected { 3296 foo := result.ModuleForTests("foo", "android_common") 3297 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"] 3298 android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected) 3299 } 3300 } 3301} 3302 3303func TestEnforceDefaultAppTargetSdkVersionFlagForTests(t *testing.T) { 3304 platform_sdk_codename := "Tiramisu" 3305 platform_sdk_version := 33 3306 testCases := []struct { 3307 name string 3308 enforceDefaultTargetSdkVersion bool 3309 expectedError string 3310 platform_sdk_final bool 3311 targetSdkVersionInBp string 3312 targetSdkVersionExpected string 3313 }{ 3314 { 3315 name: "Not enforcing Target SDK Version: Android.bp has older targetSdkVersion", 3316 enforceDefaultTargetSdkVersion: false, 3317 targetSdkVersionInBp: "29", 3318 targetSdkVersionExpected: "29", 3319 }, 3320 { 3321 name: "[SDK finalised] Enforce Target SDK Version: Android.bp has current targetSdkVersion", 3322 enforceDefaultTargetSdkVersion: true, 3323 platform_sdk_final: true, 3324 targetSdkVersionInBp: "current", 3325 targetSdkVersionExpected: "33", 3326 }, 3327 { 3328 name: "Enforce Target SDK Version: Android.bp has current targetSdkVersion", 3329 enforceDefaultTargetSdkVersion: true, 3330 platform_sdk_final: false, 3331 targetSdkVersionInBp: "current", 3332 targetSdkVersionExpected: "10000", 3333 }, 3334 } 3335 for _, testCase := range testCases { 3336 errExpected := testCase.expectedError != "" 3337 bp := fmt.Sprintf(` 3338 android_test { 3339 name: "foo", 3340 enforce_default_target_sdk_version: %t, 3341 min_sdk_version: "29", 3342 target_sdk_version: "%v", 3343 } 3344 `, testCase.enforceDefaultTargetSdkVersion, testCase.targetSdkVersionInBp) 3345 3346 fixture := android.GroupFixturePreparers( 3347 PrepareForTestWithJavaDefaultModules, 3348 android.PrepareForTestWithAllowMissingDependencies, 3349 android.PrepareForTestWithAndroidMk, 3350 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 3351 // explicitly set following platform variables to make the test deterministic 3352 variables.Platform_sdk_final = &testCase.platform_sdk_final 3353 variables.Platform_sdk_version = &platform_sdk_version 3354 variables.Platform_sdk_codename = &platform_sdk_codename 3355 variables.Unbundled_build = proptools.BoolPtr(true) 3356 variables.Unbundled_build_apps = []string{"sampleModule"} 3357 }), 3358 ) 3359 3360 errorHandler := android.FixtureExpectsNoErrors 3361 if errExpected { 3362 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.expectedError) 3363 } 3364 result := fixture.ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, bp) 3365 3366 if !errExpected { 3367 foo := result.ModuleForTests("foo", "android_common") 3368 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"] 3369 android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected) 3370 } 3371 } 3372} 3373 3374func TestAppMissingCertificateAllowMissingDependencies(t *testing.T) { 3375 result := android.GroupFixturePreparers( 3376 PrepareForTestWithJavaDefaultModules, 3377 android.PrepareForTestWithAllowMissingDependencies, 3378 android.PrepareForTestWithAndroidMk, 3379 ).RunTestWithBp(t, ` 3380 android_app { 3381 name: "foo", 3382 srcs: ["a.java"], 3383 certificate: ":missing_certificate", 3384 sdk_version: "current", 3385 } 3386 3387 android_app { 3388 name: "bar", 3389 srcs: ["a.java"], 3390 certificate: ":missing_certificate", 3391 product_specific: true, 3392 sdk_version: "current", 3393 }`) 3394 3395 foo := result.ModuleForTests("foo", "android_common") 3396 fooApk := foo.Output("foo.apk") 3397 if fooApk.Rule != android.ErrorRule { 3398 t.Fatalf("expected ErrorRule for foo.apk, got %s", fooApk.Rule.String()) 3399 } 3400 android.AssertStringDoesContain(t, "expected error rule message", fooApk.Args["error"], "missing dependencies: missing_certificate\n") 3401} 3402 3403func TestAppIncludesJniPackages(t *testing.T) { 3404 ctx := android.GroupFixturePreparers( 3405 PrepareForTestWithJavaDefaultModules, 3406 ).RunTestWithBp(t, ` 3407 android_library_import { 3408 name: "aary-nodeps", 3409 aars: ["aary.aar"], 3410 extract_jni: true, 3411 } 3412 3413 android_library { 3414 name: "aary-lib", 3415 sdk_version: "current", 3416 min_sdk_version: "21", 3417 static_libs: ["aary-nodeps"], 3418 } 3419 3420 android_app { 3421 name: "aary-lib-dep", 3422 sdk_version: "current", 3423 min_sdk_version: "21", 3424 manifest: "AndroidManifest.xml", 3425 static_libs: ["aary-lib"], 3426 use_embedded_native_libs: true, 3427 } 3428 3429 android_app { 3430 name: "aary-import-dep", 3431 sdk_version: "current", 3432 min_sdk_version: "21", 3433 manifest: "AndroidManifest.xml", 3434 static_libs: ["aary-nodeps"], 3435 use_embedded_native_libs: true, 3436 } 3437 3438 android_app { 3439 name: "aary-no-use-embedded", 3440 sdk_version: "current", 3441 min_sdk_version: "21", 3442 manifest: "AndroidManifest.xml", 3443 static_libs: ["aary-nodeps"], 3444 }`) 3445 3446 testCases := []struct { 3447 name string 3448 hasPackage bool 3449 }{ 3450 { 3451 name: "aary-import-dep", 3452 hasPackage: true, 3453 }, 3454 { 3455 name: "aary-lib-dep", 3456 hasPackage: true, 3457 }, 3458 { 3459 name: "aary-no-use-embedded", 3460 hasPackage: false, 3461 }, 3462 } 3463 3464 for _, tc := range testCases { 3465 t.Run(tc.name, func(t *testing.T) { 3466 app := ctx.ModuleForTests(tc.name, "android_common") 3467 3468 outputFile := "jnilibs.zip" 3469 jniOutputLibZip := app.MaybeOutput(outputFile) 3470 if jniOutputLibZip.Rule == nil && !tc.hasPackage { 3471 return 3472 } 3473 3474 jniPackage := "arm64-v8a_jni.zip" 3475 inputs := jniOutputLibZip.Inputs 3476 foundPackage := false 3477 for i := 0; i < len(inputs); i++ { 3478 if strings.Contains(inputs[i].String(), jniPackage) { 3479 foundPackage = true 3480 } 3481 } 3482 if foundPackage != tc.hasPackage { 3483 t.Errorf("expected to find %v in %v inputs; inputs = %v", jniPackage, outputFile, inputs) 3484 } 3485 }) 3486 } 3487} 3488 3489func TestTargetSdkVersionMtsTests(t *testing.T) { 3490 platformSdkCodename := "Tiramisu" 3491 android_test := "android_test" 3492 android_test_helper_app := "android_test_helper_app" 3493 bpTemplate := ` 3494 %v { 3495 name: "mytest", 3496 target_sdk_version: "%v", 3497 test_suites: ["othersuite", "%v"], 3498 } 3499 ` 3500 testCases := []struct { 3501 desc string 3502 moduleType string 3503 targetSdkVersionInBp string 3504 targetSdkVersionExpected string 3505 testSuites string 3506 }{ 3507 { 3508 desc: "Non-MTS android_test_apps targeting current should not be upgraded to 10000", 3509 moduleType: android_test, 3510 targetSdkVersionInBp: "current", 3511 targetSdkVersionExpected: platformSdkCodename, 3512 testSuites: "non-mts-suite", 3513 }, 3514 { 3515 desc: "MTS android_test_apps targeting released sdks should not be upgraded to 10000", 3516 moduleType: android_test, 3517 targetSdkVersionInBp: "29", 3518 targetSdkVersionExpected: "29", 3519 testSuites: "mts-suite", 3520 }, 3521 { 3522 desc: "MTS android_test_apps targeting current should be upgraded to 10000", 3523 moduleType: android_test, 3524 targetSdkVersionInBp: "current", 3525 targetSdkVersionExpected: "10000", 3526 testSuites: "mts-suite", 3527 }, 3528 { 3529 desc: "MTS android_test_helper_apps targeting current should be upgraded to 10000", 3530 moduleType: android_test_helper_app, 3531 targetSdkVersionInBp: "current", 3532 targetSdkVersionExpected: "10000", 3533 testSuites: "mts-suite", 3534 }, 3535 } 3536 fixture := android.GroupFixturePreparers( 3537 prepareForJavaTest, 3538 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 3539 variables.Platform_sdk_codename = &platformSdkCodename 3540 variables.Platform_version_active_codenames = []string{platformSdkCodename} 3541 }), 3542 ) 3543 for _, testCase := range testCases { 3544 result := fixture.RunTestWithBp(t, fmt.Sprintf(bpTemplate, testCase.moduleType, testCase.targetSdkVersionInBp, testCase.testSuites)) 3545 mytest := result.ModuleForTests("mytest", "android_common") 3546 manifestFixerArgs := mytest.Output("manifest_fixer/AndroidManifest.xml").Args["args"] 3547 android.AssertStringDoesContain(t, testCase.desc, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected) 3548 } 3549} 3550