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 "android/soong/genrule" 31) 32 33// testApp runs tests using the prepareForJavaTest 34// 35// See testJava for an explanation as to how to stop using this deprecated method. 36// 37// deprecated 38func testApp(t *testing.T, bp string) *android.TestContext { 39 t.Helper() 40 result := prepareForJavaTest.RunTestWithBp(t, bp) 41 return result.TestContext 42} 43 44func TestApp(t *testing.T) { 45 resourceFiles := []string{ 46 "res/layout/layout.xml", 47 "res/values/strings.xml", 48 "res/values-en-rUS/strings.xml", 49 } 50 51 compiledResourceFiles := []string{ 52 "aapt2/res/layout_layout.xml.flat", 53 "aapt2/res/values_strings.arsc.flat", 54 "aapt2/res/values-en-rUS_strings.arsc.flat", 55 } 56 57 for _, moduleType := range []string{"android_app", "android_library"} { 58 t.Run(moduleType, func(t *testing.T) { 59 result := android.GroupFixturePreparers( 60 prepareForJavaTest, 61 android.FixtureModifyMockFS(func(fs android.MockFS) { 62 for _, file := range resourceFiles { 63 fs[file] = nil 64 } 65 }), 66 ).RunTestWithBp(t, moduleType+` { 67 name: "foo", 68 srcs: ["a.java"], 69 sdk_version: "current" 70 } 71 `) 72 73 foo := result.ModuleForTests("foo", "android_common") 74 75 var expectedLinkImplicits []string 76 77 manifestFixer := foo.Output("manifest_fixer/AndroidManifest.xml") 78 expectedLinkImplicits = append(expectedLinkImplicits, manifestFixer.Output.String()) 79 80 frameworkRes := result.ModuleForTests("framework-res", "android_common") 81 expectedLinkImplicits = append(expectedLinkImplicits, 82 frameworkRes.Output("package-res.apk").Output.String()) 83 84 // Test the mapping from input files to compiled output file names 85 compile := foo.Output(compiledResourceFiles[0]) 86 android.AssertDeepEquals(t, "aapt2 compile inputs", resourceFiles, compile.Inputs.Strings()) 87 88 compiledResourceOutputs := compile.Outputs.Strings() 89 sort.Strings(compiledResourceOutputs) 90 91 expectedLinkImplicits = append(expectedLinkImplicits, compiledResourceOutputs...) 92 93 list := foo.Output("aapt2/res.list") 94 expectedLinkImplicits = append(expectedLinkImplicits, list.Output.String()) 95 96 // Check that the link rule uses 97 res := result.ModuleForTests("foo", "android_common").Output("package-res.apk") 98 android.AssertDeepEquals(t, "aapt2 link implicits", expectedLinkImplicits, res.Implicits.Strings()) 99 }) 100 } 101} 102 103func TestAppSplits(t *testing.T) { 104 ctx := testApp(t, ` 105 android_app { 106 name: "foo", 107 srcs: ["a.java"], 108 package_splits: ["v4", "v7,hdpi"], 109 sdk_version: "current" 110 }`) 111 112 foo := ctx.ModuleForTests("foo", "android_common") 113 114 expectedOutputs := []string{ 115 "out/soong/.intermediates/foo/android_common/foo.apk", 116 "out/soong/.intermediates/foo/android_common/foo_v4.apk", 117 "out/soong/.intermediates/foo/android_common/foo_v7_hdpi.apk", 118 } 119 for _, expectedOutput := range expectedOutputs { 120 foo.Output(expectedOutput) 121 } 122 123 outputFiles, err := foo.Module().(*AndroidApp).OutputFiles("") 124 if err != nil { 125 t.Fatal(err) 126 } 127 android.AssertPathsRelativeToTopEquals(t, `OutputFiles("")`, expectedOutputs, outputFiles) 128} 129 130func TestPlatformAPIs(t *testing.T) { 131 testJava(t, ` 132 android_app { 133 name: "foo", 134 srcs: ["a.java"], 135 platform_apis: true, 136 } 137 `) 138 139 testJava(t, ` 140 android_app { 141 name: "foo", 142 srcs: ["a.java"], 143 sdk_version: "current", 144 } 145 `) 146 147 testJavaError(t, "platform_apis must be true when sdk_version is empty.", ` 148 android_app { 149 name: "bar", 150 srcs: ["b.java"], 151 } 152 `) 153 154 testJavaError(t, "platform_apis must be false when sdk_version is not empty.", ` 155 android_app { 156 name: "bar", 157 srcs: ["b.java"], 158 sdk_version: "system_current", 159 platform_apis: true, 160 } 161 `) 162} 163 164func TestAndroidAppLinkType(t *testing.T) { 165 testJava(t, ` 166 android_app { 167 name: "foo", 168 srcs: ["a.java"], 169 libs: ["bar"], 170 static_libs: ["baz"], 171 platform_apis: true, 172 } 173 174 java_library { 175 name: "bar", 176 sdk_version: "current", 177 srcs: ["b.java"], 178 } 179 180 android_library { 181 name: "baz", 182 sdk_version: "system_current", 183 srcs: ["c.java"], 184 } 185 `) 186 187 testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", ` 188 android_app { 189 name: "foo", 190 srcs: ["a.java"], 191 libs: ["bar"], 192 sdk_version: "current", 193 static_libs: ["baz"], 194 } 195 196 java_library { 197 name: "bar", 198 sdk_version: "current", 199 srcs: ["b.java"], 200 } 201 202 android_library { 203 name: "baz", 204 sdk_version: "system_current", 205 srcs: ["c.java"], 206 } 207 `) 208 209 testJava(t, ` 210 android_app { 211 name: "foo", 212 srcs: ["a.java"], 213 libs: ["bar"], 214 sdk_version: "system_current", 215 static_libs: ["baz"], 216 } 217 218 java_library { 219 name: "bar", 220 sdk_version: "current", 221 srcs: ["b.java"], 222 } 223 224 android_library { 225 name: "baz", 226 sdk_version: "system_current", 227 srcs: ["c.java"], 228 } 229 `) 230 231 testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", ` 232 android_app { 233 name: "foo", 234 srcs: ["a.java"], 235 libs: ["bar"], 236 sdk_version: "system_current", 237 static_libs: ["baz"], 238 } 239 240 java_library { 241 name: "bar", 242 sdk_version: "current", 243 srcs: ["b.java"], 244 } 245 246 android_library { 247 name: "baz", 248 srcs: ["c.java"], 249 } 250 `) 251} 252 253func TestUpdatableApps(t *testing.T) { 254 testCases := []struct { 255 name string 256 bp string 257 expectedError string 258 }{ 259 { 260 name: "Stable public SDK", 261 bp: `android_app { 262 name: "foo", 263 srcs: ["a.java"], 264 sdk_version: "29", 265 min_sdk_version: "29", 266 updatable: true, 267 }`, 268 }, 269 { 270 name: "Stable system SDK", 271 bp: `android_app { 272 name: "foo", 273 srcs: ["a.java"], 274 sdk_version: "system_29", 275 min_sdk_version: "29", 276 updatable: true, 277 }`, 278 }, 279 { 280 name: "Current public SDK", 281 bp: `android_app { 282 name: "foo", 283 srcs: ["a.java"], 284 sdk_version: "current", 285 min_sdk_version: "29", 286 updatable: true, 287 }`, 288 }, 289 { 290 name: "Current system SDK", 291 bp: `android_app { 292 name: "foo", 293 srcs: ["a.java"], 294 sdk_version: "system_current", 295 min_sdk_version: "29", 296 updatable: true, 297 }`, 298 }, 299 { 300 name: "Current module SDK", 301 bp: `android_app { 302 name: "foo", 303 srcs: ["a.java"], 304 sdk_version: "module_current", 305 min_sdk_version: "29", 306 updatable: true, 307 }`, 308 }, 309 { 310 name: "Current core SDK", 311 bp: `android_app { 312 name: "foo", 313 srcs: ["a.java"], 314 sdk_version: "core_current", 315 min_sdk_version: "29", 316 updatable: true, 317 }`, 318 }, 319 { 320 name: "No Platform APIs", 321 bp: `android_app { 322 name: "foo", 323 srcs: ["a.java"], 324 platform_apis: true, 325 min_sdk_version: "29", 326 updatable: true, 327 }`, 328 expectedError: "Updatable apps must use stable SDKs", 329 }, 330 { 331 name: "No Core Platform APIs", 332 bp: `android_app { 333 name: "foo", 334 srcs: ["a.java"], 335 sdk_version: "core_platform", 336 min_sdk_version: "29", 337 updatable: true, 338 }`, 339 expectedError: "Updatable apps must use stable SDKs", 340 }, 341 { 342 name: "No unspecified APIs", 343 bp: `android_app { 344 name: "foo", 345 srcs: ["a.java"], 346 updatable: true, 347 min_sdk_version: "29", 348 }`, 349 expectedError: "Updatable apps must use stable SDK", 350 }, 351 { 352 name: "Must specify min_sdk_version", 353 bp: `android_app { 354 name: "app_without_min_sdk_version", 355 srcs: ["a.java"], 356 sdk_version: "29", 357 updatable: true, 358 }`, 359 expectedError: "updatable apps must set min_sdk_version.", 360 }, 361 } 362 363 for _, test := range testCases { 364 t.Run(test.name, func(t *testing.T) { 365 errorHandler := android.FixtureExpectsNoErrors 366 if test.expectedError != "" { 367 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(test.expectedError) 368 } 369 android.GroupFixturePreparers( 370 prepareForJavaTest, FixtureWithPrebuiltApis(map[string][]string{ 371 "29": {"foo"}, 372 })). 373 ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, test.bp) 374 }) 375 } 376} 377 378func TestUpdatableApps_TransitiveDepsShouldSetMinSdkVersion(t *testing.T) { 379 testJavaError(t, `module "bar".*: should support min_sdk_version\(29\)`, cc.GatherRequiredDepsForTest(android.Android)+` 380 android_app { 381 name: "foo", 382 srcs: ["a.java"], 383 updatable: true, 384 sdk_version: "current", 385 min_sdk_version: "29", 386 static_libs: ["bar"], 387 } 388 389 java_library { 390 name: "bar", 391 sdk_version: "current", 392 } 393 `) 394} 395 396func TestUpdatableApps_JniLibsShouldShouldSupportMinSdkVersion(t *testing.T) { 397 testJava(t, cc.GatherRequiredDepsForTest(android.Android)+` 398 android_app { 399 name: "foo", 400 srcs: ["a.java"], 401 updatable: true, 402 sdk_version: "current", 403 min_sdk_version: "current", 404 jni_libs: ["libjni"], 405 } 406 407 cc_library { 408 name: "libjni", 409 stl: "none", 410 system_shared_libs: [], 411 sdk_version: "current", 412 } 413 `) 414} 415 416func TestUpdatableApps_JniLibShouldBeBuiltAgainstMinSdkVersion(t *testing.T) { 417 bp := cc.GatherRequiredDepsForTest(android.Android) + ` 418 android_app { 419 name: "foo", 420 srcs: ["a.java"], 421 updatable: true, 422 sdk_version: "current", 423 min_sdk_version: "29", 424 jni_libs: ["libjni"], 425 } 426 427 cc_library { 428 name: "libjni", 429 stl: "none", 430 system_shared_libs: [], 431 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 } 486 ` 487 testJavaError(t, `"libjni" .*: sdk_version\(current\) is higher than min_sdk_version\(29\)`, bp) 488} 489 490func TestUpdatableApps_ErrorIfDepSdkVersionIsHigher(t *testing.T) { 491 bp := cc.GatherRequiredDepsForTest(android.Android) + ` 492 android_app { 493 name: "foo", 494 srcs: ["a.java"], 495 updatable: true, 496 sdk_version: "current", 497 min_sdk_version: "29", // this APK should support 29 498 jni_libs: ["libjni"], 499 } 500 501 cc_library { 502 name: "libjni", 503 stl: "none", 504 shared_libs: ["libbar"], 505 system_shared_libs: [], 506 sdk_version: "27", 507 } 508 509 cc_library { 510 name: "libbar", 511 stl: "none", 512 system_shared_libs: [], 513 sdk_version: "current", 514 } 515 ` 516 testJavaError(t, `"libjni" .*: links "libbar" built against newer API version "current"`, bp) 517} 518 519func TestResourceDirs(t *testing.T) { 520 testCases := []struct { 521 name string 522 prop string 523 resources []string 524 }{ 525 { 526 name: "no resource_dirs", 527 prop: "", 528 resources: []string{"res/res/values/strings.xml"}, 529 }, 530 { 531 name: "resource_dirs", 532 prop: `resource_dirs: ["res"]`, 533 resources: []string{"res/res/values/strings.xml"}, 534 }, 535 { 536 name: "empty resource_dirs", 537 prop: `resource_dirs: []`, 538 resources: nil, 539 }, 540 } 541 542 fs := android.MockFS{ 543 "res/res/values/strings.xml": nil, 544 } 545 546 bp := ` 547 android_app { 548 name: "foo", 549 sdk_version: "current", 550 %s 551 } 552 ` 553 554 for _, testCase := range testCases { 555 t.Run(testCase.name, func(t *testing.T) { 556 result := android.GroupFixturePreparers( 557 PrepareForTestWithJavaDefaultModules, 558 PrepareForTestWithOverlayBuildComponents, 559 fs.AddToFixture(), 560 ).RunTestWithBp(t, fmt.Sprintf(bp, testCase.prop)) 561 562 module := result.ModuleForTests("foo", "android_common") 563 resourceList := module.MaybeOutput("aapt2/res.list") 564 565 var resources []string 566 if resourceList.Rule != nil { 567 for _, compiledResource := range resourceList.Inputs.Strings() { 568 resources = append(resources, module.Output(compiledResource).Inputs.Strings()...) 569 } 570 } 571 572 android.AssertDeepEquals(t, "resource files", testCase.resources, resources) 573 }) 574 } 575} 576 577func TestLibraryAssets(t *testing.T) { 578 bp := ` 579 android_app { 580 name: "foo", 581 sdk_version: "current", 582 static_libs: ["lib1", "lib2", "lib3"], 583 } 584 585 android_library { 586 name: "lib1", 587 sdk_version: "current", 588 asset_dirs: ["assets_a"], 589 } 590 591 android_library { 592 name: "lib2", 593 sdk_version: "current", 594 } 595 596 android_library { 597 name: "lib3", 598 sdk_version: "current", 599 static_libs: ["lib4"], 600 } 601 602 android_library { 603 name: "lib4", 604 sdk_version: "current", 605 asset_dirs: ["assets_b"], 606 } 607 ` 608 609 testCases := []struct { 610 name string 611 assetFlag string 612 assetPackages []string 613 }{ 614 { 615 name: "foo", 616 // lib1 has its own asset. lib3 doesn't have any, but provides lib4's transitively. 617 assetPackages: []string{ 618 "out/soong/.intermediates/foo/android_common/aapt2/package-res.apk", 619 "out/soong/.intermediates/lib1/android_common/assets.zip", 620 "out/soong/.intermediates/lib3/android_common/assets.zip", 621 }, 622 }, 623 { 624 name: "lib1", 625 assetFlag: "-A assets_a", 626 }, 627 { 628 name: "lib2", 629 }, 630 { 631 name: "lib3", 632 assetPackages: []string{ 633 "out/soong/.intermediates/lib3/android_common/aapt2/package-res.apk", 634 "out/soong/.intermediates/lib4/android_common/assets.zip", 635 }, 636 }, 637 { 638 name: "lib4", 639 assetFlag: "-A assets_b", 640 }, 641 } 642 ctx := testApp(t, bp) 643 644 for _, test := range testCases { 645 t.Run(test.name, func(t *testing.T) { 646 m := ctx.ModuleForTests(test.name, "android_common") 647 648 // Check asset flag in aapt2 link flags 649 var aapt2link android.TestingBuildParams 650 if len(test.assetPackages) > 0 { 651 aapt2link = m.Output("aapt2/package-res.apk") 652 } else { 653 aapt2link = m.Output("package-res.apk") 654 } 655 aapt2link = aapt2link 656 aapt2Flags := aapt2link.Args["flags"] 657 if test.assetFlag != "" { 658 android.AssertStringDoesContain(t, "asset flag", aapt2Flags, test.assetFlag) 659 } else { 660 android.AssertStringDoesNotContain(t, "aapt2 link flags", aapt2Flags, " -A ") 661 } 662 663 // Check asset merge rule. 664 if len(test.assetPackages) > 0 { 665 mergeAssets := m.Output("package-res.apk") 666 android.AssertPathsRelativeToTopEquals(t, "mergeAssets inputs", test.assetPackages, mergeAssets.Inputs) 667 } 668 }) 669 } 670} 671 672func TestAppJavaResources(t *testing.T) { 673 bp := ` 674 android_app { 675 name: "foo", 676 sdk_version: "current", 677 java_resources: ["resources/a"], 678 srcs: ["a.java"], 679 } 680 681 android_app { 682 name: "bar", 683 sdk_version: "current", 684 java_resources: ["resources/a"], 685 } 686 ` 687 688 ctx := testApp(t, bp) 689 690 foo := ctx.ModuleForTests("foo", "android_common") 691 fooResources := foo.Output("res/foo.jar") 692 fooDexJar := foo.Output("dex-withres/foo.jar") 693 fooDexJarAligned := foo.Output("dex-withres-aligned/foo.jar") 694 fooApk := foo.Rule("combineApk") 695 696 if g, w := fooDexJar.Inputs.Strings(), fooResources.Output.String(); !android.InList(w, g) { 697 t.Errorf("expected resource jar %q in foo dex jar inputs %q", w, g) 698 } 699 700 if g, w := fooDexJarAligned.Input.String(), fooDexJar.Output.String(); g != w { 701 t.Errorf("expected dex jar %q in foo aligned dex jar inputs %q", w, g) 702 } 703 704 if g, w := fooApk.Inputs.Strings(), fooDexJarAligned.Output.String(); !android.InList(w, g) { 705 t.Errorf("expected aligned dex jar %q in foo apk inputs %q", w, g) 706 } 707 708 bar := ctx.ModuleForTests("bar", "android_common") 709 barResources := bar.Output("res/bar.jar") 710 barApk := bar.Rule("combineApk") 711 712 if g, w := barApk.Inputs.Strings(), barResources.Output.String(); !android.InList(w, g) { 713 t.Errorf("expected resources jar %q in bar apk inputs %q", w, g) 714 } 715} 716 717func TestAndroidResources(t *testing.T) { 718 testCases := []struct { 719 name string 720 enforceRROTargets []string 721 enforceRROExcludedOverlays []string 722 resourceFiles map[string][]string 723 overlayFiles map[string][]string 724 rroDirs map[string][]string 725 }{ 726 { 727 name: "no RRO", 728 enforceRROTargets: nil, 729 enforceRROExcludedOverlays: nil, 730 resourceFiles: map[string][]string{ 731 "foo": nil, 732 "bar": {"bar/res/res/values/strings.xml"}, 733 "lib": nil, 734 "lib2": {"lib2/res/res/values/strings.xml"}, 735 }, 736 overlayFiles: map[string][]string{ 737 "foo": { 738 "out/soong/.intermediates/lib2/android_common/package-res.apk", 739 "out/soong/.intermediates/lib/android_common/package-res.apk", 740 "out/soong/.intermediates/lib3/android_common/package-res.apk", 741 "foo/res/res/values/strings.xml", 742 "device/vendor/blah/static_overlay/foo/res/values/strings.xml", 743 "device/vendor/blah/overlay/foo/res/values/strings.xml", 744 "product/vendor/blah/overlay/foo/res/values/strings.xml", 745 }, 746 "bar": { 747 "device/vendor/blah/static_overlay/bar/res/values/strings.xml", 748 "device/vendor/blah/overlay/bar/res/values/strings.xml", 749 }, 750 "lib": { 751 "out/soong/.intermediates/lib2/android_common/package-res.apk", 752 "lib/res/res/values/strings.xml", 753 "device/vendor/blah/overlay/lib/res/values/strings.xml", 754 }, 755 }, 756 rroDirs: map[string][]string{ 757 "foo": nil, 758 "bar": nil, 759 }, 760 }, 761 { 762 name: "enforce RRO on foo", 763 enforceRROTargets: []string{"foo"}, 764 enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"}, 765 resourceFiles: map[string][]string{ 766 "foo": nil, 767 "bar": {"bar/res/res/values/strings.xml"}, 768 "lib": nil, 769 "lib2": {"lib2/res/res/values/strings.xml"}, 770 }, 771 overlayFiles: map[string][]string{ 772 "foo": { 773 "out/soong/.intermediates/lib2/android_common/package-res.apk", 774 "out/soong/.intermediates/lib/android_common/package-res.apk", 775 "out/soong/.intermediates/lib3/android_common/package-res.apk", 776 "foo/res/res/values/strings.xml", 777 "device/vendor/blah/static_overlay/foo/res/values/strings.xml", 778 }, 779 "bar": { 780 "device/vendor/blah/static_overlay/bar/res/values/strings.xml", 781 "device/vendor/blah/overlay/bar/res/values/strings.xml", 782 }, 783 "lib": { 784 "out/soong/.intermediates/lib2/android_common/package-res.apk", 785 "lib/res/res/values/strings.xml", 786 }, 787 }, 788 789 rroDirs: map[string][]string{ 790 "foo": { 791 "device:device/vendor/blah/overlay/foo/res", 792 "product:product/vendor/blah/overlay/foo/res", 793 "device:device/vendor/blah/overlay/lib/res", 794 }, 795 "bar": nil, 796 "lib": {"device:device/vendor/blah/overlay/lib/res"}, 797 }, 798 }, 799 { 800 name: "enforce RRO on all", 801 enforceRROTargets: []string{"*"}, 802 enforceRROExcludedOverlays: []string{ 803 // Excluding specific apps/res directories also allowed. 804 "device/vendor/blah/static_overlay/foo", 805 "device/vendor/blah/static_overlay/bar/res", 806 }, 807 resourceFiles: map[string][]string{ 808 "foo": nil, 809 "bar": {"bar/res/res/values/strings.xml"}, 810 "lib": nil, 811 "lib2": {"lib2/res/res/values/strings.xml"}, 812 }, 813 overlayFiles: map[string][]string{ 814 "foo": { 815 "out/soong/.intermediates/lib2/android_common/package-res.apk", 816 "out/soong/.intermediates/lib/android_common/package-res.apk", 817 "out/soong/.intermediates/lib3/android_common/package-res.apk", 818 "foo/res/res/values/strings.xml", 819 "device/vendor/blah/static_overlay/foo/res/values/strings.xml", 820 }, 821 "bar": {"device/vendor/blah/static_overlay/bar/res/values/strings.xml"}, 822 "lib": { 823 "out/soong/.intermediates/lib2/android_common/package-res.apk", 824 "lib/res/res/values/strings.xml", 825 }, 826 }, 827 rroDirs: map[string][]string{ 828 "foo": { 829 "device:device/vendor/blah/overlay/foo/res", 830 "product:product/vendor/blah/overlay/foo/res", 831 // Lib dep comes after the direct deps 832 "device:device/vendor/blah/overlay/lib/res", 833 }, 834 "bar": {"device:device/vendor/blah/overlay/bar/res"}, 835 "lib": {"device:device/vendor/blah/overlay/lib/res"}, 836 }, 837 }, 838 } 839 840 deviceResourceOverlays := []string{ 841 "device/vendor/blah/overlay", 842 "device/vendor/blah/overlay2", 843 "device/vendor/blah/static_overlay", 844 } 845 846 productResourceOverlays := []string{ 847 "product/vendor/blah/overlay", 848 } 849 850 fs := android.MockFS{ 851 "foo/res/res/values/strings.xml": nil, 852 "bar/res/res/values/strings.xml": nil, 853 "lib/res/res/values/strings.xml": nil, 854 "lib2/res/res/values/strings.xml": nil, 855 "device/vendor/blah/overlay/foo/res/values/strings.xml": nil, 856 "device/vendor/blah/overlay/bar/res/values/strings.xml": nil, 857 "device/vendor/blah/overlay/lib/res/values/strings.xml": nil, 858 "device/vendor/blah/static_overlay/foo/res/values/strings.xml": nil, 859 "device/vendor/blah/static_overlay/bar/res/values/strings.xml": nil, 860 "device/vendor/blah/overlay2/res/values/strings.xml": nil, 861 "product/vendor/blah/overlay/foo/res/values/strings.xml": nil, 862 } 863 864 bp := ` 865 android_app { 866 name: "foo", 867 sdk_version: "current", 868 resource_dirs: ["foo/res"], 869 static_libs: ["lib", "lib3"], 870 } 871 872 android_app { 873 name: "bar", 874 sdk_version: "current", 875 resource_dirs: ["bar/res"], 876 } 877 878 android_library { 879 name: "lib", 880 sdk_version: "current", 881 resource_dirs: ["lib/res"], 882 static_libs: ["lib2"], 883 } 884 885 android_library { 886 name: "lib2", 887 sdk_version: "current", 888 resource_dirs: ["lib2/res"], 889 } 890 891 // This library has the same resources as lib (should not lead to dupe RROs) 892 android_library { 893 name: "lib3", 894 sdk_version: "current", 895 resource_dirs: ["lib/res"] 896 } 897 ` 898 899 for _, testCase := range testCases { 900 t.Run(testCase.name, func(t *testing.T) { 901 result := android.GroupFixturePreparers( 902 PrepareForTestWithJavaDefaultModules, 903 PrepareForTestWithOverlayBuildComponents, 904 fs.AddToFixture(), 905 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 906 variables.DeviceResourceOverlays = deviceResourceOverlays 907 variables.ProductResourceOverlays = productResourceOverlays 908 if testCase.enforceRROTargets != nil { 909 variables.EnforceRROTargets = testCase.enforceRROTargets 910 } 911 if testCase.enforceRROExcludedOverlays != nil { 912 variables.EnforceRROExcludedOverlays = testCase.enforceRROExcludedOverlays 913 } 914 }), 915 ).RunTestWithBp(t, bp) 916 917 resourceListToFiles := func(module android.TestingModule, list []string) (files []string) { 918 for _, o := range list { 919 res := module.MaybeOutput(o) 920 if res.Rule != nil { 921 // If the overlay is compiled as part of this module (i.e. a .arsc.flat file), 922 // verify the inputs to the .arsc.flat rule. 923 files = append(files, res.Inputs.Strings()...) 924 } else { 925 // Otherwise, verify the full path to the output of the other module 926 files = append(files, o) 927 } 928 } 929 return files 930 } 931 932 getResources := func(moduleName string) (resourceFiles, overlayFiles, rroDirs []string) { 933 module := result.ModuleForTests(moduleName, "android_common") 934 resourceList := module.MaybeOutput("aapt2/res.list") 935 if resourceList.Rule != nil { 936 resourceFiles = resourceListToFiles(module, android.PathsRelativeToTop(resourceList.Inputs)) 937 } 938 overlayList := module.MaybeOutput("aapt2/overlay.list") 939 if overlayList.Rule != nil { 940 overlayFiles = resourceListToFiles(module, android.PathsRelativeToTop(overlayList.Inputs)) 941 } 942 943 for _, d := range module.Module().(AndroidLibraryDependency).ExportedRRODirs() { 944 var prefix string 945 if d.overlayType == device { 946 prefix = "device:" 947 } else if d.overlayType == product { 948 prefix = "product:" 949 } else { 950 t.Fatalf("Unexpected overlayType %d", d.overlayType) 951 } 952 rroDirs = append(rroDirs, prefix+android.PathRelativeToTop(d.path)) 953 } 954 955 return resourceFiles, overlayFiles, rroDirs 956 } 957 958 modules := []string{"foo", "bar", "lib", "lib2"} 959 for _, module := range modules { 960 resourceFiles, overlayFiles, rroDirs := getResources(module) 961 962 if !reflect.DeepEqual(resourceFiles, testCase.resourceFiles[module]) { 963 t.Errorf("expected %s resource files:\n %#v\n got:\n %#v", 964 module, testCase.resourceFiles[module], resourceFiles) 965 } 966 if !reflect.DeepEqual(overlayFiles, testCase.overlayFiles[module]) { 967 t.Errorf("expected %s overlay files:\n %#v\n got:\n %#v", 968 module, testCase.overlayFiles[module], overlayFiles) 969 } 970 if !reflect.DeepEqual(rroDirs, testCase.rroDirs[module]) { 971 t.Errorf("expected %s rroDirs: %#v\n got:\n %#v", 972 module, testCase.rroDirs[module], rroDirs) 973 } 974 } 975 }) 976 } 977} 978 979func checkSdkVersion(t *testing.T, result *android.TestResult, expectedSdkVersion string) { 980 foo := result.ModuleForTests("foo", "android_common") 981 link := foo.Output("package-res.apk") 982 linkFlags := strings.Split(link.Args["flags"], " ") 983 min := android.IndexList("--min-sdk-version", linkFlags) 984 target := android.IndexList("--target-sdk-version", linkFlags) 985 986 if min == -1 || target == -1 || min == len(linkFlags)-1 || target == len(linkFlags)-1 { 987 t.Fatalf("missing --min-sdk-version or --target-sdk-version in link flags: %q", linkFlags) 988 } 989 990 gotMinSdkVersion := linkFlags[min+1] 991 gotTargetSdkVersion := linkFlags[target+1] 992 993 android.AssertStringEquals(t, "incorrect --min-sdk-version", expectedSdkVersion, gotMinSdkVersion) 994 995 android.AssertStringEquals(t, "incorrect --target-sdk-version", expectedSdkVersion, gotTargetSdkVersion) 996} 997 998func TestAppSdkVersion(t *testing.T) { 999 testCases := []struct { 1000 name string 1001 sdkVersion string 1002 platformSdkInt int 1003 platformSdkCodename string 1004 platformSdkFinal bool 1005 expectedMinSdkVersion string 1006 platformApis bool 1007 activeCodenames []string 1008 }{ 1009 { 1010 name: "current final SDK", 1011 sdkVersion: "current", 1012 platformSdkInt: 27, 1013 platformSdkCodename: "REL", 1014 platformSdkFinal: true, 1015 expectedMinSdkVersion: "27", 1016 }, 1017 { 1018 name: "current non-final SDK", 1019 sdkVersion: "current", 1020 platformSdkInt: 27, 1021 platformSdkCodename: "OMR1", 1022 platformSdkFinal: false, 1023 expectedMinSdkVersion: "OMR1", 1024 activeCodenames: []string{"OMR1"}, 1025 }, 1026 { 1027 name: "default final SDK", 1028 sdkVersion: "", 1029 platformApis: true, 1030 platformSdkInt: 27, 1031 platformSdkCodename: "REL", 1032 platformSdkFinal: true, 1033 expectedMinSdkVersion: "27", 1034 }, 1035 { 1036 name: "default non-final SDK", 1037 sdkVersion: "", 1038 platformApis: true, 1039 platformSdkInt: 27, 1040 platformSdkCodename: "OMR1", 1041 platformSdkFinal: false, 1042 expectedMinSdkVersion: "OMR1", 1043 activeCodenames: []string{"OMR1"}, 1044 }, 1045 { 1046 name: "14", 1047 sdkVersion: "14", 1048 expectedMinSdkVersion: "14", 1049 platformSdkCodename: "S", 1050 activeCodenames: []string{"S"}, 1051 }, 1052 } 1053 1054 for _, moduleType := range []string{"android_app", "android_library"} { 1055 for _, test := range testCases { 1056 t.Run(moduleType+" "+test.name, func(t *testing.T) { 1057 platformApiProp := "" 1058 if test.platformApis { 1059 platformApiProp = "platform_apis: true," 1060 } 1061 bp := fmt.Sprintf(`%s { 1062 name: "foo", 1063 srcs: ["a.java"], 1064 sdk_version: "%s", 1065 %s 1066 }`, moduleType, test.sdkVersion, platformApiProp) 1067 1068 result := android.GroupFixturePreparers( 1069 prepareForJavaTest, 1070 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1071 variables.Platform_sdk_version = &test.platformSdkInt 1072 variables.Platform_sdk_codename = &test.platformSdkCodename 1073 variables.Platform_version_active_codenames = test.activeCodenames 1074 variables.Platform_sdk_final = &test.platformSdkFinal 1075 }), 1076 FixtureWithPrebuiltApis(map[string][]string{ 1077 "14": {"foo"}, 1078 }), 1079 ).RunTestWithBp(t, bp) 1080 1081 checkSdkVersion(t, result, test.expectedMinSdkVersion) 1082 }) 1083 } 1084 } 1085} 1086 1087func TestVendorAppSdkVersion(t *testing.T) { 1088 testCases := []struct { 1089 name string 1090 sdkVersion string 1091 platformSdkInt int 1092 platformSdkCodename string 1093 platformSdkFinal bool 1094 deviceCurrentApiLevelForVendorModules string 1095 expectedMinSdkVersion string 1096 }{ 1097 { 1098 name: "current final SDK", 1099 sdkVersion: "current", 1100 platformSdkInt: 29, 1101 platformSdkCodename: "REL", 1102 platformSdkFinal: true, 1103 deviceCurrentApiLevelForVendorModules: "29", 1104 expectedMinSdkVersion: "29", 1105 }, 1106 { 1107 name: "current final SDK", 1108 sdkVersion: "current", 1109 platformSdkInt: 29, 1110 platformSdkCodename: "REL", 1111 platformSdkFinal: true, 1112 deviceCurrentApiLevelForVendorModules: "28", 1113 expectedMinSdkVersion: "28", 1114 }, 1115 { 1116 name: "current final SDK", 1117 sdkVersion: "current", 1118 platformSdkInt: 29, 1119 platformSdkCodename: "Q", 1120 platformSdkFinal: false, 1121 deviceCurrentApiLevelForVendorModules: "28", 1122 expectedMinSdkVersion: "28", 1123 }, 1124 } 1125 1126 for _, moduleType := range []string{"android_app", "android_library"} { 1127 for _, sdkKind := range []string{"", "system_"} { 1128 for _, test := range testCases { 1129 t.Run(moduleType+" "+test.name, func(t *testing.T) { 1130 bp := fmt.Sprintf(`%s { 1131 name: "foo", 1132 srcs: ["a.java"], 1133 sdk_version: "%s%s", 1134 vendor: true, 1135 }`, moduleType, sdkKind, test.sdkVersion) 1136 1137 result := android.GroupFixturePreparers( 1138 prepareForJavaTest, 1139 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1140 variables.Platform_sdk_version = &test.platformSdkInt 1141 variables.Platform_sdk_codename = &test.platformSdkCodename 1142 variables.Platform_sdk_final = &test.platformSdkFinal 1143 variables.DeviceCurrentApiLevelForVendorModules = &test.deviceCurrentApiLevelForVendorModules 1144 variables.DeviceSystemSdkVersions = []string{"28", "29"} 1145 }), 1146 FixtureWithPrebuiltApis(map[string][]string{ 1147 "28": {"foo"}, 1148 "29": {"foo"}, 1149 "current": {"foo"}, 1150 }), 1151 ).RunTestWithBp(t, bp) 1152 1153 checkSdkVersion(t, result, test.expectedMinSdkVersion) 1154 }) 1155 } 1156 } 1157 } 1158} 1159 1160func TestJNIABI(t *testing.T) { 1161 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+` 1162 cc_library { 1163 name: "libjni", 1164 system_shared_libs: [], 1165 sdk_version: "current", 1166 stl: "none", 1167 } 1168 1169 android_test { 1170 name: "test", 1171 sdk_version: "core_platform", 1172 jni_libs: ["libjni"], 1173 } 1174 1175 android_test { 1176 name: "test_first", 1177 sdk_version: "core_platform", 1178 compile_multilib: "first", 1179 jni_libs: ["libjni"], 1180 } 1181 1182 android_test { 1183 name: "test_both", 1184 sdk_version: "core_platform", 1185 compile_multilib: "both", 1186 jni_libs: ["libjni"], 1187 } 1188 1189 android_test { 1190 name: "test_32", 1191 sdk_version: "core_platform", 1192 compile_multilib: "32", 1193 jni_libs: ["libjni"], 1194 } 1195 1196 android_test { 1197 name: "test_64", 1198 sdk_version: "core_platform", 1199 compile_multilib: "64", 1200 jni_libs: ["libjni"], 1201 } 1202 `) 1203 1204 testCases := []struct { 1205 name string 1206 abis []string 1207 }{ 1208 {"test", []string{"arm64-v8a"}}, 1209 {"test_first", []string{"arm64-v8a"}}, 1210 {"test_both", []string{"arm64-v8a", "armeabi-v7a"}}, 1211 {"test_32", []string{"armeabi-v7a"}}, 1212 {"test_64", []string{"arm64-v8a"}}, 1213 } 1214 1215 for _, test := range testCases { 1216 t.Run(test.name, func(t *testing.T) { 1217 app := ctx.ModuleForTests(test.name, "android_common") 1218 jniLibZip := app.Output("jnilibs.zip") 1219 var abis []string 1220 args := strings.Fields(jniLibZip.Args["jarArgs"]) 1221 for i := 0; i < len(args); i++ { 1222 if args[i] == "-P" { 1223 abis = append(abis, filepath.Base(args[i+1])) 1224 i++ 1225 } 1226 } 1227 if !reflect.DeepEqual(abis, test.abis) { 1228 t.Errorf("want abis %v, got %v", test.abis, abis) 1229 } 1230 }) 1231 } 1232} 1233 1234func TestAppSdkVersionByPartition(t *testing.T) { 1235 testJavaError(t, "sdk_version must have a value when the module is located at vendor or product", ` 1236 android_app { 1237 name: "foo", 1238 srcs: ["a.java"], 1239 vendor: true, 1240 platform_apis: true, 1241 } 1242 `) 1243 1244 testJava(t, ` 1245 android_app { 1246 name: "bar", 1247 srcs: ["b.java"], 1248 platform_apis: true, 1249 } 1250 `) 1251 1252 for _, enforce := range []bool{true, false} { 1253 bp := ` 1254 android_app { 1255 name: "foo", 1256 srcs: ["a.java"], 1257 product_specific: true, 1258 platform_apis: true, 1259 } 1260 ` 1261 1262 errorHandler := android.FixtureExpectsNoErrors 1263 if enforce { 1264 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern("sdk_version must have a value when the module is located at vendor or product") 1265 } 1266 1267 android.GroupFixturePreparers( 1268 PrepareForTestWithJavaDefaultModules, 1269 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1270 variables.EnforceProductPartitionInterface = proptools.BoolPtr(enforce) 1271 }), 1272 ). 1273 ExtendWithErrorHandler(errorHandler). 1274 RunTestWithBp(t, bp) 1275 } 1276} 1277 1278func TestJNIPackaging(t *testing.T) { 1279 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+` 1280 cc_library { 1281 name: "libjni", 1282 system_shared_libs: [], 1283 stl: "none", 1284 sdk_version: "current", 1285 } 1286 1287 android_app { 1288 name: "app", 1289 jni_libs: ["libjni"], 1290 sdk_version: "current", 1291 } 1292 1293 android_app { 1294 name: "app_noembed", 1295 jni_libs: ["libjni"], 1296 use_embedded_native_libs: false, 1297 sdk_version: "current", 1298 } 1299 1300 android_app { 1301 name: "app_embed", 1302 jni_libs: ["libjni"], 1303 use_embedded_native_libs: true, 1304 sdk_version: "current", 1305 } 1306 1307 android_test { 1308 name: "test", 1309 sdk_version: "current", 1310 jni_libs: ["libjni"], 1311 } 1312 1313 android_test { 1314 name: "test_noembed", 1315 sdk_version: "current", 1316 jni_libs: ["libjni"], 1317 use_embedded_native_libs: false, 1318 } 1319 1320 android_test_helper_app { 1321 name: "test_helper", 1322 sdk_version: "current", 1323 jni_libs: ["libjni"], 1324 } 1325 1326 android_test_helper_app { 1327 name: "test_helper_noembed", 1328 sdk_version: "current", 1329 jni_libs: ["libjni"], 1330 use_embedded_native_libs: false, 1331 } 1332 `) 1333 1334 testCases := []struct { 1335 name string 1336 packaged bool 1337 compressed bool 1338 }{ 1339 {"app", false, false}, 1340 {"app_noembed", false, false}, 1341 {"app_embed", true, false}, 1342 {"test", true, false}, 1343 {"test_noembed", true, true}, 1344 {"test_helper", true, false}, 1345 {"test_helper_noembed", true, true}, 1346 } 1347 1348 for _, test := range testCases { 1349 t.Run(test.name, func(t *testing.T) { 1350 app := ctx.ModuleForTests(test.name, "android_common") 1351 jniLibZip := app.MaybeOutput("jnilibs.zip") 1352 if g, w := (jniLibZip.Rule != nil), test.packaged; g != w { 1353 t.Errorf("expected jni packaged %v, got %v", w, g) 1354 } 1355 1356 if jniLibZip.Rule != nil { 1357 if g, w := !strings.Contains(jniLibZip.Args["jarArgs"], "-L 0"), test.compressed; g != w { 1358 t.Errorf("expected jni compressed %v, got %v", w, g) 1359 } 1360 1361 if !strings.Contains(jniLibZip.Implicits[0].String(), "_sdk_") { 1362 t.Errorf("expected input %q to use sdk variant", jniLibZip.Implicits[0].String()) 1363 } 1364 } 1365 }) 1366 } 1367} 1368 1369func TestJNISDK(t *testing.T) { 1370 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+` 1371 cc_library { 1372 name: "libjni", 1373 system_shared_libs: [], 1374 stl: "none", 1375 sdk_version: "current", 1376 } 1377 1378 android_test { 1379 name: "app_platform", 1380 jni_libs: ["libjni"], 1381 platform_apis: true, 1382 } 1383 1384 android_test { 1385 name: "app_sdk", 1386 jni_libs: ["libjni"], 1387 sdk_version: "current", 1388 } 1389 1390 android_test { 1391 name: "app_force_platform", 1392 jni_libs: ["libjni"], 1393 sdk_version: "current", 1394 jni_uses_platform_apis: true, 1395 } 1396 1397 android_test { 1398 name: "app_force_sdk", 1399 jni_libs: ["libjni"], 1400 platform_apis: true, 1401 jni_uses_sdk_apis: true, 1402 } 1403 1404 cc_library { 1405 name: "libvendorjni", 1406 system_shared_libs: [], 1407 stl: "none", 1408 vendor: true, 1409 } 1410 1411 android_test { 1412 name: "app_vendor", 1413 jni_libs: ["libvendorjni"], 1414 sdk_version: "current", 1415 vendor: true, 1416 } 1417 `) 1418 1419 testCases := []struct { 1420 name string 1421 sdkJNI bool 1422 vendorJNI bool 1423 }{ 1424 {name: "app_platform"}, 1425 {name: "app_sdk", sdkJNI: true}, 1426 {name: "app_force_platform"}, 1427 {name: "app_force_sdk", sdkJNI: true}, 1428 {name: "app_vendor", vendorJNI: true}, 1429 } 1430 1431 platformJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_shared"). 1432 Output("libjni.so").Output.String() 1433 sdkJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared"). 1434 Output("libjni.so").Output.String() 1435 vendorJNI := ctx.ModuleForTests("libvendorjni", "android_arm64_armv8-a_shared"). 1436 Output("libvendorjni.so").Output.String() 1437 1438 for _, test := range testCases { 1439 t.Run(test.name, func(t *testing.T) { 1440 app := ctx.ModuleForTests(test.name, "android_common") 1441 1442 jniLibZip := app.MaybeOutput("jnilibs.zip") 1443 if len(jniLibZip.Implicits) != 1 { 1444 t.Fatalf("expected exactly one jni library, got %q", jniLibZip.Implicits.Strings()) 1445 } 1446 gotJNI := jniLibZip.Implicits[0].String() 1447 1448 if test.sdkJNI { 1449 if gotJNI != sdkJNI { 1450 t.Errorf("expected SDK JNI library %q, got %q", sdkJNI, gotJNI) 1451 } 1452 } else if test.vendorJNI { 1453 if gotJNI != vendorJNI { 1454 t.Errorf("expected platform JNI library %q, got %q", vendorJNI, gotJNI) 1455 } 1456 } else { 1457 if gotJNI != platformJNI { 1458 t.Errorf("expected platform JNI library %q, got %q", platformJNI, gotJNI) 1459 } 1460 } 1461 }) 1462 } 1463 1464 t.Run("jni_uses_platform_apis_error", func(t *testing.T) { 1465 testJavaError(t, `jni_uses_platform_apis: can only be set for modules that set sdk_version`, ` 1466 android_test { 1467 name: "app_platform", 1468 platform_apis: true, 1469 jni_uses_platform_apis: true, 1470 } 1471 `) 1472 }) 1473 1474 t.Run("jni_uses_sdk_apis_error", func(t *testing.T) { 1475 testJavaError(t, `jni_uses_sdk_apis: can only be set for modules that do not set sdk_version`, ` 1476 android_test { 1477 name: "app_sdk", 1478 sdk_version: "current", 1479 jni_uses_sdk_apis: true, 1480 } 1481 `) 1482 }) 1483 1484} 1485 1486func TestCertificates(t *testing.T) { 1487 testCases := []struct { 1488 name string 1489 bp string 1490 certificateOverride string 1491 expectedLineage string 1492 expectedCertificate string 1493 }{ 1494 { 1495 name: "default", 1496 bp: ` 1497 android_app { 1498 name: "foo", 1499 srcs: ["a.java"], 1500 sdk_version: "current", 1501 } 1502 `, 1503 certificateOverride: "", 1504 expectedLineage: "", 1505 expectedCertificate: "build/make/target/product/security/testkey.x509.pem build/make/target/product/security/testkey.pk8", 1506 }, 1507 { 1508 name: "module certificate property", 1509 bp: ` 1510 android_app { 1511 name: "foo", 1512 srcs: ["a.java"], 1513 certificate: ":new_certificate", 1514 sdk_version: "current", 1515 } 1516 1517 android_app_certificate { 1518 name: "new_certificate", 1519 certificate: "cert/new_cert", 1520 } 1521 `, 1522 certificateOverride: "", 1523 expectedLineage: "", 1524 expectedCertificate: "cert/new_cert.x509.pem cert/new_cert.pk8", 1525 }, 1526 { 1527 name: "path certificate property", 1528 bp: ` 1529 android_app { 1530 name: "foo", 1531 srcs: ["a.java"], 1532 certificate: "expiredkey", 1533 sdk_version: "current", 1534 } 1535 `, 1536 certificateOverride: "", 1537 expectedLineage: "", 1538 expectedCertificate: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", 1539 }, 1540 { 1541 name: "certificate overrides", 1542 bp: ` 1543 android_app { 1544 name: "foo", 1545 srcs: ["a.java"], 1546 certificate: "expiredkey", 1547 sdk_version: "current", 1548 } 1549 1550 android_app_certificate { 1551 name: "new_certificate", 1552 certificate: "cert/new_cert", 1553 } 1554 `, 1555 certificateOverride: "foo:new_certificate", 1556 expectedLineage: "", 1557 expectedCertificate: "cert/new_cert.x509.pem cert/new_cert.pk8", 1558 }, 1559 { 1560 name: "certificate lineage", 1561 bp: ` 1562 android_app { 1563 name: "foo", 1564 srcs: ["a.java"], 1565 certificate: ":new_certificate", 1566 lineage: "lineage.bin", 1567 sdk_version: "current", 1568 } 1569 1570 android_app_certificate { 1571 name: "new_certificate", 1572 certificate: "cert/new_cert", 1573 } 1574 `, 1575 certificateOverride: "", 1576 expectedLineage: "--lineage lineage.bin", 1577 expectedCertificate: "cert/new_cert.x509.pem cert/new_cert.pk8", 1578 }, 1579 { 1580 name: "lineage from filegroup", 1581 bp: ` 1582 android_app { 1583 name: "foo", 1584 srcs: ["a.java"], 1585 certificate: ":new_certificate", 1586 lineage: ":lineage_bin", 1587 sdk_version: "current", 1588 } 1589 1590 android_app_certificate { 1591 name: "new_certificate", 1592 certificate: "cert/new_cert", 1593 } 1594 1595 filegroup { 1596 name: "lineage_bin", 1597 srcs: ["lineage.bin"], 1598 } 1599 `, 1600 certificateOverride: "", 1601 expectedLineage: "--lineage lineage.bin", 1602 expectedCertificate: "cert/new_cert.x509.pem cert/new_cert.pk8", 1603 }, 1604 } 1605 1606 for _, test := range testCases { 1607 t.Run(test.name, func(t *testing.T) { 1608 result := android.GroupFixturePreparers( 1609 PrepareForTestWithJavaDefaultModules, 1610 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1611 if test.certificateOverride != "" { 1612 variables.CertificateOverrides = []string{test.certificateOverride} 1613 } 1614 }), 1615 ).RunTestWithBp(t, test.bp) 1616 1617 foo := result.ModuleForTests("foo", "android_common") 1618 1619 signapk := foo.Output("foo.apk") 1620 signCertificateFlags := signapk.Args["certificates"] 1621 android.AssertStringEquals(t, "certificates flags", test.expectedCertificate, signCertificateFlags) 1622 1623 signFlags := signapk.Args["flags"] 1624 android.AssertStringEquals(t, "signing flags", test.expectedLineage, signFlags) 1625 }) 1626 } 1627} 1628 1629func TestRequestV4SigningFlag(t *testing.T) { 1630 testCases := []struct { 1631 name string 1632 bp string 1633 expected string 1634 }{ 1635 { 1636 name: "default", 1637 bp: ` 1638 android_app { 1639 name: "foo", 1640 srcs: ["a.java"], 1641 sdk_version: "current", 1642 } 1643 `, 1644 expected: "", 1645 }, 1646 { 1647 name: "default", 1648 bp: ` 1649 android_app { 1650 name: "foo", 1651 srcs: ["a.java"], 1652 sdk_version: "current", 1653 v4_signature: false, 1654 } 1655 `, 1656 expected: "", 1657 }, 1658 { 1659 name: "module certificate property", 1660 bp: ` 1661 android_app { 1662 name: "foo", 1663 srcs: ["a.java"], 1664 sdk_version: "current", 1665 v4_signature: true, 1666 } 1667 `, 1668 expected: "--enable-v4", 1669 }, 1670 } 1671 1672 for _, test := range testCases { 1673 t.Run(test.name, func(t *testing.T) { 1674 result := android.GroupFixturePreparers( 1675 PrepareForTestWithJavaDefaultModules, 1676 ).RunTestWithBp(t, test.bp) 1677 1678 foo := result.ModuleForTests("foo", "android_common") 1679 1680 signapk := foo.Output("foo.apk") 1681 signFlags := signapk.Args["flags"] 1682 android.AssertStringEquals(t, "signing flags", test.expected, signFlags) 1683 }) 1684 } 1685} 1686 1687func TestPackageNameOverride(t *testing.T) { 1688 testCases := []struct { 1689 name string 1690 bp string 1691 packageNameOverride string 1692 expected []string 1693 }{ 1694 { 1695 name: "default", 1696 bp: ` 1697 android_app { 1698 name: "foo", 1699 srcs: ["a.java"], 1700 sdk_version: "current", 1701 } 1702 `, 1703 packageNameOverride: "", 1704 expected: []string{ 1705 "out/soong/.intermediates/foo/android_common/foo.apk", 1706 "out/soong/target/product/test_device/system/app/foo/foo.apk", 1707 }, 1708 }, 1709 { 1710 name: "overridden", 1711 bp: ` 1712 android_app { 1713 name: "foo", 1714 srcs: ["a.java"], 1715 sdk_version: "current", 1716 } 1717 `, 1718 packageNameOverride: "foo:bar", 1719 expected: []string{ 1720 // The package apk should be still be the original name for test dependencies. 1721 "out/soong/.intermediates/foo/android_common/bar.apk", 1722 "out/soong/target/product/test_device/system/app/bar/bar.apk", 1723 }, 1724 }, 1725 } 1726 1727 for _, test := range testCases { 1728 t.Run(test.name, func(t *testing.T) { 1729 result := android.GroupFixturePreparers( 1730 PrepareForTestWithJavaDefaultModules, 1731 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1732 if test.packageNameOverride != "" { 1733 variables.PackageNameOverrides = []string{test.packageNameOverride} 1734 } 1735 }), 1736 ).RunTestWithBp(t, test.bp) 1737 1738 foo := result.ModuleForTests("foo", "android_common") 1739 1740 outSoongDir := result.Config.BuildDir() 1741 1742 outputs := foo.AllOutputs() 1743 outputMap := make(map[string]bool) 1744 for _, o := range outputs { 1745 outputMap[android.StringPathRelativeToTop(outSoongDir, o)] = true 1746 } 1747 for _, e := range test.expected { 1748 if _, exist := outputMap[e]; !exist { 1749 t.Errorf("Can't find %q in output files.\nAll outputs:%v", e, outputs) 1750 } 1751 } 1752 }) 1753 } 1754} 1755 1756func TestInstrumentationTargetOverridden(t *testing.T) { 1757 bp := ` 1758 android_app { 1759 name: "foo", 1760 srcs: ["a.java"], 1761 sdk_version: "current", 1762 } 1763 1764 android_test { 1765 name: "bar", 1766 instrumentation_for: "foo", 1767 sdk_version: "current", 1768 } 1769 ` 1770 1771 result := android.GroupFixturePreparers( 1772 PrepareForTestWithJavaDefaultModules, 1773 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1774 variables.ManifestPackageNameOverrides = []string{"foo:org.dandroid.bp"} 1775 }), 1776 ).RunTestWithBp(t, bp) 1777 1778 bar := result.ModuleForTests("bar", "android_common") 1779 res := bar.Output("package-res.apk") 1780 aapt2Flags := res.Args["flags"] 1781 e := "--rename-instrumentation-target-package org.dandroid.bp" 1782 if !strings.Contains(aapt2Flags, e) { 1783 t.Errorf("target package renaming flag, %q is missing in aapt2 link flags, %q", e, aapt2Flags) 1784 } 1785} 1786 1787func TestOverrideAndroidApp(t *testing.T) { 1788 result := PrepareForTestWithJavaDefaultModules.RunTestWithBp( 1789 t, ` 1790 android_app { 1791 name: "foo", 1792 srcs: ["a.java"], 1793 certificate: "expiredkey", 1794 overrides: ["qux"], 1795 sdk_version: "current", 1796 } 1797 1798 override_android_app { 1799 name: "bar", 1800 base: "foo", 1801 certificate: ":new_certificate", 1802 lineage: "lineage.bin", 1803 logging_parent: "bah", 1804 } 1805 1806 android_app_certificate { 1807 name: "new_certificate", 1808 certificate: "cert/new_cert", 1809 } 1810 1811 override_android_app { 1812 name: "baz", 1813 base: "foo", 1814 package_name: "org.dandroid.bp", 1815 } 1816 1817 override_android_app { 1818 name: "baz_no_rename_resources", 1819 base: "foo", 1820 package_name: "org.dandroid.bp", 1821 rename_resources_package: false, 1822 } 1823 1824 android_app { 1825 name: "foo_no_rename_resources", 1826 srcs: ["a.java"], 1827 certificate: "expiredkey", 1828 overrides: ["qux"], 1829 rename_resources_package: false, 1830 sdk_version: "current", 1831 } 1832 1833 override_android_app { 1834 name: "baz_base_no_rename_resources", 1835 base: "foo_no_rename_resources", 1836 package_name: "org.dandroid.bp", 1837 } 1838 1839 override_android_app { 1840 name: "baz_override_base_rename_resources", 1841 base: "foo_no_rename_resources", 1842 package_name: "org.dandroid.bp", 1843 rename_resources_package: true, 1844 } 1845 `) 1846 1847 expectedVariants := []struct { 1848 name string 1849 moduleName string 1850 variantName string 1851 apkName string 1852 apkPath string 1853 certFlag string 1854 lineageFlag string 1855 overrides []string 1856 packageFlag string 1857 renameResources bool 1858 logging_parent string 1859 }{ 1860 { 1861 name: "foo", 1862 moduleName: "foo", 1863 variantName: "android_common", 1864 apkPath: "out/soong/target/product/test_device/system/app/foo/foo.apk", 1865 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", 1866 lineageFlag: "", 1867 overrides: []string{"qux"}, 1868 packageFlag: "", 1869 renameResources: false, 1870 logging_parent: "", 1871 }, 1872 { 1873 name: "foo", 1874 moduleName: "bar", 1875 variantName: "android_common_bar", 1876 apkPath: "out/soong/target/product/test_device/system/app/bar/bar.apk", 1877 certFlag: "cert/new_cert.x509.pem cert/new_cert.pk8", 1878 lineageFlag: "--lineage lineage.bin", 1879 overrides: []string{"qux", "foo"}, 1880 packageFlag: "", 1881 renameResources: false, 1882 logging_parent: "bah", 1883 }, 1884 { 1885 name: "foo", 1886 moduleName: "baz", 1887 variantName: "android_common_baz", 1888 apkPath: "out/soong/target/product/test_device/system/app/baz/baz.apk", 1889 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", 1890 lineageFlag: "", 1891 overrides: []string{"qux", "foo"}, 1892 packageFlag: "org.dandroid.bp", 1893 renameResources: true, 1894 logging_parent: "", 1895 }, 1896 { 1897 name: "foo", 1898 moduleName: "baz_no_rename_resources", 1899 variantName: "android_common_baz_no_rename_resources", 1900 apkPath: "out/soong/target/product/test_device/system/app/baz_no_rename_resources/baz_no_rename_resources.apk", 1901 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", 1902 lineageFlag: "", 1903 overrides: []string{"qux", "foo"}, 1904 packageFlag: "org.dandroid.bp", 1905 renameResources: false, 1906 logging_parent: "", 1907 }, 1908 { 1909 name: "foo_no_rename_resources", 1910 moduleName: "baz_base_no_rename_resources", 1911 variantName: "android_common_baz_base_no_rename_resources", 1912 apkPath: "out/soong/target/product/test_device/system/app/baz_base_no_rename_resources/baz_base_no_rename_resources.apk", 1913 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", 1914 lineageFlag: "", 1915 overrides: []string{"qux", "foo_no_rename_resources"}, 1916 packageFlag: "org.dandroid.bp", 1917 renameResources: false, 1918 logging_parent: "", 1919 }, 1920 { 1921 name: "foo_no_rename_resources", 1922 moduleName: "baz_override_base_rename_resources", 1923 variantName: "android_common_baz_override_base_rename_resources", 1924 apkPath: "out/soong/target/product/test_device/system/app/baz_override_base_rename_resources/baz_override_base_rename_resources.apk", 1925 certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", 1926 lineageFlag: "", 1927 overrides: []string{"qux", "foo_no_rename_resources"}, 1928 packageFlag: "org.dandroid.bp", 1929 renameResources: true, 1930 logging_parent: "", 1931 }, 1932 } 1933 for _, expected := range expectedVariants { 1934 variant := result.ModuleForTests(expected.name, expected.variantName) 1935 1936 // Check the final apk name 1937 variant.Output(expected.apkPath) 1938 1939 // Check the certificate paths 1940 signapk := variant.Output(expected.moduleName + ".apk") 1941 certFlag := signapk.Args["certificates"] 1942 android.AssertStringEquals(t, "certificates flags", expected.certFlag, certFlag) 1943 1944 // Check the lineage flags 1945 lineageFlag := signapk.Args["flags"] 1946 android.AssertStringEquals(t, "signing flags", expected.lineageFlag, lineageFlag) 1947 1948 // Check if the overrides field values are correctly aggregated. 1949 mod := variant.Module().(*AndroidApp) 1950 android.AssertDeepEquals(t, "overrides property", expected.overrides, mod.appProperties.Overrides) 1951 1952 // Test Overridable property: Logging_parent 1953 logging_parent := mod.aapt.LoggingParent 1954 android.AssertStringEquals(t, "overrides property value for logging parent", expected.logging_parent, logging_parent) 1955 1956 // Check the package renaming flag, if exists. 1957 res := variant.Output("package-res.apk") 1958 aapt2Flags := res.Args["flags"] 1959 checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag) 1960 expectedPackage := expected.packageFlag 1961 if !expected.renameResources { 1962 expectedPackage = "" 1963 } 1964 checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expectedPackage) 1965 } 1966} 1967 1968func TestOverrideAndroidAppDependency(t *testing.T) { 1969 ctx, _ := testJava(t, ` 1970 android_app { 1971 name: "foo", 1972 srcs: ["a.java"], 1973 sdk_version: "current", 1974 } 1975 1976 override_android_app { 1977 name: "bar", 1978 base: "foo", 1979 package_name: "org.dandroid.bp", 1980 } 1981 1982 android_test { 1983 name: "baz", 1984 srcs: ["b.java"], 1985 instrumentation_for: "foo", 1986 } 1987 1988 android_test { 1989 name: "qux", 1990 srcs: ["b.java"], 1991 instrumentation_for: "bar", 1992 } 1993 `) 1994 1995 // Verify baz, which depends on the overridden module foo, has the correct classpath javac arg. 1996 javac := ctx.ModuleForTests("baz", "android_common").Rule("javac") 1997 fooTurbine := "out/soong/.intermediates/foo/android_common/turbine-combined/foo.jar" 1998 if !strings.Contains(javac.Args["classpath"], fooTurbine) { 1999 t.Errorf("baz classpath %v does not contain %q", javac.Args["classpath"], fooTurbine) 2000 } 2001 2002 // Verify qux, which depends on the overriding module bar, has the correct classpath javac arg. 2003 javac = ctx.ModuleForTests("qux", "android_common").Rule("javac") 2004 barTurbine := "out/soong/.intermediates/foo/android_common_bar/turbine-combined/foo.jar" 2005 if !strings.Contains(javac.Args["classpath"], barTurbine) { 2006 t.Errorf("qux classpath %v does not contain %q", javac.Args["classpath"], barTurbine) 2007 } 2008} 2009 2010func TestOverrideAndroidTest(t *testing.T) { 2011 ctx, _ := testJava(t, ` 2012 android_app { 2013 name: "foo", 2014 srcs: ["a.java"], 2015 package_name: "com.android.foo", 2016 sdk_version: "current", 2017 } 2018 2019 override_android_app { 2020 name: "bar", 2021 base: "foo", 2022 package_name: "com.android.bar", 2023 } 2024 2025 android_test { 2026 name: "foo_test", 2027 srcs: ["b.java"], 2028 instrumentation_for: "foo", 2029 } 2030 2031 override_android_test { 2032 name: "bar_test", 2033 base: "foo_test", 2034 package_name: "com.android.bar.test", 2035 instrumentation_for: "bar", 2036 instrumentation_target_package: "com.android.bar", 2037 } 2038 `) 2039 2040 expectedVariants := []struct { 2041 moduleName string 2042 variantName string 2043 apkPath string 2044 overrides []string 2045 targetVariant string 2046 packageFlag string 2047 targetPackageFlag string 2048 }{ 2049 { 2050 variantName: "android_common", 2051 apkPath: "/target/product/test_device/testcases/foo_test/arm64/foo_test.apk", 2052 overrides: nil, 2053 targetVariant: "android_common", 2054 packageFlag: "", 2055 targetPackageFlag: "", 2056 }, 2057 { 2058 variantName: "android_common_bar_test", 2059 apkPath: "/target/product/test_device/testcases/bar_test/arm64/bar_test.apk", 2060 overrides: []string{"foo_test"}, 2061 targetVariant: "android_common_bar", 2062 packageFlag: "com.android.bar.test", 2063 targetPackageFlag: "com.android.bar", 2064 }, 2065 } 2066 for _, expected := range expectedVariants { 2067 variant := ctx.ModuleForTests("foo_test", expected.variantName) 2068 2069 // Check the final apk name 2070 variant.Output("out/soong" + expected.apkPath) 2071 2072 // Check if the overrides field values are correctly aggregated. 2073 mod := variant.Module().(*AndroidTest) 2074 if !reflect.DeepEqual(expected.overrides, mod.appProperties.Overrides) { 2075 t.Errorf("Incorrect overrides property value, expected: %q, got: %q", 2076 expected.overrides, mod.appProperties.Overrides) 2077 } 2078 2079 // Check if javac classpath has the correct jar file path. This checks instrumentation_for overrides. 2080 javac := variant.Rule("javac") 2081 turbine := filepath.Join("out", "soong", ".intermediates", "foo", expected.targetVariant, "turbine-combined", "foo.jar") 2082 if !strings.Contains(javac.Args["classpath"], turbine) { 2083 t.Errorf("classpath %q does not contain %q", javac.Args["classpath"], turbine) 2084 } 2085 2086 // Check aapt2 flags. 2087 res := variant.Output("package-res.apk") 2088 aapt2Flags := res.Args["flags"] 2089 checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag) 2090 checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expected.packageFlag) 2091 checkAapt2LinkFlag(t, aapt2Flags, "rename-instrumentation-target-package", expected.targetPackageFlag) 2092 } 2093} 2094 2095func TestAndroidTest_FixTestConfig(t *testing.T) { 2096 ctx, _ := testJava(t, ` 2097 android_app { 2098 name: "foo", 2099 srcs: ["a.java"], 2100 package_name: "com.android.foo", 2101 sdk_version: "current", 2102 } 2103 2104 android_test { 2105 name: "foo_test", 2106 srcs: ["b.java"], 2107 instrumentation_for: "foo", 2108 } 2109 2110 android_test { 2111 name: "bar_test", 2112 srcs: ["b.java"], 2113 package_name: "com.android.bar.test", 2114 instrumentation_for: "foo", 2115 } 2116 2117 override_android_test { 2118 name: "baz_test", 2119 base: "foo_test", 2120 package_name: "com.android.baz.test", 2121 } 2122 `) 2123 2124 testCases := []struct { 2125 moduleName string 2126 variantName string 2127 expectedFlags []string 2128 }{ 2129 { 2130 moduleName: "foo_test", 2131 variantName: "android_common", 2132 }, 2133 { 2134 moduleName: "bar_test", 2135 variantName: "android_common", 2136 expectedFlags: []string{ 2137 "--manifest out/soong/.intermediates/bar_test/android_common/manifest_fixer/AndroidManifest.xml", 2138 "--package-name com.android.bar.test", 2139 }, 2140 }, 2141 { 2142 moduleName: "foo_test", 2143 variantName: "android_common_baz_test", 2144 expectedFlags: []string{ 2145 "--manifest out/soong/.intermediates/foo_test/android_common_baz_test/manifest_fixer/AndroidManifest.xml", 2146 "--package-name com.android.baz.test", 2147 "--test-file-name baz_test.apk", 2148 }, 2149 }, 2150 } 2151 2152 for _, test := range testCases { 2153 variant := ctx.ModuleForTests(test.moduleName, test.variantName) 2154 params := variant.MaybeOutput("test_config_fixer/AndroidTest.xml") 2155 2156 if len(test.expectedFlags) > 0 { 2157 if params.Rule == nil { 2158 t.Errorf("test_config_fixer was expected to run, but didn't") 2159 } else { 2160 for _, flag := range test.expectedFlags { 2161 if !strings.Contains(params.RuleParams.Command, flag) { 2162 t.Errorf("Flag %q was not found in command: %q", flag, params.RuleParams.Command) 2163 } 2164 } 2165 } 2166 } else { 2167 if params.Rule != nil { 2168 t.Errorf("test_config_fixer was not expected to run, but did: %q", params.RuleParams.Command) 2169 } 2170 } 2171 2172 } 2173} 2174 2175func TestStl(t *testing.T) { 2176 ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+` 2177 cc_library { 2178 name: "libjni", 2179 sdk_version: "current", 2180 stl: "c++_shared", 2181 } 2182 2183 android_test { 2184 name: "stl", 2185 jni_libs: ["libjni"], 2186 compile_multilib: "both", 2187 sdk_version: "current", 2188 stl: "c++_shared", 2189 } 2190 2191 android_test { 2192 name: "system", 2193 jni_libs: ["libjni"], 2194 compile_multilib: "both", 2195 sdk_version: "current", 2196 } 2197 `) 2198 2199 testCases := []struct { 2200 name string 2201 jnis []string 2202 }{ 2203 {"stl", 2204 []string{ 2205 "libjni.so", 2206 "libc++_shared.so", 2207 }, 2208 }, 2209 {"system", 2210 []string{ 2211 "libjni.so", 2212 }, 2213 }, 2214 } 2215 2216 for _, test := range testCases { 2217 t.Run(test.name, func(t *testing.T) { 2218 app := ctx.ModuleForTests(test.name, "android_common") 2219 jniLibZip := app.Output("jnilibs.zip") 2220 var jnis []string 2221 args := strings.Fields(jniLibZip.Args["jarArgs"]) 2222 for i := 0; i < len(args); i++ { 2223 if args[i] == "-f" { 2224 jnis = append(jnis, args[i+1]) 2225 i += 1 2226 } 2227 } 2228 jnisJoined := strings.Join(jnis, " ") 2229 for _, jni := range test.jnis { 2230 if !strings.Contains(jnisJoined, jni) { 2231 t.Errorf("missing jni %q in %q", jni, jnis) 2232 } 2233 } 2234 }) 2235 } 2236} 2237 2238func TestUsesLibraries(t *testing.T) { 2239 bp := ` 2240 java_sdk_library { 2241 name: "foo", 2242 srcs: ["a.java"], 2243 api_packages: ["foo"], 2244 sdk_version: "current", 2245 } 2246 2247 java_sdk_library { 2248 name: "qux", 2249 srcs: ["a.java"], 2250 api_packages: ["qux"], 2251 sdk_version: "current", 2252 } 2253 2254 java_sdk_library { 2255 name: "quuz", 2256 srcs: ["a.java"], 2257 api_packages: ["quuz"], 2258 sdk_version: "current", 2259 } 2260 2261 java_sdk_library { 2262 name: "fred", 2263 srcs: ["a.java"], 2264 api_packages: ["fred"], 2265 sdk_version: "current", 2266 } 2267 2268 java_sdk_library { 2269 name: "bar", 2270 srcs: ["a.java"], 2271 api_packages: ["bar"], 2272 sdk_version: "current", 2273 } 2274 2275 java_sdk_library { 2276 name: "runtime-library", 2277 srcs: ["a.java"], 2278 sdk_version: "current", 2279 } 2280 2281 java_library { 2282 name: "static-runtime-helper", 2283 srcs: ["a.java"], 2284 libs: ["runtime-library"], 2285 sdk_version: "current", 2286 } 2287 2288 // A library that has to use "provides_uses_lib", because: 2289 // - it is not an SDK library 2290 // - its library name is different from its module name 2291 java_library { 2292 name: "non-sdk-lib", 2293 provides_uses_lib: "com.non.sdk.lib", 2294 installable: true, 2295 srcs: ["a.java"], 2296 } 2297 2298 android_app { 2299 name: "app", 2300 srcs: ["a.java"], 2301 libs: [ 2302 "qux", 2303 "quuz.stubs" 2304 ], 2305 static_libs: [ 2306 "static-runtime-helper", 2307 // statically linked component libraries should not pull their SDK libraries, 2308 // so "fred" should not be added to class loader context 2309 "fred.stubs", 2310 ], 2311 uses_libs: [ 2312 "foo", 2313 "non-sdk-lib" 2314 ], 2315 sdk_version: "current", 2316 optional_uses_libs: [ 2317 "bar", 2318 "baz", 2319 ], 2320 } 2321 2322 android_app_import { 2323 name: "prebuilt", 2324 apk: "prebuilts/apk/app.apk", 2325 certificate: "platform", 2326 uses_libs: [ 2327 "foo", 2328 "non-sdk-lib", 2329 "android.test.runner" 2330 ], 2331 optional_uses_libs: [ 2332 "bar", 2333 "baz", 2334 ], 2335 } 2336 ` 2337 2338 result := android.GroupFixturePreparers( 2339 prepareForJavaTest, 2340 PrepareForTestWithJavaSdkLibraryFiles, 2341 FixtureWithLastReleaseApis("runtime-library", "foo", "quuz", "qux", "bar", "fred"), 2342 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 2343 variables.MissingUsesLibraries = []string{"baz"} 2344 }), 2345 ).RunTestWithBp(t, bp) 2346 2347 app := result.ModuleForTests("app", "android_common") 2348 prebuilt := result.ModuleForTests("prebuilt", "android_common") 2349 2350 // Test that implicit dependencies on java_sdk_library instances are passed to the manifest. 2351 // This should not include explicit `uses_libs`/`optional_uses_libs` entries. 2352 actualManifestFixerArgs := app.Output("manifest_fixer/AndroidManifest.xml").Args["args"] 2353 expectManifestFixerArgs := `--extract-native-libs=true ` + 2354 `--uses-library qux ` + 2355 `--uses-library quuz ` + 2356 `--uses-library foo ` + // TODO(b/132357300): "foo" should not be passed to manifest_fixer 2357 `--uses-library com.non.sdk.lib ` + // TODO(b/132357300): "com.non.sdk.lib" should not be passed to manifest_fixer 2358 `--uses-library bar ` + // TODO(b/132357300): "bar" should not be passed to manifest_fixer 2359 `--uses-library runtime-library` 2360 android.AssertStringEquals(t, "manifest_fixer args", expectManifestFixerArgs, actualManifestFixerArgs) 2361 2362 // Test that all libraries are verified (library order matters). 2363 verifyCmd := app.Rule("verify_uses_libraries").RuleParams.Command 2364 verifyArgs := `--uses-library foo ` + 2365 `--uses-library com.non.sdk.lib ` + 2366 `--uses-library qux ` + 2367 `--uses-library quuz ` + 2368 `--uses-library runtime-library ` + 2369 `--optional-uses-library bar ` + 2370 `--optional-uses-library baz ` 2371 android.AssertStringDoesContain(t, "verify cmd args", verifyCmd, verifyArgs) 2372 2373 // Test that all libraries are verified for an APK (library order matters). 2374 verifyApkCmd := prebuilt.Rule("verify_uses_libraries").RuleParams.Command 2375 verifyApkArgs := `--uses-library foo ` + 2376 `--uses-library com.non.sdk.lib ` + 2377 `--uses-library android.test.runner ` + 2378 `--optional-uses-library bar ` + 2379 `--optional-uses-library baz ` 2380 android.AssertStringDoesContain(t, "verify apk cmd args", verifyApkCmd, verifyApkArgs) 2381 2382 // Test that all present libraries are preopted, including implicit SDK dependencies, possibly stubs 2383 cmd := app.Rule("dexpreopt").RuleParams.Command 2384 w := `--target-context-for-sdk any ` + 2385 `PCL[/system/framework/qux.jar]#` + 2386 `PCL[/system/framework/quuz.jar]#` + 2387 `PCL[/system/framework/foo.jar]#` + 2388 `PCL[/system/framework/non-sdk-lib.jar]#` + 2389 `PCL[/system/framework/bar.jar]#` + 2390 `PCL[/system/framework/runtime-library.jar]` 2391 android.AssertStringDoesContain(t, "dexpreopt app cmd args", cmd, w) 2392 2393 // Test conditional context for target SDK version 28. 2394 android.AssertStringDoesContain(t, "dexpreopt app cmd 28", cmd, 2395 `--target-context-for-sdk 28`+ 2396 ` PCL[/system/framework/org.apache.http.legacy.jar] `) 2397 2398 // Test conditional context for target SDK version 29. 2399 android.AssertStringDoesContain(t, "dexpreopt app cmd 29", cmd, 2400 `--target-context-for-sdk 29`+ 2401 ` PCL[/system/framework/android.hidl.manager-V1.0-java.jar]`+ 2402 `#PCL[/system/framework/android.hidl.base-V1.0-java.jar] `) 2403 2404 // Test conditional context for target SDK version 30. 2405 // "android.test.mock" is absent because "android.test.runner" is not used. 2406 android.AssertStringDoesContain(t, "dexpreopt app cmd 30", cmd, 2407 `--target-context-for-sdk 30`+ 2408 ` PCL[/system/framework/android.test.base.jar] `) 2409 2410 cmd = prebuilt.Rule("dexpreopt").RuleParams.Command 2411 android.AssertStringDoesContain(t, "dexpreopt prebuilt cmd", cmd, 2412 `--target-context-for-sdk any`+ 2413 ` PCL[/system/framework/foo.jar]`+ 2414 `#PCL[/system/framework/non-sdk-lib.jar]`+ 2415 `#PCL[/system/framework/android.test.runner.jar]`+ 2416 `#PCL[/system/framework/bar.jar] `) 2417 2418 // Test conditional context for target SDK version 30. 2419 // "android.test.mock" is present because "android.test.runner" is used. 2420 android.AssertStringDoesContain(t, "dexpreopt prebuilt cmd 30", cmd, 2421 `--target-context-for-sdk 30`+ 2422 ` PCL[/system/framework/android.test.base.jar]`+ 2423 `#PCL[/system/framework/android.test.mock.jar] `) 2424} 2425 2426func TestDexpreoptBcp(t *testing.T) { 2427 bp := ` 2428 java_sdk_library { 2429 name: "foo", 2430 srcs: ["a.java"], 2431 api_packages: ["foo"], 2432 sdk_version: "current", 2433 } 2434 2435 java_sdk_library { 2436 name: "bar", 2437 srcs: ["a.java"], 2438 api_packages: ["bar"], 2439 permitted_packages: ["bar"], 2440 sdk_version: "current", 2441 } 2442 2443 android_app { 2444 name: "app", 2445 srcs: ["a.java"], 2446 sdk_version: "current", 2447 } 2448 ` 2449 2450 testCases := []struct { 2451 name string 2452 with bool 2453 expect string 2454 }{ 2455 { 2456 name: "with updatable bcp", 2457 with: true, 2458 expect: "/system/framework/foo.jar:/system/framework/bar.jar", 2459 }, 2460 { 2461 name: "without updatable bcp", 2462 with: false, 2463 expect: "/system/framework/foo.jar", 2464 }, 2465 } 2466 2467 for _, test := range testCases { 2468 t.Run(test.name, func(t *testing.T) { 2469 result := android.GroupFixturePreparers( 2470 prepareForJavaTest, 2471 PrepareForTestWithJavaSdkLibraryFiles, 2472 FixtureWithLastReleaseApis("runtime-library", "foo", "bar"), 2473 dexpreopt.FixtureSetBootJars("platform:foo"), 2474 dexpreopt.FixtureSetUpdatableBootJars("platform:bar"), 2475 dexpreopt.FixtureSetPreoptWithUpdatableBcp(test.with), 2476 ).RunTestWithBp(t, bp) 2477 2478 app := result.ModuleForTests("app", "android_common") 2479 cmd := app.Rule("dexpreopt").RuleParams.Command 2480 bcp := " -Xbootclasspath-locations:" + test.expect + " " // space at the end matters 2481 android.AssertStringDoesContain(t, "dexpreopt app bcp", cmd, bcp) 2482 }) 2483 } 2484} 2485 2486func TestCodelessApp(t *testing.T) { 2487 testCases := []struct { 2488 name string 2489 bp string 2490 noCode bool 2491 }{ 2492 { 2493 name: "normal", 2494 bp: ` 2495 android_app { 2496 name: "foo", 2497 srcs: ["a.java"], 2498 sdk_version: "current", 2499 } 2500 `, 2501 noCode: false, 2502 }, 2503 { 2504 name: "app without sources", 2505 bp: ` 2506 android_app { 2507 name: "foo", 2508 sdk_version: "current", 2509 } 2510 `, 2511 noCode: true, 2512 }, 2513 { 2514 name: "app with libraries", 2515 bp: ` 2516 android_app { 2517 name: "foo", 2518 static_libs: ["lib"], 2519 sdk_version: "current", 2520 } 2521 2522 java_library { 2523 name: "lib", 2524 srcs: ["a.java"], 2525 sdk_version: "current", 2526 } 2527 `, 2528 noCode: false, 2529 }, 2530 { 2531 name: "app with sourceless libraries", 2532 bp: ` 2533 android_app { 2534 name: "foo", 2535 static_libs: ["lib"], 2536 sdk_version: "current", 2537 } 2538 2539 java_library { 2540 name: "lib", 2541 sdk_version: "current", 2542 } 2543 `, 2544 // TODO(jungjw): this should probably be true 2545 noCode: false, 2546 }, 2547 } 2548 2549 for _, test := range testCases { 2550 t.Run(test.name, func(t *testing.T) { 2551 ctx := testApp(t, test.bp) 2552 2553 foo := ctx.ModuleForTests("foo", "android_common") 2554 manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"] 2555 if strings.Contains(manifestFixerArgs, "--has-no-code") != test.noCode { 2556 t.Errorf("unexpected manifest_fixer args: %q", manifestFixerArgs) 2557 } 2558 }) 2559 } 2560} 2561 2562func TestEmbedNotice(t *testing.T) { 2563 result := android.GroupFixturePreparers( 2564 PrepareForTestWithJavaDefaultModules, 2565 cc.PrepareForTestWithCcDefaultModules, 2566 genrule.PrepareForTestWithGenRuleBuildComponents, 2567 android.MockFS{ 2568 "APP_NOTICE": nil, 2569 "GENRULE_NOTICE": nil, 2570 "LIB_NOTICE": nil, 2571 "TOOL_NOTICE": nil, 2572 }.AddToFixture(), 2573 ).RunTestWithBp(t, ` 2574 android_app { 2575 name: "foo", 2576 srcs: ["a.java"], 2577 static_libs: ["javalib"], 2578 jni_libs: ["libjni"], 2579 notice: "APP_NOTICE", 2580 embed_notices: true, 2581 sdk_version: "current", 2582 } 2583 2584 // No embed_notice flag 2585 android_app { 2586 name: "bar", 2587 srcs: ["a.java"], 2588 jni_libs: ["libjni"], 2589 notice: "APP_NOTICE", 2590 sdk_version: "current", 2591 } 2592 2593 // No NOTICE files 2594 android_app { 2595 name: "baz", 2596 srcs: ["a.java"], 2597 embed_notices: true, 2598 sdk_version: "current", 2599 } 2600 2601 cc_library { 2602 name: "libjni", 2603 system_shared_libs: [], 2604 stl: "none", 2605 notice: "LIB_NOTICE", 2606 sdk_version: "current", 2607 } 2608 2609 java_library { 2610 name: "javalib", 2611 srcs: [ 2612 ":gen", 2613 ], 2614 sdk_version: "current", 2615 } 2616 2617 genrule { 2618 name: "gen", 2619 tools: ["gentool"], 2620 out: ["gen.java"], 2621 notice: "GENRULE_NOTICE", 2622 } 2623 2624 java_binary_host { 2625 name: "gentool", 2626 srcs: ["b.java"], 2627 notice: "TOOL_NOTICE", 2628 } 2629 `) 2630 2631 // foo has NOTICE files to process, and embed_notices is true. 2632 foo := result.ModuleForTests("foo", "android_common") 2633 // verify merge notices rule. 2634 mergeNotices := foo.Rule("mergeNoticesRule") 2635 noticeInputs := mergeNotices.Inputs.Strings() 2636 // TOOL_NOTICE should be excluded as it's a host module. 2637 if len(mergeNotices.Inputs) != 3 { 2638 t.Errorf("number of input notice files: expected = 3, actual = %q", noticeInputs) 2639 } 2640 if !inList("APP_NOTICE", noticeInputs) { 2641 t.Errorf("APP_NOTICE is missing from notice files, %q", noticeInputs) 2642 } 2643 if !inList("LIB_NOTICE", noticeInputs) { 2644 t.Errorf("LIB_NOTICE is missing from notice files, %q", noticeInputs) 2645 } 2646 if !inList("GENRULE_NOTICE", noticeInputs) { 2647 t.Errorf("GENRULE_NOTICE is missing from notice files, %q", noticeInputs) 2648 } 2649 // aapt2 flags should include -A <NOTICE dir> so that its contents are put in the APK's /assets. 2650 res := foo.Output("package-res.apk") 2651 aapt2Flags := res.Args["flags"] 2652 e := "-A out/soong/.intermediates/foo/android_common/NOTICE" 2653 android.AssertStringDoesContain(t, "expected.apkPath", aapt2Flags, e) 2654 2655 // bar has NOTICE files to process, but embed_notices is not set. 2656 bar := result.ModuleForTests("bar", "android_common") 2657 res = bar.Output("package-res.apk") 2658 aapt2Flags = res.Args["flags"] 2659 e = "-A out/soong/.intermediates/bar/android_common/NOTICE" 2660 android.AssertStringDoesNotContain(t, "bar shouldn't have the asset dir flag for NOTICE", aapt2Flags, e) 2661 2662 // baz's embed_notice is true, but it doesn't have any NOTICE files. 2663 baz := result.ModuleForTests("baz", "android_common") 2664 res = baz.Output("package-res.apk") 2665 aapt2Flags = res.Args["flags"] 2666 e = "-A out/soong/.intermediates/baz/android_common/NOTICE" 2667 if strings.Contains(aapt2Flags, e) { 2668 t.Errorf("baz shouldn't have the asset dir flag for NOTICE: %q", e) 2669 } 2670} 2671 2672func TestUncompressDex(t *testing.T) { 2673 testCases := []struct { 2674 name string 2675 bp string 2676 2677 uncompressedPlatform bool 2678 uncompressedUnbundled bool 2679 }{ 2680 { 2681 name: "normal", 2682 bp: ` 2683 android_app { 2684 name: "foo", 2685 srcs: ["a.java"], 2686 sdk_version: "current", 2687 } 2688 `, 2689 uncompressedPlatform: true, 2690 uncompressedUnbundled: false, 2691 }, 2692 { 2693 name: "use_embedded_dex", 2694 bp: ` 2695 android_app { 2696 name: "foo", 2697 use_embedded_dex: true, 2698 srcs: ["a.java"], 2699 sdk_version: "current", 2700 } 2701 `, 2702 uncompressedPlatform: true, 2703 uncompressedUnbundled: true, 2704 }, 2705 { 2706 name: "privileged", 2707 bp: ` 2708 android_app { 2709 name: "foo", 2710 privileged: true, 2711 srcs: ["a.java"], 2712 sdk_version: "current", 2713 } 2714 `, 2715 uncompressedPlatform: true, 2716 uncompressedUnbundled: true, 2717 }, 2718 { 2719 name: "normal_uncompress_dex_true", 2720 bp: ` 2721 android_app { 2722 name: "foo", 2723 srcs: ["a.java"], 2724 sdk_version: "current", 2725 uncompress_dex: true, 2726 } 2727 `, 2728 uncompressedPlatform: true, 2729 uncompressedUnbundled: true, 2730 }, 2731 { 2732 name: "normal_uncompress_dex_false", 2733 bp: ` 2734 android_app { 2735 name: "foo", 2736 srcs: ["a.java"], 2737 sdk_version: "current", 2738 uncompress_dex: false, 2739 } 2740 `, 2741 uncompressedPlatform: false, 2742 uncompressedUnbundled: false, 2743 }, 2744 } 2745 2746 test := func(t *testing.T, bp string, want bool, unbundled bool) { 2747 t.Helper() 2748 2749 result := android.GroupFixturePreparers( 2750 prepareForJavaTest, 2751 PrepareForTestWithPrebuiltsOfCurrentApi, 2752 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 2753 if unbundled { 2754 variables.Unbundled_build = proptools.BoolPtr(true) 2755 variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true) 2756 } 2757 }), 2758 ).RunTestWithBp(t, bp) 2759 2760 foo := result.ModuleForTests("foo", "android_common") 2761 dex := foo.Rule("r8") 2762 uncompressedInDexJar := strings.Contains(dex.Args["zipFlags"], "-L 0") 2763 aligned := foo.MaybeRule("zipalign").Rule != nil 2764 2765 android.AssertBoolEquals(t, "uncompressed in dex", want, uncompressedInDexJar) 2766 2767 android.AssertBoolEquals(t, "aligne", want, aligned) 2768 } 2769 2770 for _, tt := range testCases { 2771 t.Run(tt.name, func(t *testing.T) { 2772 t.Run("platform", func(t *testing.T) { 2773 test(t, tt.bp, tt.uncompressedPlatform, false) 2774 }) 2775 t.Run("unbundled", func(t *testing.T) { 2776 test(t, tt.bp, tt.uncompressedUnbundled, true) 2777 }) 2778 }) 2779 } 2780} 2781 2782func checkAapt2LinkFlag(t *testing.T, aapt2Flags, flagName, expectedValue string) { 2783 if expectedValue != "" { 2784 expectedFlag := "--" + flagName + " " + expectedValue 2785 if !strings.Contains(aapt2Flags, expectedFlag) { 2786 t.Errorf("%q is missing in aapt2 link flags, %q", expectedFlag, aapt2Flags) 2787 } 2788 } else { 2789 unexpectedFlag := "--" + flagName 2790 if strings.Contains(aapt2Flags, unexpectedFlag) { 2791 t.Errorf("unexpected flag, %q is found in aapt2 link flags, %q", unexpectedFlag, aapt2Flags) 2792 } 2793 } 2794} 2795 2796func TestExportedProguardFlagFiles(t *testing.T) { 2797 ctx, _ := testJava(t, ` 2798 android_app { 2799 name: "foo", 2800 sdk_version: "current", 2801 static_libs: ["lib1"], 2802 } 2803 2804 android_library { 2805 name: "lib1", 2806 sdk_version: "current", 2807 optimize: { 2808 proguard_flags_files: ["lib1proguard.cfg"], 2809 } 2810 } 2811 `) 2812 2813 m := ctx.ModuleForTests("foo", "android_common") 2814 hasLib1Proguard := false 2815 for _, s := range m.Rule("java.r8").Implicits.Strings() { 2816 if s == "lib1proguard.cfg" { 2817 hasLib1Proguard = true 2818 break 2819 } 2820 } 2821 2822 if !hasLib1Proguard { 2823 t.Errorf("App does not use library proguard config") 2824 } 2825} 2826