1// Copyright 2018 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 apex 16 17import ( 18 "fmt" 19 "path" 20 "path/filepath" 21 "reflect" 22 "regexp" 23 "slices" 24 "sort" 25 "strconv" 26 "strings" 27 "testing" 28 29 "android/soong/aconfig/codegen" 30 31 "github.com/google/blueprint" 32 "github.com/google/blueprint/bpmodify" 33 "github.com/google/blueprint/proptools" 34 35 "android/soong/android" 36 "android/soong/bpf" 37 "android/soong/cc" 38 "android/soong/dexpreopt" 39 prebuilt_etc "android/soong/etc" 40 "android/soong/filesystem" 41 "android/soong/java" 42 "android/soong/rust" 43 "android/soong/sh" 44) 45 46// names returns name list from white space separated string 47func names(s string) (ns []string) { 48 for _, n := range strings.Split(s, " ") { 49 if len(n) > 0 { 50 ns = append(ns, n) 51 } 52 } 53 return 54} 55 56func testApexError(t *testing.T, pattern, bp string, preparers ...android.FixturePreparer) { 57 t.Helper() 58 android.GroupFixturePreparers( 59 prepareForApexTest, 60 android.GroupFixturePreparers(preparers...), 61 ). 62 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)). 63 RunTestWithBp(t, bp) 64} 65 66func testApex(t *testing.T, bp string, preparers ...android.FixturePreparer) *android.TestContext { 67 t.Helper() 68 69 optionalBpPreparer := android.NullFixturePreparer 70 if bp != "" { 71 optionalBpPreparer = android.FixtureWithRootAndroidBp(bp) 72 } 73 74 result := android.GroupFixturePreparers( 75 prepareForApexTest, 76 android.GroupFixturePreparers(preparers...), 77 optionalBpPreparer, 78 ).RunTest(t) 79 80 return result.TestContext 81} 82 83func withFiles(files android.MockFS) android.FixturePreparer { 84 return files.AddToFixture() 85} 86 87func withManifestPackageNameOverrides(specs []string) android.FixturePreparer { 88 return android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 89 variables.ManifestPackageNameOverrides = specs 90 }) 91} 92 93func withApexGlobalMinSdkVersionOverride(minSdkOverride *string) android.FixturePreparer { 94 return android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 95 variables.ApexGlobalMinSdkVersionOverride = minSdkOverride 96 }) 97} 98 99var withBinder32bit = android.FixtureModifyProductVariables( 100 func(variables android.FixtureProductVariables) { 101 variables.Binder32bit = proptools.BoolPtr(true) 102 }, 103) 104 105var withUnbundledBuild = android.FixtureModifyProductVariables( 106 func(variables android.FixtureProductVariables) { 107 variables.Unbundled_build = proptools.BoolPtr(true) 108 }, 109) 110 111// Legacy preparer used for running tests within the apex package. 112// 113// This includes everything that was needed to run any test in the apex package prior to the 114// introduction of the test fixtures. Tests that are being converted to use fixtures directly 115// rather than through the testApex...() methods should avoid using this and instead use the 116// various preparers directly, using android.GroupFixturePreparers(...) to group them when 117// necessary. 118// 119// deprecated 120var prepareForApexTest = android.GroupFixturePreparers( 121 // General preparers in alphabetical order as test infrastructure will enforce correct 122 // registration order. 123 android.PrepareForTestWithAndroidBuildComponents, 124 bpf.PrepareForTestWithBpf, 125 cc.PrepareForTestWithCcBuildComponents, 126 java.PrepareForTestWithDexpreopt, 127 prebuilt_etc.PrepareForTestWithPrebuiltEtc, 128 rust.PrepareForTestWithRustDefaultModules, 129 sh.PrepareForTestWithShBuildComponents, 130 codegen.PrepareForTestWithAconfigBuildComponents, 131 132 PrepareForTestWithApexBuildComponents, 133 134 // Additional apex test specific preparers. 135 android.FixtureAddTextFile("system/sepolicy/Android.bp", ` 136 filegroup { 137 name: "myapex-file_contexts", 138 srcs: [ 139 "apex/myapex-file_contexts", 140 ], 141 } 142 `), 143 prepareForTestWithMyapex, 144 android.FixtureMergeMockFs(android.MockFS{ 145 "a.java": nil, 146 "PrebuiltAppFoo.apk": nil, 147 "PrebuiltAppFooPriv.apk": nil, 148 "apex_manifest.json": nil, 149 "AndroidManifest.xml": nil, 150 "system/sepolicy/apex/myapex.updatable-file_contexts": nil, 151 "system/sepolicy/apex/myapex2-file_contexts": nil, 152 "system/sepolicy/apex/otherapex-file_contexts": nil, 153 "system/sepolicy/apex/com.android.vndk-file_contexts": nil, 154 "system/sepolicy/apex/com.android.vndk.current-file_contexts": nil, 155 "mylib.cpp": nil, 156 "mytest.cpp": nil, 157 "mytest1.cpp": nil, 158 "mytest2.cpp": nil, 159 "mytest3.cpp": nil, 160 "myprebuilt": nil, 161 "my_include": nil, 162 "foo/bar/MyClass.java": nil, 163 "prebuilt.jar": nil, 164 "prebuilt.so": nil, 165 "vendor/foo/devkeys/test.x509.pem": nil, 166 "vendor/foo/devkeys/test.pk8": nil, 167 "testkey.x509.pem": nil, 168 "testkey.pk8": nil, 169 "testkey.override.x509.pem": nil, 170 "testkey.override.pk8": nil, 171 "vendor/foo/devkeys/testkey.avbpubkey": nil, 172 "vendor/foo/devkeys/testkey.pem": nil, 173 "NOTICE": nil, 174 "custom_notice": nil, 175 "custom_notice_for_static_lib": nil, 176 "testkey2.avbpubkey": nil, 177 "testkey2.pem": nil, 178 "myapex-arm64.apex": nil, 179 "myapex-arm.apex": nil, 180 "myapex.apks": nil, 181 "frameworks/base/api/current.txt": nil, 182 "framework/aidl/a.aidl": nil, 183 "dummy.txt": nil, 184 "baz": nil, 185 "bar/baz": nil, 186 "testdata/baz": nil, 187 "AppSet.apks": nil, 188 "foo.rs": nil, 189 "libfoo.jar": nil, 190 "libbar.jar": nil, 191 }, 192 ), 193 194 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 195 variables.DefaultAppCertificate = proptools.StringPtr("vendor/foo/devkeys/test") 196 variables.CertificateOverrides = []string{"myapex_keytest:myapex.certificate.override"} 197 variables.Platform_sdk_codename = proptools.StringPtr("Q") 198 variables.Platform_sdk_final = proptools.BoolPtr(false) 199 // "Tiramisu" needs to be in the next line for compatibility with soong code, 200 // not because of these tests specifically (it's not used by the tests) 201 variables.Platform_version_active_codenames = []string{"Q", "Tiramisu"} 202 variables.BuildId = proptools.StringPtr("TEST.BUILD_ID") 203 }), 204) 205 206var prepareForTestWithMyapex = android.FixtureMergeMockFs(android.MockFS{ 207 "system/sepolicy/apex/myapex-file_contexts": nil, 208}) 209 210var prepareForTestWithOtherapex = android.FixtureMergeMockFs(android.MockFS{ 211 "system/sepolicy/apex/otherapex-file_contexts": nil, 212}) 213 214// ensure that 'result' equals 'expected' 215func ensureEquals(t *testing.T, result string, expected string) { 216 t.Helper() 217 if result != expected { 218 t.Errorf("%q != %q", expected, result) 219 } 220} 221 222// ensure that 'result' contains 'expected' 223func ensureContains(t *testing.T, result string, expected string) { 224 t.Helper() 225 if !strings.Contains(result, expected) { 226 t.Errorf("%q is not found in %q", expected, result) 227 } 228} 229 230// ensure that 'result' contains 'expected' exactly one time 231func ensureContainsOnce(t *testing.T, result string, expected string) { 232 t.Helper() 233 count := strings.Count(result, expected) 234 if count != 1 { 235 t.Errorf("%q is found %d times (expected 1 time) in %q", expected, count, result) 236 } 237} 238 239// ensures that 'result' does not contain 'notExpected' 240func ensureNotContains(t *testing.T, result string, notExpected string) { 241 t.Helper() 242 if strings.Contains(result, notExpected) { 243 t.Errorf("%q is found in %q", notExpected, result) 244 } 245} 246 247func ensureMatches(t *testing.T, result string, expectedRex string) { 248 t.Helper() 249 ok, err := regexp.MatchString(expectedRex, result) 250 if err != nil { 251 t.Fatalf("regexp failure trying to match %s against `%s` expression: %s", result, expectedRex, err) 252 return 253 } 254 if !ok { 255 t.Errorf("%s does not match regular expession %s", result, expectedRex) 256 } 257} 258 259func ensureListContainsMatch(t *testing.T, result []string, expectedRex string) { 260 t.Helper() 261 p := regexp.MustCompile(expectedRex) 262 if android.IndexListPred(func(s string) bool { return p.MatchString(s) }, result) == -1 { 263 t.Errorf("%q is not found in %v", expectedRex, result) 264 } 265} 266 267func ensureListContains(t *testing.T, result []string, expected string) { 268 t.Helper() 269 if !android.InList(expected, result) { 270 t.Errorf("%q is not found in %v", expected, result) 271 } 272} 273 274func ensureListNotContains(t *testing.T, result []string, notExpected string) { 275 t.Helper() 276 if android.InList(notExpected, result) { 277 t.Errorf("%q is found in %v", notExpected, result) 278 } 279} 280 281func ensureListEmpty(t *testing.T, result []string) { 282 t.Helper() 283 if len(result) > 0 { 284 t.Errorf("%q is expected to be empty", result) 285 } 286} 287 288func ensureListNotEmpty(t *testing.T, result []string) { 289 t.Helper() 290 if len(result) == 0 { 291 t.Errorf("%q is expected to be not empty", result) 292 } 293} 294 295// Minimal test 296func TestBasicApex(t *testing.T) { 297 t.Parallel() 298 ctx := testApex(t, ` 299 apex_defaults { 300 name: "myapex-defaults", 301 manifest: ":myapex.manifest", 302 androidManifest: ":myapex.androidmanifest", 303 key: "myapex.key", 304 binaries: ["foo.rust"], 305 native_shared_libs: [ 306 "mylib", 307 "libfoo.ffi", 308 ], 309 rust_dyn_libs: ["libfoo.dylib.rust"], 310 multilib: { 311 both: { 312 binaries: ["foo"], 313 } 314 }, 315 java_libs: [ 316 "myjar", 317 "myjar_dex", 318 ], 319 updatable: false, 320 } 321 322 apex { 323 name: "myapex", 324 defaults: ["myapex-defaults"], 325 } 326 327 apex_key { 328 name: "myapex.key", 329 public_key: "testkey.avbpubkey", 330 private_key: "testkey.pem", 331 } 332 333 filegroup { 334 name: "myapex.manifest", 335 srcs: ["apex_manifest.json"], 336 } 337 338 filegroup { 339 name: "myapex.androidmanifest", 340 srcs: ["AndroidManifest.xml"], 341 } 342 343 cc_library { 344 name: "mylib", 345 srcs: ["mylib.cpp"], 346 shared_libs: [ 347 "mylib2", 348 "libbar.ffi", 349 ], 350 system_shared_libs: [], 351 stl: "none", 352 // TODO: remove //apex_available:platform 353 apex_available: [ 354 "//apex_available:platform", 355 "myapex", 356 ], 357 } 358 359 cc_binary { 360 name: "foo", 361 srcs: ["mylib.cpp"], 362 compile_multilib: "both", 363 multilib: { 364 lib32: { 365 suffix: "32", 366 }, 367 lib64: { 368 suffix: "64", 369 }, 370 }, 371 symlinks: ["foo_link_"], 372 symlink_preferred_arch: true, 373 system_shared_libs: [], 374 stl: "none", 375 apex_available: [ "myapex" ], 376 } 377 378 rust_binary { 379 name: "foo.rust", 380 srcs: ["foo.rs"], 381 rlibs: ["libfoo.rlib.rust"], 382 rustlibs: ["libfoo.transitive.dylib.rust"], 383 apex_available: ["myapex"], 384 } 385 386 rust_library_rlib { 387 name: "libfoo.rlib.rust", 388 srcs: ["foo.rs"], 389 crate_name: "foo", 390 apex_available: ["myapex"], 391 shared_libs: ["libfoo.shared_from_rust"], 392 } 393 394 cc_library_shared { 395 name: "libfoo.shared_from_rust", 396 srcs: ["mylib.cpp"], 397 system_shared_libs: [], 398 stl: "none", 399 apex_available: ["myapex"], 400 } 401 402 rust_library_dylib { 403 name: "libfoo.dylib.rust", 404 srcs: ["foo.rs"], 405 crate_name: "foo", 406 apex_available: ["myapex"], 407 } 408 409 rust_library_dylib { 410 name: "libfoo.transitive.dylib.rust", 411 srcs: ["foo.rs"], 412 crate_name: "foo", 413 apex_available: ["myapex"], 414 } 415 416 rust_ffi_shared { 417 name: "libfoo.ffi", 418 srcs: ["foo.rs"], 419 crate_name: "foo", 420 apex_available: ["myapex"], 421 } 422 423 rust_ffi_shared { 424 name: "libbar.ffi", 425 srcs: ["foo.rs"], 426 crate_name: "bar", 427 apex_available: ["myapex"], 428 } 429 430 cc_library_shared { 431 name: "mylib2", 432 srcs: ["mylib.cpp"], 433 system_shared_libs: [], 434 stl: "none", 435 static_libs: ["libstatic"], 436 // TODO: remove //apex_available:platform 437 apex_available: [ 438 "//apex_available:platform", 439 "myapex", 440 ], 441 } 442 443 cc_prebuilt_library_shared { 444 name: "mylib2", 445 srcs: ["prebuilt.so"], 446 // TODO: remove //apex_available:platform 447 apex_available: [ 448 "//apex_available:platform", 449 "myapex", 450 ], 451 } 452 453 cc_library_static { 454 name: "libstatic", 455 srcs: ["mylib.cpp"], 456 system_shared_libs: [], 457 stl: "none", 458 // TODO: remove //apex_available:platform 459 apex_available: [ 460 "//apex_available:platform", 461 "myapex", 462 ], 463 } 464 465 java_library { 466 name: "myjar", 467 srcs: ["foo/bar/MyClass.java"], 468 stem: "myjar_stem", 469 sdk_version: "none", 470 system_modules: "none", 471 static_libs: ["myotherjar"], 472 libs: ["mysharedjar"], 473 // TODO: remove //apex_available:platform 474 apex_available: [ 475 "//apex_available:platform", 476 "myapex", 477 ], 478 compile_dex: true, 479 } 480 481 dex_import { 482 name: "myjar_dex", 483 jars: ["prebuilt.jar"], 484 apex_available: [ 485 "//apex_available:platform", 486 "myapex", 487 ], 488 } 489 490 java_library { 491 name: "myotherjar", 492 srcs: ["foo/bar/MyClass.java"], 493 sdk_version: "none", 494 system_modules: "none", 495 // TODO: remove //apex_available:platform 496 apex_available: [ 497 "//apex_available:platform", 498 "myapex", 499 ], 500 } 501 502 java_library { 503 name: "mysharedjar", 504 srcs: ["foo/bar/MyClass.java"], 505 sdk_version: "none", 506 system_modules: "none", 507 } 508 `) 509 510 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule") 511 512 // Make sure that Android.mk is created 513 ab := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle) 514 data := android.AndroidMkDataForTest(t, ctx, ab) 515 var builder strings.Builder 516 data.Custom(&builder, ab.BaseModuleName(), "TARGET_", "", data) 517 518 androidMk := builder.String() 519 ensureContains(t, androidMk, "LOCAL_MODULE := mylib.myapex\n") 520 ensureNotContains(t, androidMk, "LOCAL_MODULE := mylib.com.android.myapex\n") 521 522 optFlags := apexRule.Args["opt_flags"] 523 ensureContains(t, optFlags, "--pubkey vendor/foo/devkeys/testkey.avbpubkey") 524 // Ensure that the NOTICE output is being packaged as an asset. 525 ensureContains(t, optFlags, "--assets_dir out/soong/.intermediates/myapex/android_common_myapex/NOTICE") 526 527 copyCmds := apexRule.Args["copy_commands"] 528 529 // Ensure that main rule creates an output 530 ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned") 531 532 // Ensure that apex variant is created for the direct dep 533 ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_apex10000") 534 ensureListContains(t, ctx.ModuleVariantsForTests("myjar"), "android_common_apex10000") 535 ensureListContains(t, ctx.ModuleVariantsForTests("myjar_dex"), "android_common_apex10000") 536 ensureListContains(t, ctx.ModuleVariantsForTests("foo.rust"), "android_arm64_armv8-a_apex10000") 537 ensureListContains(t, ctx.ModuleVariantsForTests("libfoo.ffi"), "android_arm64_armv8-a_shared_apex10000") 538 539 // Ensure that apex variant is created for the indirect dep 540 ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_apex10000") 541 ensureListContains(t, ctx.ModuleVariantsForTests("myotherjar"), "android_common_apex10000") 542 ensureListContains(t, ctx.ModuleVariantsForTests("libfoo.rlib.rust"), "android_arm64_armv8-a_rlib_dylib-std_apex10000") 543 ensureListContains(t, ctx.ModuleVariantsForTests("libfoo.dylib.rust"), "android_arm64_armv8-a_dylib_apex10000") 544 ensureListContains(t, ctx.ModuleVariantsForTests("libfoo.transitive.dylib.rust"), "android_arm64_armv8-a_dylib_apex10000") 545 ensureListContains(t, ctx.ModuleVariantsForTests("libbar.ffi"), "android_arm64_armv8-a_shared_apex10000") 546 ensureListContains(t, ctx.ModuleVariantsForTests("libfoo.shared_from_rust"), "android_arm64_armv8-a_shared_apex10000") 547 548 // Ensure that both direct and indirect deps are copied into apex 549 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") 550 ensureContains(t, copyCmds, "image.apex/lib64/mylib2.so") 551 ensureContains(t, copyCmds, "image.apex/javalib/myjar_stem.jar") 552 ensureContains(t, copyCmds, "image.apex/javalib/myjar_dex.jar") 553 ensureContains(t, copyCmds, "image.apex/lib64/libfoo.dylib.rust.dylib.so") 554 ensureContains(t, copyCmds, "image.apex/lib64/libfoo.transitive.dylib.rust.dylib.so") 555 ensureContains(t, copyCmds, "image.apex/lib64/libfoo.ffi.so") 556 ensureContains(t, copyCmds, "image.apex/lib64/libbar.ffi.so") 557 ensureContains(t, copyCmds, "image.apex/lib64/libfoo.shared_from_rust.so") 558 // .. but not for java libs 559 ensureNotContains(t, copyCmds, "image.apex/javalib/myotherjar.jar") 560 ensureNotContains(t, copyCmds, "image.apex/javalib/msharedjar.jar") 561 562 // Ensure that the platform variant ends with _shared or _common 563 ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared") 564 ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared") 565 ensureListContains(t, ctx.ModuleVariantsForTests("myjar"), "android_common") 566 ensureListContains(t, ctx.ModuleVariantsForTests("myotherjar"), "android_common") 567 ensureListContains(t, ctx.ModuleVariantsForTests("mysharedjar"), "android_common") 568 569 // Ensure that dynamic dependency to java libs are not included 570 ensureListNotContains(t, ctx.ModuleVariantsForTests("mysharedjar"), "android_common_myapex") 571 572 // Ensure that all symlinks are present. 573 found_foo_link_64 := false 574 found_foo := false 575 for _, cmd := range strings.Split(copyCmds, " && ") { 576 if strings.HasPrefix(cmd, "ln -sfn foo64") { 577 if strings.HasSuffix(cmd, "bin/foo") { 578 found_foo = true 579 } else if strings.HasSuffix(cmd, "bin/foo_link_64") { 580 found_foo_link_64 = true 581 } 582 } 583 } 584 good := found_foo && found_foo_link_64 585 if !good { 586 t.Errorf("Could not find all expected symlinks! foo: %t, foo_link_64: %t. Command was %s", found_foo, found_foo_link_64, copyCmds) 587 } 588 589 fullDepsInfo := strings.Split(android.ContentFromFileRuleForTests(t, ctx, 590 ctx.ModuleForTests("myapex", "android_common_myapex").Output("depsinfo/fulllist.txt")), "\n") 591 ensureListContains(t, fullDepsInfo, " myjar(minSdkVersion:(no version)) <- myapex") 592 ensureListContains(t, fullDepsInfo, " mylib2(minSdkVersion:(no version)) <- mylib") 593 ensureListContains(t, fullDepsInfo, " myotherjar(minSdkVersion:(no version)) <- myjar") 594 ensureListContains(t, fullDepsInfo, " mysharedjar(minSdkVersion:(no version)) (external) <- myjar") 595 596 flatDepsInfo := strings.Split(android.ContentFromFileRuleForTests(t, ctx, 597 ctx.ModuleForTests("myapex", "android_common_myapex").Output("depsinfo/flatlist.txt")), "\n") 598 ensureListContains(t, flatDepsInfo, "myjar(minSdkVersion:(no version))") 599 ensureListContains(t, flatDepsInfo, "mylib2(minSdkVersion:(no version))") 600 ensureListContains(t, flatDepsInfo, "myotherjar(minSdkVersion:(no version))") 601 ensureListContains(t, flatDepsInfo, "mysharedjar(minSdkVersion:(no version)) (external)") 602} 603 604func TestDefaults(t *testing.T) { 605 t.Parallel() 606 ctx := testApex(t, ` 607 apex_defaults { 608 name: "myapex-defaults", 609 key: "myapex.key", 610 prebuilts: ["myetc"], 611 native_shared_libs: ["mylib"], 612 java_libs: ["myjar"], 613 apps: ["AppFoo"], 614 rros: ["rro"], 615 bpfs: ["bpf", "netdTest"], 616 updatable: false, 617 } 618 619 prebuilt_etc { 620 name: "myetc", 621 src: "myprebuilt", 622 } 623 624 apex { 625 name: "myapex", 626 defaults: ["myapex-defaults"], 627 } 628 629 apex_key { 630 name: "myapex.key", 631 public_key: "testkey.avbpubkey", 632 private_key: "testkey.pem", 633 } 634 635 cc_library { 636 name: "mylib", 637 system_shared_libs: [], 638 stl: "none", 639 apex_available: [ "myapex" ], 640 } 641 642 java_library { 643 name: "myjar", 644 srcs: ["foo/bar/MyClass.java"], 645 sdk_version: "none", 646 system_modules: "none", 647 apex_available: [ "myapex" ], 648 compile_dex: true, 649 } 650 651 android_app { 652 name: "AppFoo", 653 srcs: ["foo/bar/MyClass.java"], 654 sdk_version: "none", 655 system_modules: "none", 656 apex_available: [ "myapex" ], 657 } 658 659 runtime_resource_overlay { 660 name: "rro", 661 theme: "blue", 662 } 663 664 bpf { 665 name: "bpf", 666 srcs: ["bpf.c", "bpf2.c"], 667 } 668 669 bpf { 670 name: "netdTest", 671 srcs: ["netdTest.c"], 672 sub_dir: "netd", 673 } 674 675 `) 676 ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{ 677 "etc/myetc", 678 "javalib/myjar.jar", 679 "lib64/mylib.so", 680 "app/AppFoo@TEST.BUILD_ID/AppFoo.apk", 681 "overlay/blue/rro.apk", 682 "etc/bpf/bpf.o", 683 "etc/bpf/bpf2.o", 684 "etc/bpf/netd/netdTest.o", 685 }) 686} 687 688func TestApexManifest(t *testing.T) { 689 t.Parallel() 690 ctx := testApex(t, ` 691 apex { 692 name: "myapex", 693 key: "myapex.key", 694 updatable: false, 695 } 696 697 apex_key { 698 name: "myapex.key", 699 public_key: "testkey.avbpubkey", 700 private_key: "testkey.pem", 701 } 702 `) 703 704 module := ctx.ModuleForTests("myapex", "android_common_myapex") 705 args := module.Rule("apexRule").Args 706 if manifest := args["manifest"]; manifest != module.Output("apex_manifest.pb").Output.String() { 707 t.Error("manifest should be apex_manifest.pb, but " + manifest) 708 } 709} 710 711func TestApexManifestMinSdkVersion(t *testing.T) { 712 t.Parallel() 713 ctx := testApex(t, ` 714 apex_defaults { 715 name: "my_defaults", 716 key: "myapex.key", 717 product_specific: true, 718 file_contexts: ":my-file-contexts", 719 updatable: false, 720 } 721 apex { 722 name: "myapex_30", 723 min_sdk_version: "30", 724 defaults: ["my_defaults"], 725 } 726 727 apex { 728 name: "myapex_current", 729 min_sdk_version: "current", 730 defaults: ["my_defaults"], 731 } 732 733 apex { 734 name: "myapex_none", 735 defaults: ["my_defaults"], 736 } 737 738 apex_key { 739 name: "myapex.key", 740 public_key: "testkey.avbpubkey", 741 private_key: "testkey.pem", 742 } 743 744 filegroup { 745 name: "my-file-contexts", 746 srcs: ["product_specific_file_contexts"], 747 } 748 `, withFiles(map[string][]byte{ 749 "product_specific_file_contexts": nil, 750 }), android.FixtureModifyProductVariables( 751 func(variables android.FixtureProductVariables) { 752 variables.Unbundled_build = proptools.BoolPtr(true) 753 variables.Always_use_prebuilt_sdks = proptools.BoolPtr(false) 754 }), android.FixtureMergeEnv(map[string]string{ 755 "UNBUNDLED_BUILD_TARGET_SDK_WITH_API_FINGERPRINT": "true", 756 })) 757 758 testCases := []struct { 759 module string 760 minSdkVersion string 761 }{ 762 { 763 module: "myapex_30", 764 minSdkVersion: "30", 765 }, 766 { 767 module: "myapex_current", 768 minSdkVersion: "Q.$$(cat out/soong/api_fingerprint.txt)", 769 }, 770 { 771 module: "myapex_none", 772 minSdkVersion: "Q.$$(cat out/soong/api_fingerprint.txt)", 773 }, 774 } 775 for _, tc := range testCases { 776 module := ctx.ModuleForTests(tc.module, "android_common_"+tc.module) 777 args := module.Rule("apexRule").Args 778 optFlags := args["opt_flags"] 779 if !strings.Contains(optFlags, "--min_sdk_version "+tc.minSdkVersion) { 780 t.Errorf("%s: Expected min_sdk_version=%s, got: %s", tc.module, tc.minSdkVersion, optFlags) 781 } 782 } 783} 784 785func TestApexWithDessertSha(t *testing.T) { 786 t.Parallel() 787 ctx := testApex(t, ` 788 apex_defaults { 789 name: "my_defaults", 790 key: "myapex.key", 791 product_specific: true, 792 file_contexts: ":my-file-contexts", 793 updatable: false, 794 } 795 apex { 796 name: "myapex_30", 797 min_sdk_version: "30", 798 defaults: ["my_defaults"], 799 } 800 801 apex { 802 name: "myapex_current", 803 min_sdk_version: "current", 804 defaults: ["my_defaults"], 805 } 806 807 apex { 808 name: "myapex_none", 809 defaults: ["my_defaults"], 810 } 811 812 apex_key { 813 name: "myapex.key", 814 public_key: "testkey.avbpubkey", 815 private_key: "testkey.pem", 816 } 817 818 filegroup { 819 name: "my-file-contexts", 820 srcs: ["product_specific_file_contexts"], 821 } 822 `, withFiles(map[string][]byte{ 823 "product_specific_file_contexts": nil, 824 }), android.FixtureModifyProductVariables( 825 func(variables android.FixtureProductVariables) { 826 variables.Unbundled_build = proptools.BoolPtr(true) 827 variables.Always_use_prebuilt_sdks = proptools.BoolPtr(false) 828 }), android.FixtureMergeEnv(map[string]string{ 829 "UNBUNDLED_BUILD_TARGET_SDK_WITH_DESSERT_SHA": "UpsideDownCake.abcdefghijklmnopqrstuvwxyz123456", 830 })) 831 832 testCases := []struct { 833 module string 834 minSdkVersion string 835 }{ 836 { 837 module: "myapex_30", 838 minSdkVersion: "30", 839 }, 840 { 841 module: "myapex_current", 842 minSdkVersion: "UpsideDownCake.abcdefghijklmnopqrstuvwxyz123456", 843 }, 844 { 845 module: "myapex_none", 846 minSdkVersion: "UpsideDownCake.abcdefghijklmnopqrstuvwxyz123456", 847 }, 848 } 849 for _, tc := range testCases { 850 module := ctx.ModuleForTests(tc.module, "android_common_"+tc.module) 851 args := module.Rule("apexRule").Args 852 optFlags := args["opt_flags"] 853 if !strings.Contains(optFlags, "--min_sdk_version "+tc.minSdkVersion) { 854 t.Errorf("%s: Expected min_sdk_version=%s, got: %s", tc.module, tc.minSdkVersion, optFlags) 855 } 856 } 857} 858 859func TestFileContexts(t *testing.T) { 860 t.Parallel() 861 for _, vendor := range []bool{true, false} { 862 prop := "" 863 if vendor { 864 prop = "vendor: true,\n" 865 } 866 ctx := testApex(t, ` 867 apex { 868 name: "myapex", 869 key: "myapex.key", 870 updatable: false, 871 `+prop+` 872 } 873 874 apex_key { 875 name: "myapex.key", 876 public_key: "testkey.avbpubkey", 877 private_key: "testkey.pem", 878 } 879 `) 880 881 rule := ctx.ModuleForTests("myapex", "android_common_myapex").Output("file_contexts") 882 if vendor { 883 android.AssertStringDoesContain(t, "should force-label as vendor_apex_metadata_file", 884 rule.RuleParams.Command, 885 "apex_manifest\\\\.pb u:object_r:vendor_apex_metadata_file:s0") 886 } else { 887 android.AssertStringDoesContain(t, "should force-label as system_file", 888 rule.RuleParams.Command, 889 "apex_manifest\\\\.pb u:object_r:system_file:s0") 890 } 891 } 892} 893 894func TestApexWithStubs(t *testing.T) { 895 t.Parallel() 896 ctx := testApex(t, ` 897 apex { 898 name: "myapex", 899 key: "myapex.key", 900 native_shared_libs: ["mylib", "mylib3"], 901 binaries: ["foo.rust"], 902 updatable: false, 903 } 904 905 apex_key { 906 name: "myapex.key", 907 public_key: "testkey.avbpubkey", 908 private_key: "testkey.pem", 909 } 910 911 cc_library { 912 name: "mylib", 913 srcs: ["mylib.cpp"], 914 shared_libs: ["mylib2", "mylib3#impl", "my_prebuilt_platform_lib", "my_prebuilt_platform_stub_only_lib"], 915 system_shared_libs: [], 916 stl: "none", 917 apex_available: [ "myapex" ], 918 } 919 920 cc_library { 921 name: "mylib2", 922 srcs: ["mylib.cpp"], 923 cflags: ["-include mylib.h"], 924 system_shared_libs: [], 925 stl: "none", 926 stubs: { 927 symbol_file: "mylib2.map.txt", 928 versions: ["1", "2", "3"], 929 }, 930 } 931 932 cc_library { 933 name: "mylib3", 934 srcs: ["mylib.cpp"], 935 shared_libs: ["mylib4"], 936 system_shared_libs: [], 937 stl: "none", 938 stubs: { 939 symbol_file: "mylib3.map.txt", 940 versions: ["10", "11", "12"], 941 }, 942 apex_available: [ "myapex" ], 943 } 944 945 cc_library { 946 name: "mylib4", 947 srcs: ["mylib.cpp"], 948 system_shared_libs: [], 949 stl: "none", 950 apex_available: [ "myapex" ], 951 } 952 953 cc_prebuilt_library_shared { 954 name: "my_prebuilt_platform_lib", 955 stubs: { 956 symbol_file: "my_prebuilt_platform_lib.map.txt", 957 versions: ["1", "2", "3"], 958 }, 959 srcs: ["foo.so"], 960 } 961 962 // Similar to my_prebuilt_platform_lib, but this library only provides stubs, i.e. srcs is empty 963 cc_prebuilt_library_shared { 964 name: "my_prebuilt_platform_stub_only_lib", 965 stubs: { 966 symbol_file: "my_prebuilt_platform_stub_only_lib.map.txt", 967 versions: ["1", "2", "3"], 968 } 969 } 970 971 rust_binary { 972 name: "foo.rust", 973 srcs: ["foo.rs"], 974 shared_libs: ["libfoo.shared_from_rust"], 975 prefer_rlib: true, 976 apex_available: ["myapex"], 977 } 978 979 cc_library_shared { 980 name: "libfoo.shared_from_rust", 981 srcs: ["mylib.cpp"], 982 system_shared_libs: [], 983 stl: "none", 984 stubs: { 985 versions: ["10", "11", "12"], 986 }, 987 } 988 989 `) 990 991 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule") 992 copyCmds := apexRule.Args["copy_commands"] 993 994 // Ensure that direct non-stubs dep is always included 995 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") 996 997 // Ensure that indirect stubs dep is not included 998 ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so") 999 1000 // Ensure that direct stubs dep is included 1001 ensureContains(t, copyCmds, "image.apex/lib64/mylib3.so") 1002 1003 mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"] 1004 1005 // Ensure that mylib is linking with the latest version of stubs for mylib2 1006 ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_current/mylib2.so") 1007 // ... and not linking to the non-stub (impl) variant of mylib2 1008 ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so") 1009 1010 // Ensure that mylib is linking with the non-stub (impl) of mylib3 (because the dependency is added with mylib3#impl) 1011 ensureContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_apex10000/mylib3.so") 1012 // .. and not linking to the stubs variant of mylib3 1013 ensureNotContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_12/mylib3.so") 1014 1015 // Comment out this test. Now it fails after the optimization of sharing "cflags" in cc/cc.go 1016 // is replaced by sharing of "cFlags" in cc/builder.go. 1017 // The "cflags" contains "-include mylib.h", but cFlags contained only a reference to the 1018 // module variable representing "cflags". So it was not detected by ensureNotContains. 1019 // Now "cFlags" is a reference to a module variable like $flags1, which includes all previous 1020 // content of "cflags". ModuleForTests...Args["cFlags"] returns the full string of $flags1, 1021 // including the original cflags's "-include mylib.h". 1022 // 1023 // Ensure that stubs libs are built without -include flags 1024 // mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"] 1025 // ensureNotContains(t, mylib2Cflags, "-include ") 1026 1027 // Ensure that genstub for platform-provided lib is invoked with --systemapi 1028 ensureContains(t, ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"], "--systemapi") 1029 // Ensure that genstub for apex-provided lib is invoked with --apex 1030 ensureContains(t, ctx.ModuleForTests("mylib3", "android_arm64_armv8-a_shared_12").Rule("genStubSrc").Args["flags"], "--apex") 1031 1032 ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{ 1033 "lib64/mylib.so", 1034 "lib64/mylib3.so", 1035 "lib64/mylib4.so", 1036 "bin/foo.rust", 1037 "lib64/libc++.so", // by the implicit dependency from foo.rust 1038 "lib64/liblog.so", // by the implicit dependency from foo.rust 1039 }) 1040 1041 // Ensure that stub dependency from a rust module is not included 1042 ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.shared_from_rust.so") 1043 // The rust module is linked to the stub cc library 1044 rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustc").Args["linkFlags"] 1045 ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so") 1046 ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so") 1047 1048 apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexManifestRule") 1049 ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libfoo.shared_from_rust.so") 1050 1051 // Ensure that mylib is linking with the latest version of stubs for my_prebuilt_platform_lib 1052 ensureContains(t, mylibLdFlags, "my_prebuilt_platform_lib/android_arm64_armv8-a_shared_current/my_prebuilt_platform_lib.so") 1053 // ... and not linking to the non-stub (impl) variant of my_prebuilt_platform_lib 1054 ensureNotContains(t, mylibLdFlags, "my_prebuilt_platform_lib/android_arm64_armv8-a_shared/my_prebuilt_platform_lib.so") 1055 // Ensure that genstub for platform-provided lib is invoked with --systemapi 1056 ensureContains(t, ctx.ModuleForTests("my_prebuilt_platform_lib", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"], "--systemapi") 1057 1058 // Ensure that mylib is linking with the latest version of stubs for my_prebuilt_platform_lib 1059 ensureContains(t, mylibLdFlags, "my_prebuilt_platform_stub_only_lib/android_arm64_armv8-a_shared_current/my_prebuilt_platform_stub_only_lib.so") 1060 // ... and not linking to the non-stub (impl) variant of my_prebuilt_platform_lib 1061 ensureNotContains(t, mylibLdFlags, "my_prebuilt_platform_stub_only_lib/android_arm64_armv8-a_shared/my_prebuilt_platform_stub_only_lib.so") 1062 // Ensure that genstub for platform-provided lib is invoked with --systemapi 1063 ensureContains(t, ctx.ModuleForTests("my_prebuilt_platform_stub_only_lib", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"], "--systemapi") 1064} 1065 1066func TestApexShouldNotEmbedStubVariant(t *testing.T) { 1067 t.Parallel() 1068 testApexError(t, `module "myapex" .*: native_shared_libs: "libbar" is a stub`, ` 1069 apex { 1070 name: "myapex", 1071 key: "myapex.key", 1072 vendor: true, 1073 updatable: false, 1074 native_shared_libs: ["libbar"], // should not add an LLNDK stub in a vendor apex 1075 } 1076 1077 apex_key { 1078 name: "myapex.key", 1079 public_key: "testkey.avbpubkey", 1080 private_key: "testkey.pem", 1081 } 1082 1083 cc_library { 1084 name: "libbar", 1085 srcs: ["mylib.cpp"], 1086 llndk: { 1087 symbol_file: "libbar.map.txt", 1088 } 1089 } 1090 `) 1091} 1092 1093func TestApexCanUsePrivateApis(t *testing.T) { 1094 t.Parallel() 1095 ctx := testApex(t, ` 1096 apex { 1097 name: "myapex", 1098 key: "myapex.key", 1099 native_shared_libs: ["mylib"], 1100 binaries: ["foo.rust"], 1101 updatable: false, 1102 platform_apis: true, 1103 } 1104 1105 apex_key { 1106 name: "myapex.key", 1107 public_key: "testkey.avbpubkey", 1108 private_key: "testkey.pem", 1109 } 1110 1111 cc_library { 1112 name: "mylib", 1113 srcs: ["mylib.cpp"], 1114 shared_libs: ["mylib2"], 1115 system_shared_libs: [], 1116 stl: "none", 1117 apex_available: [ "myapex" ], 1118 } 1119 1120 cc_library { 1121 name: "mylib2", 1122 srcs: ["mylib.cpp"], 1123 cflags: ["-include mylib.h"], 1124 system_shared_libs: [], 1125 stl: "none", 1126 stubs: { 1127 versions: ["1", "2", "3"], 1128 }, 1129 } 1130 1131 rust_binary { 1132 name: "foo.rust", 1133 srcs: ["foo.rs"], 1134 shared_libs: ["libfoo.shared_from_rust"], 1135 prefer_rlib: true, 1136 apex_available: ["myapex"], 1137 } 1138 1139 cc_library_shared { 1140 name: "libfoo.shared_from_rust", 1141 srcs: ["mylib.cpp"], 1142 system_shared_libs: [], 1143 stl: "none", 1144 stubs: { 1145 versions: ["10", "11", "12"], 1146 }, 1147 } 1148 `) 1149 1150 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule") 1151 copyCmds := apexRule.Args["copy_commands"] 1152 1153 // Ensure that indirect stubs dep is not included 1154 ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so") 1155 ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.shared_from_rust.so") 1156 1157 // Ensure that we are using non-stub variants of mylib2 and libfoo.shared_from_rust (because 1158 // of the platform_apis: true) 1159 mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"] 1160 ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_current/mylib2.so") 1161 ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so") 1162 rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustc").Args["linkFlags"] 1163 ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so") 1164 ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so") 1165} 1166 1167func TestApexWithStubsWithMinSdkVersion(t *testing.T) { 1168 t.Parallel() 1169 ctx := testApex(t, ` 1170 apex { 1171 name: "myapex", 1172 key: "myapex.key", 1173 native_shared_libs: ["mylib", "mylib3"], 1174 min_sdk_version: "29", 1175 } 1176 1177 apex_key { 1178 name: "myapex.key", 1179 public_key: "testkey.avbpubkey", 1180 private_key: "testkey.pem", 1181 } 1182 1183 cc_library { 1184 name: "mylib", 1185 srcs: ["mylib.cpp"], 1186 shared_libs: ["mylib2", "mylib3#impl"], 1187 system_shared_libs: [], 1188 stl: "none", 1189 apex_available: [ "myapex" ], 1190 min_sdk_version: "28", 1191 } 1192 1193 cc_library { 1194 name: "mylib2", 1195 srcs: ["mylib.cpp"], 1196 cflags: ["-include mylib.h"], 1197 system_shared_libs: [], 1198 stl: "none", 1199 stubs: { 1200 symbol_file: "mylib2.map.txt", 1201 versions: ["28", "29", "30", "current"], 1202 }, 1203 min_sdk_version: "28", 1204 } 1205 1206 cc_library { 1207 name: "mylib3", 1208 srcs: ["mylib.cpp"], 1209 shared_libs: ["mylib4"], 1210 system_shared_libs: [], 1211 stl: "none", 1212 stubs: { 1213 symbol_file: "mylib3.map.txt", 1214 versions: ["28", "29", "30", "current"], 1215 }, 1216 apex_available: [ "myapex" ], 1217 min_sdk_version: "28", 1218 } 1219 1220 cc_library { 1221 name: "mylib4", 1222 srcs: ["mylib.cpp"], 1223 system_shared_libs: [], 1224 stl: "none", 1225 apex_available: [ "myapex" ], 1226 min_sdk_version: "28", 1227 } 1228 `) 1229 1230 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule") 1231 copyCmds := apexRule.Args["copy_commands"] 1232 1233 // Ensure that direct non-stubs dep is always included 1234 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") 1235 1236 // Ensure that indirect stubs dep is not included 1237 ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so") 1238 1239 // Ensure that direct stubs dep is included 1240 ensureContains(t, copyCmds, "image.apex/lib64/mylib3.so") 1241 1242 mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex29").Rule("ld").Args["libFlags"] 1243 1244 // Ensure that mylib is linking with the latest version of stub for mylib2 1245 ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_current/mylib2.so") 1246 // ... and not linking to the non-stub (impl) variant of mylib2 1247 ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so") 1248 1249 // Ensure that mylib is linking with the non-stub (impl) of mylib3 (because the dependency is added with mylib3#impl) 1250 ensureContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_apex29/mylib3.so") 1251 // .. and not linking to the stubs variant of mylib3 1252 ensureNotContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_29/mylib3.so") 1253 1254 // Ensure that stubs libs are built without -include flags 1255 mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_29").Rule("cc").Args["cFlags"] 1256 ensureNotContains(t, mylib2Cflags, "-include ") 1257 1258 // Ensure that genstub is invoked with --systemapi 1259 ensureContains(t, ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_29").Rule("genStubSrc").Args["flags"], "--systemapi") 1260 1261 ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{ 1262 "lib64/mylib.so", 1263 "lib64/mylib3.so", 1264 "lib64/mylib4.so", 1265 }) 1266} 1267 1268func TestApex_PlatformUsesLatestStubFromApex(t *testing.T) { 1269 t.Parallel() 1270 // myapex (Z) 1271 // mylib -----------------. 1272 // | 1273 // otherapex (29) | 1274 // libstub's versions: 29 Z current 1275 // | 1276 // <platform> | 1277 // libplatform ----------------' 1278 ctx := testApex(t, ` 1279 apex { 1280 name: "myapex", 1281 key: "myapex.key", 1282 native_shared_libs: ["mylib"], 1283 min_sdk_version: "Z", // non-final 1284 } 1285 1286 cc_library { 1287 name: "mylib", 1288 srcs: ["mylib.cpp"], 1289 shared_libs: ["libstub"], 1290 apex_available: ["myapex"], 1291 min_sdk_version: "Z", 1292 } 1293 1294 apex_key { 1295 name: "myapex.key", 1296 public_key: "testkey.avbpubkey", 1297 private_key: "testkey.pem", 1298 } 1299 1300 apex { 1301 name: "otherapex", 1302 key: "myapex.key", 1303 native_shared_libs: ["libstub"], 1304 min_sdk_version: "29", 1305 } 1306 1307 cc_library { 1308 name: "libstub", 1309 srcs: ["mylib.cpp"], 1310 stubs: { 1311 versions: ["29", "Z", "current"], 1312 }, 1313 apex_available: ["otherapex"], 1314 min_sdk_version: "29", 1315 } 1316 1317 // platform module depending on libstub from otherapex should use the latest stub("current") 1318 cc_library { 1319 name: "libplatform", 1320 srcs: ["mylib.cpp"], 1321 shared_libs: ["libstub"], 1322 } 1323 `, 1324 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1325 variables.Platform_sdk_codename = proptools.StringPtr("Z") 1326 variables.Platform_sdk_final = proptools.BoolPtr(false) 1327 variables.Platform_version_active_codenames = []string{"Z"} 1328 }), 1329 ) 1330 1331 // Ensure that mylib from myapex is built against the latest stub (current) 1332 mylibCflags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex10000").Rule("cc").Args["cFlags"] 1333 ensureContains(t, mylibCflags, "-D__LIBSTUB_API__=10000 ") 1334 mylibLdflags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"] 1335 ensureContains(t, mylibLdflags, "libstub/android_arm64_armv8-a_shared_current/libstub.so ") 1336 1337 // Ensure that libplatform is built against latest stub ("current") of mylib3 from the apex 1338 libplatformCflags := ctx.ModuleForTests("libplatform", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"] 1339 ensureContains(t, libplatformCflags, "-D__LIBSTUB_API__=10000 ") // "current" maps to 10000 1340 libplatformLdflags := ctx.ModuleForTests("libplatform", "android_arm64_armv8-a_shared").Rule("ld").Args["libFlags"] 1341 ensureContains(t, libplatformLdflags, "libstub/android_arm64_armv8-a_shared_current/libstub.so ") 1342} 1343 1344func TestApexWithExplicitStubsDependency(t *testing.T) { 1345 t.Parallel() 1346 ctx := testApex(t, ` 1347 apex { 1348 name: "myapex2", 1349 key: "myapex2.key", 1350 native_shared_libs: ["mylib"], 1351 updatable: false, 1352 } 1353 1354 apex_key { 1355 name: "myapex2.key", 1356 public_key: "testkey.avbpubkey", 1357 private_key: "testkey.pem", 1358 } 1359 1360 cc_library { 1361 name: "mylib", 1362 srcs: ["mylib.cpp"], 1363 shared_libs: ["libfoo#10"], 1364 static_libs: ["libbaz"], 1365 system_shared_libs: [], 1366 stl: "none", 1367 apex_available: [ "myapex2" ], 1368 } 1369 1370 cc_library { 1371 name: "libfoo", 1372 srcs: ["mylib.cpp"], 1373 shared_libs: ["libbar"], 1374 system_shared_libs: [], 1375 stl: "none", 1376 stubs: { 1377 versions: ["10", "20", "30"], 1378 }, 1379 } 1380 1381 cc_library { 1382 name: "libbar", 1383 srcs: ["mylib.cpp"], 1384 system_shared_libs: [], 1385 stl: "none", 1386 } 1387 1388 cc_library_static { 1389 name: "libbaz", 1390 srcs: ["mylib.cpp"], 1391 system_shared_libs: [], 1392 stl: "none", 1393 apex_available: [ "myapex2" ], 1394 } 1395 1396 `) 1397 1398 apexRule := ctx.ModuleForTests("myapex2", "android_common_myapex2").Rule("apexRule") 1399 copyCmds := apexRule.Args["copy_commands"] 1400 1401 // Ensure that direct non-stubs dep is always included 1402 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") 1403 1404 // Ensure that indirect stubs dep is not included 1405 ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.so") 1406 1407 // Ensure that dependency of stubs is not included 1408 ensureNotContains(t, copyCmds, "image.apex/lib64/libbar.so") 1409 1410 mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"] 1411 1412 // Ensure that mylib is linking with version 10 of libfoo 1413 ensureContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_shared_10/libfoo.so") 1414 // ... and not linking to the non-stub (impl) variant of libfoo 1415 ensureNotContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_shared/libfoo.so") 1416 1417 libFooStubsLdFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared_10").Rule("ld").Args["libFlags"] 1418 1419 // Ensure that libfoo stubs is not linking to libbar (since it is a stubs) 1420 ensureNotContains(t, libFooStubsLdFlags, "libbar.so") 1421 1422 fullDepsInfo := strings.Split(android.ContentFromFileRuleForTests(t, ctx, 1423 ctx.ModuleForTests("myapex2", "android_common_myapex2").Output("depsinfo/fulllist.txt")), "\n") 1424 ensureListContains(t, fullDepsInfo, " libfoo(minSdkVersion:(no version)) (external) <- mylib") 1425 1426 flatDepsInfo := strings.Split(android.ContentFromFileRuleForTests(t, ctx, 1427 ctx.ModuleForTests("myapex2", "android_common_myapex2").Output("depsinfo/flatlist.txt")), "\n") 1428 ensureListContains(t, flatDepsInfo, "libfoo(minSdkVersion:(no version)) (external)") 1429} 1430 1431func TestApexWithRuntimeLibsDependency(t *testing.T) { 1432 t.Parallel() 1433 /* 1434 myapex 1435 | 1436 v (runtime_libs) 1437 mylib ------+------> libfoo [provides stub] 1438 | 1439 `------> libbar 1440 */ 1441 ctx := testApex(t, ` 1442 apex { 1443 name: "myapex", 1444 key: "myapex.key", 1445 native_shared_libs: ["mylib"], 1446 updatable: false, 1447 } 1448 1449 apex_key { 1450 name: "myapex.key", 1451 public_key: "testkey.avbpubkey", 1452 private_key: "testkey.pem", 1453 } 1454 1455 cc_library { 1456 name: "mylib", 1457 srcs: ["mylib.cpp"], 1458 static_libs: ["libstatic"], 1459 shared_libs: ["libshared"], 1460 runtime_libs: ["libfoo", "libbar"], 1461 system_shared_libs: [], 1462 stl: "none", 1463 apex_available: [ "myapex" ], 1464 } 1465 1466 cc_library { 1467 name: "libfoo", 1468 srcs: ["mylib.cpp"], 1469 system_shared_libs: [], 1470 stl: "none", 1471 stubs: { 1472 versions: ["10", "20", "30"], 1473 }, 1474 } 1475 1476 cc_library { 1477 name: "libbar", 1478 srcs: ["mylib.cpp"], 1479 system_shared_libs: [], 1480 stl: "none", 1481 apex_available: [ "myapex" ], 1482 } 1483 1484 cc_library { 1485 name: "libstatic", 1486 srcs: ["mylib.cpp"], 1487 system_shared_libs: [], 1488 stl: "none", 1489 apex_available: [ "myapex" ], 1490 runtime_libs: ["libstatic_to_runtime"], 1491 } 1492 1493 cc_library { 1494 name: "libshared", 1495 srcs: ["mylib.cpp"], 1496 system_shared_libs: [], 1497 stl: "none", 1498 apex_available: [ "myapex" ], 1499 runtime_libs: ["libshared_to_runtime"], 1500 } 1501 1502 cc_library { 1503 name: "libstatic_to_runtime", 1504 srcs: ["mylib.cpp"], 1505 system_shared_libs: [], 1506 stl: "none", 1507 apex_available: [ "myapex" ], 1508 } 1509 1510 cc_library { 1511 name: "libshared_to_runtime", 1512 srcs: ["mylib.cpp"], 1513 system_shared_libs: [], 1514 stl: "none", 1515 apex_available: [ "myapex" ], 1516 } 1517 `) 1518 1519 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule") 1520 copyCmds := apexRule.Args["copy_commands"] 1521 1522 // Ensure that direct non-stubs dep is always included 1523 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") 1524 1525 // Ensure that indirect stubs dep is not included 1526 ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.so") 1527 1528 // Ensure that runtime_libs dep in included 1529 ensureContains(t, copyCmds, "image.apex/lib64/libbar.so") 1530 ensureContains(t, copyCmds, "image.apex/lib64/libshared.so") 1531 ensureContains(t, copyCmds, "image.apex/lib64/libshared_to_runtime.so") 1532 1533 ensureNotContains(t, copyCmds, "image.apex/lib64/libstatic_to_runtime.so") 1534 1535 apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexManifestRule") 1536 ensureListEmpty(t, names(apexManifestRule.Args["provideNativeLibs"])) 1537 ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libfoo.so") 1538} 1539 1540var prepareForTestOfRuntimeApexWithHwasan = android.GroupFixturePreparers( 1541 cc.PrepareForTestWithCcBuildComponents, 1542 PrepareForTestWithApexBuildComponents, 1543 android.FixtureAddTextFile("bionic/apex/Android.bp", ` 1544 apex { 1545 name: "com.android.runtime", 1546 key: "com.android.runtime.key", 1547 native_shared_libs: ["libc"], 1548 updatable: false, 1549 } 1550 1551 apex_key { 1552 name: "com.android.runtime.key", 1553 public_key: "testkey.avbpubkey", 1554 private_key: "testkey.pem", 1555 } 1556 `), 1557 android.FixtureAddFile("system/sepolicy/apex/com.android.runtime-file_contexts", nil), 1558) 1559 1560func TestRuntimeApexShouldInstallHwasanIfLibcDependsOnIt(t *testing.T) { 1561 t.Parallel() 1562 result := android.GroupFixturePreparers(prepareForTestOfRuntimeApexWithHwasan).RunTestWithBp(t, ` 1563 cc_library { 1564 name: "libc", 1565 no_libcrt: true, 1566 nocrt: true, 1567 no_crt_pad_segment: true, 1568 stl: "none", 1569 system_shared_libs: [], 1570 stubs: { versions: ["1"] }, 1571 apex_available: ["com.android.runtime"], 1572 1573 sanitize: { 1574 hwaddress: true, 1575 } 1576 } 1577 1578 cc_prebuilt_library_shared { 1579 name: "libclang_rt.hwasan", 1580 no_libcrt: true, 1581 nocrt: true, 1582 no_crt_pad_segment: true, 1583 stl: "none", 1584 system_shared_libs: [], 1585 srcs: [""], 1586 stubs: { versions: ["1"] }, 1587 stem: "libclang_rt.hwasan-aarch64-android", 1588 1589 sanitize: { 1590 never: true, 1591 }, 1592 apex_available: [ 1593 "//apex_available:anyapex", 1594 "//apex_available:platform", 1595 ], 1596 } `) 1597 ctx := result.TestContext 1598 1599 ensureExactContents(t, ctx, "com.android.runtime", "android_common_hwasan_com.android.runtime", []string{ 1600 "lib64/bionic/libc.so", 1601 "lib64/bionic/libclang_rt.hwasan-aarch64-android.so", 1602 }) 1603 1604 hwasan := ctx.ModuleForTests("libclang_rt.hwasan", "android_arm64_armv8-a_shared") 1605 1606 installed := hwasan.Description("install libclang_rt.hwasan") 1607 ensureContains(t, installed.Output.String(), "/system/lib64/bootstrap/libclang_rt.hwasan-aarch64-android.so") 1608 1609 symlink := hwasan.Description("install symlink libclang_rt.hwasan") 1610 ensureEquals(t, symlink.Args["fromPath"], "/apex/com.android.runtime/lib64/bionic/libclang_rt.hwasan-aarch64-android.so") 1611 ensureContains(t, symlink.Output.String(), "/system/lib64/libclang_rt.hwasan-aarch64-android.so") 1612} 1613 1614func TestRuntimeApexShouldInstallHwasanIfHwaddressSanitized(t *testing.T) { 1615 t.Parallel() 1616 result := android.GroupFixturePreparers( 1617 prepareForTestOfRuntimeApexWithHwasan, 1618 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1619 variables.SanitizeDevice = []string{"hwaddress"} 1620 }), 1621 ).RunTestWithBp(t, ` 1622 cc_library { 1623 name: "libc", 1624 no_libcrt: true, 1625 nocrt: true, 1626 no_crt_pad_segment: true, 1627 stl: "none", 1628 system_shared_libs: [], 1629 stubs: { versions: ["1"] }, 1630 apex_available: ["com.android.runtime"], 1631 } 1632 1633 cc_prebuilt_library_shared { 1634 name: "libclang_rt.hwasan", 1635 no_libcrt: true, 1636 nocrt: true, 1637 no_crt_pad_segment: true, 1638 stl: "none", 1639 system_shared_libs: [], 1640 srcs: [""], 1641 stubs: { versions: ["1"] }, 1642 stem: "libclang_rt.hwasan-aarch64-android", 1643 1644 sanitize: { 1645 never: true, 1646 }, 1647 apex_available: [ 1648 "//apex_available:anyapex", 1649 "//apex_available:platform", 1650 ], 1651 } 1652 `) 1653 ctx := result.TestContext 1654 1655 ensureExactContents(t, ctx, "com.android.runtime", "android_common_hwasan_com.android.runtime", []string{ 1656 "lib64/bionic/libc.so", 1657 "lib64/bionic/libclang_rt.hwasan-aarch64-android.so", 1658 }) 1659 1660 hwasan := ctx.ModuleForTests("libclang_rt.hwasan", "android_arm64_armv8-a_shared") 1661 1662 installed := hwasan.Description("install libclang_rt.hwasan") 1663 ensureContains(t, installed.Output.String(), "/system/lib64/bootstrap/libclang_rt.hwasan-aarch64-android.so") 1664 1665 symlink := hwasan.Description("install symlink libclang_rt.hwasan") 1666 ensureEquals(t, symlink.Args["fromPath"], "/apex/com.android.runtime/lib64/bionic/libclang_rt.hwasan-aarch64-android.so") 1667 ensureContains(t, symlink.Output.String(), "/system/lib64/libclang_rt.hwasan-aarch64-android.so") 1668} 1669 1670func TestApexDependsOnLLNDKTransitively(t *testing.T) { 1671 t.Parallel() 1672 testcases := []struct { 1673 name string 1674 minSdkVersion string 1675 apexVariant string 1676 shouldLink string 1677 shouldNotLink []string 1678 }{ 1679 { 1680 name: "unspecified version links to the latest", 1681 minSdkVersion: "", 1682 apexVariant: "apex10000", 1683 shouldLink: "current", 1684 shouldNotLink: []string{"29", "30"}, 1685 }, 1686 { 1687 name: "always use the latest", 1688 minSdkVersion: "min_sdk_version: \"29\",", 1689 apexVariant: "apex29", 1690 shouldLink: "current", 1691 shouldNotLink: []string{"29", "30"}, 1692 }, 1693 } 1694 for _, tc := range testcases { 1695 t.Run(tc.name, func(t *testing.T) { 1696 t.Parallel() 1697 ctx := testApex(t, ` 1698 apex { 1699 name: "myapex", 1700 key: "myapex.key", 1701 native_shared_libs: ["mylib"], 1702 updatable: false, 1703 `+tc.minSdkVersion+` 1704 } 1705 1706 apex_key { 1707 name: "myapex.key", 1708 public_key: "testkey.avbpubkey", 1709 private_key: "testkey.pem", 1710 } 1711 1712 cc_library { 1713 name: "mylib", 1714 srcs: ["mylib.cpp"], 1715 vendor_available: true, 1716 shared_libs: ["libbar"], 1717 system_shared_libs: [], 1718 stl: "none", 1719 apex_available: [ "myapex" ], 1720 min_sdk_version: "29", 1721 } 1722 1723 cc_library { 1724 name: "libbar", 1725 srcs: ["mylib.cpp"], 1726 system_shared_libs: [], 1727 stl: "none", 1728 stubs: { versions: ["29","30"] }, 1729 llndk: { 1730 symbol_file: "libbar.map.txt", 1731 } 1732 } 1733 `, 1734 withUnbundledBuild, 1735 ) 1736 1737 // Ensure that LLNDK dep is not included 1738 ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{ 1739 "lib64/mylib.so", 1740 }) 1741 1742 // Ensure that LLNDK dep is required 1743 apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexManifestRule") 1744 ensureListEmpty(t, names(apexManifestRule.Args["provideNativeLibs"])) 1745 ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libbar.so") 1746 1747 mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_"+tc.apexVariant).Rule("ld").Args["libFlags"] 1748 ensureContains(t, mylibLdFlags, "libbar/android_arm64_armv8-a_shared_"+tc.shouldLink+"/libbar.so") 1749 for _, ver := range tc.shouldNotLink { 1750 ensureNotContains(t, mylibLdFlags, "libbar/android_arm64_armv8-a_shared_"+ver+"/libbar.so") 1751 } 1752 1753 mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_"+tc.apexVariant).Rule("cc").Args["cFlags"] 1754 ver := tc.shouldLink 1755 if tc.shouldLink == "current" { 1756 ver = strconv.Itoa(android.FutureApiLevelInt) 1757 } 1758 ensureContains(t, mylibCFlags, "__LIBBAR_API__="+ver) 1759 }) 1760 } 1761} 1762 1763func TestApexWithSystemLibsStubs(t *testing.T) { 1764 t.Parallel() 1765 ctx := testApex(t, ` 1766 apex { 1767 name: "myapex", 1768 key: "myapex.key", 1769 native_shared_libs: ["mylib", "mylib_shared", "libdl", "libm"], 1770 updatable: false, 1771 } 1772 1773 apex_key { 1774 name: "myapex.key", 1775 public_key: "testkey.avbpubkey", 1776 private_key: "testkey.pem", 1777 } 1778 1779 cc_library { 1780 name: "mylib", 1781 srcs: ["mylib.cpp"], 1782 system_shared_libs: ["libc"], 1783 shared_libs: ["libdl#27", "libm#impl"], 1784 stl: "none", 1785 apex_available: [ "myapex" ], 1786 } 1787 1788 cc_library_shared { 1789 name: "mylib_shared", 1790 srcs: ["mylib.cpp"], 1791 shared_libs: ["libdl#27"], 1792 stl: "none", 1793 apex_available: [ "myapex" ], 1794 } 1795 1796 cc_library { 1797 name: "libBootstrap", 1798 srcs: ["mylib.cpp"], 1799 stl: "none", 1800 bootstrap: true, 1801 } 1802 `) 1803 1804 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule") 1805 copyCmds := apexRule.Args["copy_commands"] 1806 1807 // Ensure that mylib, libm, libdl are included. 1808 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") 1809 ensureContains(t, copyCmds, "image.apex/lib64/bionic/libm.so") 1810 ensureContains(t, copyCmds, "image.apex/lib64/bionic/libdl.so") 1811 1812 // Ensure that libc is not included (since it has stubs and not listed in native_shared_libs) 1813 ensureNotContains(t, copyCmds, "image.apex/lib64/bionic/libc.so") 1814 1815 mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"] 1816 mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex10000").Rule("cc").Args["cFlags"] 1817 mylibSharedCFlags := ctx.ModuleForTests("mylib_shared", "android_arm64_armv8-a_shared_apex10000").Rule("cc").Args["cFlags"] 1818 1819 // For dependency to libc 1820 // Ensure that mylib is linking with the latest version of stubs 1821 ensureContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_shared_current/libc.so") 1822 // ... and not linking to the non-stub (impl) variant 1823 ensureNotContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_shared/libc.so") 1824 // ... Cflags from stub is correctly exported to mylib 1825 ensureContains(t, mylibCFlags, "__LIBC_API__=10000") 1826 ensureContains(t, mylibSharedCFlags, "__LIBC_API__=10000") 1827 1828 // For dependency to libm 1829 // Ensure that mylib is linking with the non-stub (impl) variant 1830 ensureContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_shared_apex10000/libm.so") 1831 // ... and not linking to the stub variant 1832 ensureNotContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_shared_29/libm.so") 1833 // ... and is not compiling with the stub 1834 ensureNotContains(t, mylibCFlags, "__LIBM_API__=29") 1835 ensureNotContains(t, mylibSharedCFlags, "__LIBM_API__=29") 1836 1837 // For dependency to libdl 1838 // Ensure that mylib is linking with the specified version of stubs 1839 ensureContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_27/libdl.so") 1840 // ... and not linking to the other versions of stubs 1841 ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_28/libdl.so") 1842 ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_29/libdl.so") 1843 // ... and not linking to the non-stub (impl) variant 1844 ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_apex10000/libdl.so") 1845 // ... Cflags from stub is correctly exported to mylib 1846 ensureContains(t, mylibCFlags, "__LIBDL_API__=27") 1847 ensureContains(t, mylibSharedCFlags, "__LIBDL_API__=27") 1848 1849 // Ensure that libBootstrap is depending on the platform variant of bionic libs 1850 libFlags := ctx.ModuleForTests("libBootstrap", "android_arm64_armv8-a_shared").Rule("ld").Args["libFlags"] 1851 ensureContains(t, libFlags, "libc/android_arm64_armv8-a_shared/libc.so") 1852 ensureContains(t, libFlags, "libm/android_arm64_armv8-a_shared/libm.so") 1853 ensureContains(t, libFlags, "libdl/android_arm64_armv8-a_shared/libdl.so") 1854} 1855 1856func TestApexMinSdkVersion_NativeModulesShouldBeBuiltAgainstStubs(t *testing.T) { 1857 t.Parallel() 1858 // there are three links between liba --> libz. 1859 // 1) myapex -> libx -> liba -> libz : this should be #30 link 1860 // 2) otherapex -> liby -> liba -> libz : this should be #30 link 1861 // 3) (platform) -> liba -> libz : this should be non-stub link 1862 ctx := testApex(t, ` 1863 apex { 1864 name: "myapex", 1865 key: "myapex.key", 1866 native_shared_libs: ["libx"], 1867 min_sdk_version: "29", 1868 } 1869 1870 apex { 1871 name: "otherapex", 1872 key: "myapex.key", 1873 native_shared_libs: ["liby"], 1874 min_sdk_version: "30", 1875 } 1876 1877 apex_key { 1878 name: "myapex.key", 1879 public_key: "testkey.avbpubkey", 1880 private_key: "testkey.pem", 1881 } 1882 1883 cc_library { 1884 name: "libx", 1885 shared_libs: ["liba"], 1886 system_shared_libs: [], 1887 stl: "none", 1888 apex_available: [ "myapex" ], 1889 min_sdk_version: "29", 1890 } 1891 1892 cc_library { 1893 name: "liby", 1894 shared_libs: ["liba"], 1895 system_shared_libs: [], 1896 stl: "none", 1897 apex_available: [ "otherapex" ], 1898 min_sdk_version: "29", 1899 } 1900 1901 cc_library { 1902 name: "liba", 1903 shared_libs: ["libz"], 1904 system_shared_libs: [], 1905 stl: "none", 1906 apex_available: [ 1907 "//apex_available:anyapex", 1908 "//apex_available:platform", 1909 ], 1910 min_sdk_version: "29", 1911 } 1912 1913 cc_library { 1914 name: "libz", 1915 system_shared_libs: [], 1916 stl: "none", 1917 stubs: { 1918 versions: ["28", "30"], 1919 }, 1920 } 1921 `) 1922 1923 expectLink := func(from, from_variant, to, to_variant string) { 1924 ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"] 1925 ensureContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so") 1926 } 1927 expectNoLink := func(from, from_variant, to, to_variant string) { 1928 ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"] 1929 ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so") 1930 } 1931 // platform liba is linked to non-stub version 1932 expectLink("liba", "shared", "libz", "shared") 1933 // liba in myapex is linked to current 1934 expectLink("liba", "shared_apex29", "libz", "shared_current") 1935 expectNoLink("liba", "shared_apex29", "libz", "shared_30") 1936 expectNoLink("liba", "shared_apex29", "libz", "shared_28") 1937 expectNoLink("liba", "shared_apex29", "libz", "shared") 1938 // liba in otherapex is linked to current 1939 expectLink("liba", "shared_apex30", "libz", "shared_current") 1940 expectNoLink("liba", "shared_apex30", "libz", "shared_30") 1941 expectNoLink("liba", "shared_apex30", "libz", "shared_28") 1942 expectNoLink("liba", "shared_apex30", "libz", "shared") 1943} 1944 1945func TestApexMinSdkVersion_SupportsCodeNames(t *testing.T) { 1946 t.Parallel() 1947 ctx := testApex(t, ` 1948 apex { 1949 name: "myapex", 1950 key: "myapex.key", 1951 native_shared_libs: ["libx"], 1952 min_sdk_version: "R", 1953 } 1954 1955 apex_key { 1956 name: "myapex.key", 1957 public_key: "testkey.avbpubkey", 1958 private_key: "testkey.pem", 1959 } 1960 1961 cc_library { 1962 name: "libx", 1963 shared_libs: ["libz"], 1964 system_shared_libs: [], 1965 stl: "none", 1966 apex_available: [ "myapex" ], 1967 min_sdk_version: "R", 1968 } 1969 1970 cc_library { 1971 name: "libz", 1972 system_shared_libs: [], 1973 stl: "none", 1974 stubs: { 1975 versions: ["29", "R"], 1976 }, 1977 } 1978 `, 1979 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1980 variables.Platform_version_active_codenames = []string{"R"} 1981 }), 1982 ) 1983 1984 expectLink := func(from, from_variant, to, to_variant string) { 1985 ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"] 1986 ensureContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so") 1987 } 1988 expectNoLink := func(from, from_variant, to, to_variant string) { 1989 ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"] 1990 ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so") 1991 } 1992 expectLink("libx", "shared_apex10000", "libz", "shared_current") 1993 expectNoLink("libx", "shared_apex10000", "libz", "shared_R") 1994 expectNoLink("libx", "shared_apex10000", "libz", "shared_29") 1995 expectNoLink("libx", "shared_apex10000", "libz", "shared") 1996} 1997 1998func TestApexMinSdkVersion_SupportsCodeNames_JavaLibs(t *testing.T) { 1999 t.Parallel() 2000 testApex(t, ` 2001 apex { 2002 name: "myapex", 2003 key: "myapex.key", 2004 java_libs: ["libx"], 2005 min_sdk_version: "S", 2006 } 2007 2008 apex_key { 2009 name: "myapex.key", 2010 public_key: "testkey.avbpubkey", 2011 private_key: "testkey.pem", 2012 } 2013 2014 java_library { 2015 name: "libx", 2016 srcs: ["a.java"], 2017 apex_available: [ "myapex" ], 2018 sdk_version: "current", 2019 min_sdk_version: "S", // should be okay 2020 compile_dex: true, 2021 } 2022 `, 2023 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 2024 variables.Platform_version_active_codenames = []string{"S"} 2025 variables.Platform_sdk_codename = proptools.StringPtr("S") 2026 }), 2027 ) 2028} 2029 2030func TestApexMinSdkVersion_DefaultsToLatest(t *testing.T) { 2031 t.Parallel() 2032 ctx := testApex(t, ` 2033 apex { 2034 name: "myapex", 2035 key: "myapex.key", 2036 native_shared_libs: ["libx"], 2037 updatable: false, 2038 } 2039 2040 apex_key { 2041 name: "myapex.key", 2042 public_key: "testkey.avbpubkey", 2043 private_key: "testkey.pem", 2044 } 2045 2046 cc_library { 2047 name: "libx", 2048 shared_libs: ["libz"], 2049 system_shared_libs: [], 2050 stl: "none", 2051 apex_available: [ "myapex" ], 2052 } 2053 2054 cc_library { 2055 name: "libz", 2056 system_shared_libs: [], 2057 stl: "none", 2058 stubs: { 2059 versions: ["1", "2"], 2060 }, 2061 } 2062 `) 2063 2064 expectLink := func(from, from_variant, to, to_variant string) { 2065 ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"] 2066 ensureContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so") 2067 } 2068 expectNoLink := func(from, from_variant, to, to_variant string) { 2069 ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"] 2070 ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so") 2071 } 2072 expectLink("libx", "shared_apex10000", "libz", "shared_current") 2073 expectNoLink("libx", "shared_apex10000", "libz", "shared_1") 2074 expectNoLink("libx", "shared_apex10000", "libz", "shared_2") 2075 expectNoLink("libx", "shared_apex10000", "libz", "shared") 2076} 2077 2078func TestApexMinSdkVersion_InVendorApex(t *testing.T) { 2079 t.Parallel() 2080 ctx := testApex(t, ` 2081 apex { 2082 name: "myapex", 2083 key: "myapex.key", 2084 native_shared_libs: ["mylib"], 2085 updatable: true, 2086 vendor: true, 2087 min_sdk_version: "29", 2088 } 2089 2090 apex_key { 2091 name: "myapex.key", 2092 public_key: "testkey.avbpubkey", 2093 private_key: "testkey.pem", 2094 } 2095 2096 cc_library { 2097 name: "mylib", 2098 srcs: ["mylib.cpp"], 2099 vendor_available: true, 2100 min_sdk_version: "29", 2101 shared_libs: ["libbar"], 2102 } 2103 2104 cc_library { 2105 name: "libbar", 2106 stubs: { versions: ["29", "30"] }, 2107 llndk: { symbol_file: "libbar.map.txt" }, 2108 } 2109 `) 2110 2111 vendorVariant := "android_vendor_arm64_armv8-a" 2112 2113 mylib := ctx.ModuleForTests("mylib", vendorVariant+"_shared_apex29") 2114 2115 // Ensure that mylib links with "current" LLNDK 2116 libFlags := names(mylib.Rule("ld").Args["libFlags"]) 2117 ensureListContains(t, libFlags, "out/soong/.intermediates/libbar/"+vendorVariant+"_shared/libbar.so") 2118 2119 // Ensure that mylib is targeting 29 2120 ccRule := ctx.ModuleForTests("mylib", vendorVariant+"_static_apex29").Output("obj/mylib.o") 2121 ensureContains(t, ccRule.Args["cFlags"], "-target aarch64-linux-android29") 2122 2123 // Ensure that the correct variant of crtbegin_so is used. 2124 crtBegin := mylib.Rule("ld").Args["crtBegin"] 2125 ensureContains(t, crtBegin, "out/soong/.intermediates/"+cc.DefaultCcCommonTestModulesDir+"crtbegin_so/"+vendorVariant+"_apex29/crtbegin_so.o") 2126 2127 // Ensure that the crtbegin_so used by the APEX is targeting 29 2128 cflags := ctx.ModuleForTests("crtbegin_so", vendorVariant+"_apex29").Rule("cc").Args["cFlags"] 2129 android.AssertStringDoesContain(t, "cflags", cflags, "-target aarch64-linux-android29") 2130} 2131 2132func TestTrackAllowedDeps(t *testing.T) { 2133 t.Parallel() 2134 ctx := testApex(t, ` 2135 apex { 2136 name: "myapex", 2137 key: "myapex.key", 2138 updatable: true, 2139 native_shared_libs: [ 2140 "mylib", 2141 "yourlib", 2142 ], 2143 min_sdk_version: "29", 2144 } 2145 2146 apex { 2147 name: "myapex2", 2148 key: "myapex.key", 2149 updatable: false, 2150 native_shared_libs: ["yourlib"], 2151 } 2152 2153 apex_key { 2154 name: "myapex.key", 2155 public_key: "testkey.avbpubkey", 2156 private_key: "testkey.pem", 2157 } 2158 2159 cc_library { 2160 name: "mylib", 2161 srcs: ["mylib.cpp"], 2162 shared_libs: ["libbar"], 2163 min_sdk_version: "29", 2164 apex_available: ["myapex"], 2165 } 2166 2167 cc_library { 2168 name: "libbar", 2169 stubs: { versions: ["29", "30"] }, 2170 } 2171 2172 cc_library { 2173 name: "yourlib", 2174 srcs: ["mylib.cpp"], 2175 min_sdk_version: "29", 2176 apex_available: ["myapex", "myapex2", "//apex_available:platform"], 2177 } 2178 `, withFiles(android.MockFS{ 2179 "packages/modules/common/build/allowed_deps.txt": nil, 2180 })) 2181 2182 depsinfo := ctx.SingletonForTests("apex_depsinfo_singleton") 2183 inputs := depsinfo.Rule("generateApexDepsInfoFilesRule").BuildParams.Inputs.Strings() 2184 android.AssertStringListContains(t, "updatable myapex should generate depsinfo file", inputs, 2185 "out/soong/.intermediates/myapex/android_common_myapex/depsinfo/flatlist.txt") 2186 android.AssertStringListDoesNotContain(t, "non-updatable myapex2 should not generate depsinfo file", inputs, 2187 "out/soong/.intermediates/myapex2/android_common_myapex2/depsinfo/flatlist.txt") 2188 2189 myapex := ctx.ModuleForTests("myapex", "android_common_myapex") 2190 flatlist := strings.Split(android.ContentFromFileRuleForTests(t, ctx, 2191 myapex.Output("depsinfo/flatlist.txt")), "\n") 2192 android.AssertStringListContains(t, "deps with stubs should be tracked in depsinfo as external dep", 2193 flatlist, "libbar(minSdkVersion:(no version)) (external)") 2194 android.AssertStringListDoesNotContain(t, "do not track if not available for platform", 2195 flatlist, "mylib:(minSdkVersion:29)") 2196 android.AssertStringListContains(t, "track platform-available lib", 2197 flatlist, "yourlib(minSdkVersion:29)") 2198} 2199 2200func TestTrackCustomAllowedDepsInvalidDefaultTxt(t *testing.T) { 2201 t.Parallel() 2202 ctx := testApex(t, ` 2203 apex { 2204 name: "myapex", 2205 key: "myapex.key", 2206 updatable: true, 2207 native_shared_libs: [ 2208 "mylib", 2209 "yourlib", 2210 ], 2211 min_sdk_version: "29", 2212 } 2213 2214 apex { 2215 name: "myapex2", 2216 key: "myapex.key", 2217 updatable: false, 2218 native_shared_libs: ["yourlib"], 2219 } 2220 2221 apex_key { 2222 name: "myapex.key", 2223 public_key: "testkey.avbpubkey", 2224 private_key: "testkey.pem", 2225 } 2226 2227 cc_library { 2228 name: "mylib", 2229 srcs: ["mylib.cpp"], 2230 shared_libs: ["libbar"], 2231 min_sdk_version: "29", 2232 apex_available: ["myapex"], 2233 } 2234 2235 cc_library { 2236 name: "libbar", 2237 stubs: { versions: ["29", "30"] }, 2238 } 2239 2240 cc_library { 2241 name: "yourlib", 2242 srcs: ["mylib.cpp"], 2243 min_sdk_version: "29", 2244 apex_available: ["myapex", "myapex2", "//apex_available:platform"], 2245 } 2246 `, withFiles(android.MockFS{ 2247 "packages/modules/common/build/custom_allowed_deps.txt": nil, 2248 }), 2249 android.FixtureModifyProductVariables( 2250 func(variables android.FixtureProductVariables) { 2251 variables.ExtraAllowedDepsTxt = proptools.StringPtr("packages/modules/common/build/custom_allowed_deps.txt") 2252 }, 2253 )) 2254 2255 depsinfo := ctx.SingletonForTests("apex_depsinfo_singleton") 2256 inputs := depsinfo.Rule("generateApexDepsInfoFilesRule").BuildParams.Inputs.Strings() 2257 android.AssertStringListContains(t, "updatable myapex should generate depsinfo file", inputs, 2258 "out/soong/.intermediates/myapex/android_common_myapex/depsinfo/flatlist.txt") 2259 android.AssertStringListDoesNotContain(t, "non-updatable myapex2 should not generate depsinfo file", inputs, 2260 "out/soong/.intermediates/myapex2/android_common_myapex2/depsinfo/flatlist.txt") 2261 2262 myapex := ctx.ModuleForTests("myapex", "android_common_myapex") 2263 flatlist := strings.Split(android.ContentFromFileRuleForTests(t, ctx, 2264 myapex.Output("depsinfo/flatlist.txt")), "\n") 2265 android.AssertStringListContains(t, "deps with stubs should be tracked in depsinfo as external dep", 2266 flatlist, "libbar(minSdkVersion:(no version)) (external)") 2267 android.AssertStringListDoesNotContain(t, "do not track if not available for platform", 2268 flatlist, "mylib:(minSdkVersion:29)") 2269 android.AssertStringListContains(t, "track platform-available lib", 2270 flatlist, "yourlib(minSdkVersion:29)") 2271} 2272 2273func TestTrackCustomAllowedDepsWithDefaultTxt(t *testing.T) { 2274 t.Parallel() 2275 ctx := testApex(t, ` 2276 apex { 2277 name: "myapex", 2278 key: "myapex.key", 2279 updatable: true, 2280 native_shared_libs: [ 2281 "mylib", 2282 "yourlib", 2283 ], 2284 min_sdk_version: "29", 2285 } 2286 2287 apex { 2288 name: "myapex2", 2289 key: "myapex.key", 2290 updatable: false, 2291 native_shared_libs: ["yourlib"], 2292 } 2293 2294 apex_key { 2295 name: "myapex.key", 2296 public_key: "testkey.avbpubkey", 2297 private_key: "testkey.pem", 2298 } 2299 2300 cc_library { 2301 name: "mylib", 2302 srcs: ["mylib.cpp"], 2303 shared_libs: ["libbar"], 2304 min_sdk_version: "29", 2305 apex_available: ["myapex"], 2306 } 2307 2308 cc_library { 2309 name: "libbar", 2310 stubs: { versions: ["29", "30"] }, 2311 } 2312 2313 cc_library { 2314 name: "yourlib", 2315 srcs: ["mylib.cpp"], 2316 min_sdk_version: "29", 2317 apex_available: ["myapex", "myapex2", "//apex_available:platform"], 2318 } 2319 `, withFiles(android.MockFS{ 2320 "packages/modules/common/build/custom_allowed_deps.txt": nil, 2321 "packages/modules/common/build/allowed_deps.txt": nil, 2322 }), 2323 android.FixtureModifyProductVariables( 2324 func(variables android.FixtureProductVariables) { 2325 variables.ExtraAllowedDepsTxt = proptools.StringPtr("packages/modules/common/build/custom_allowed_deps.txt") 2326 }, 2327 )) 2328 2329 depsinfo := ctx.SingletonForTests("apex_depsinfo_singleton") 2330 inputs := depsinfo.Rule("generateApexDepsInfoFilesRule").BuildParams.Inputs.Strings() 2331 android.AssertStringListContains(t, "updatable myapex should generate depsinfo file", inputs, 2332 "out/soong/.intermediates/myapex/android_common_myapex/depsinfo/flatlist.txt") 2333 android.AssertStringListDoesNotContain(t, "non-updatable myapex2 should not generate depsinfo file", inputs, 2334 "out/soong/.intermediates/myapex2/android_common_myapex2/depsinfo/flatlist.txt") 2335 2336 myapex := ctx.ModuleForTests("myapex", "android_common_myapex") 2337 flatlist := strings.Split(android.ContentFromFileRuleForTests(t, ctx, 2338 myapex.Output("depsinfo/flatlist.txt")), "\n") 2339 android.AssertStringListContains(t, "deps with stubs should be tracked in depsinfo as external dep", 2340 flatlist, "libbar(minSdkVersion:(no version)) (external)") 2341 android.AssertStringListDoesNotContain(t, "do not track if not available for platform", 2342 flatlist, "mylib:(minSdkVersion:29)") 2343 android.AssertStringListContains(t, "track platform-available lib", 2344 flatlist, "yourlib(minSdkVersion:29)") 2345} 2346 2347func TestTrackAllowedDeps_SkipWithoutAllowedDepsTxt(t *testing.T) { 2348 t.Parallel() 2349 ctx := testApex(t, ` 2350 apex { 2351 name: "myapex", 2352 key: "myapex.key", 2353 updatable: true, 2354 min_sdk_version: "29", 2355 } 2356 2357 apex_key { 2358 name: "myapex.key", 2359 public_key: "testkey.avbpubkey", 2360 private_key: "testkey.pem", 2361 } 2362 `) 2363 depsinfo := ctx.SingletonForTests("apex_depsinfo_singleton") 2364 if nil != depsinfo.MaybeRule("generateApexDepsInfoFilesRule").Output { 2365 t.Error("apex_depsinfo_singleton shouldn't run when allowed_deps.txt doesn't exist") 2366 } 2367} 2368 2369func TestPlatformUsesLatestStubsFromApexes(t *testing.T) { 2370 t.Parallel() 2371 ctx := testApex(t, ` 2372 apex { 2373 name: "myapex", 2374 key: "myapex.key", 2375 native_shared_libs: ["libx"], 2376 updatable: false, 2377 } 2378 2379 apex_key { 2380 name: "myapex.key", 2381 public_key: "testkey.avbpubkey", 2382 private_key: "testkey.pem", 2383 } 2384 2385 cc_library { 2386 name: "libx", 2387 system_shared_libs: [], 2388 stl: "none", 2389 apex_available: [ "myapex" ], 2390 stubs: { 2391 versions: ["1", "2"], 2392 }, 2393 } 2394 2395 cc_library { 2396 name: "libz", 2397 shared_libs: ["libx"], 2398 system_shared_libs: [], 2399 stl: "none", 2400 } 2401 `) 2402 2403 expectLink := func(from, from_variant, to, to_variant string) { 2404 t.Helper() 2405 ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"] 2406 ensureContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so") 2407 } 2408 expectNoLink := func(from, from_variant, to, to_variant string) { 2409 t.Helper() 2410 ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"] 2411 ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so") 2412 } 2413 expectLink("libz", "shared", "libx", "shared_current") 2414 expectNoLink("libz", "shared", "libx", "shared_2") 2415 expectNoLink("libz", "shared", "libz", "shared_1") 2416 expectNoLink("libz", "shared", "libz", "shared") 2417} 2418 2419var prepareForTestWithSantitizeHwaddress = android.FixtureModifyProductVariables( 2420 func(variables android.FixtureProductVariables) { 2421 variables.SanitizeDevice = []string{"hwaddress"} 2422 }, 2423) 2424 2425func TestQApexesUseLatestStubsInBundledBuildsAndHWASAN(t *testing.T) { 2426 t.Parallel() 2427 ctx := testApex(t, ` 2428 apex { 2429 name: "myapex", 2430 key: "myapex.key", 2431 native_shared_libs: ["libx"], 2432 min_sdk_version: "29", 2433 } 2434 2435 apex_key { 2436 name: "myapex.key", 2437 public_key: "testkey.avbpubkey", 2438 private_key: "testkey.pem", 2439 } 2440 2441 cc_library { 2442 name: "libx", 2443 shared_libs: ["libbar"], 2444 apex_available: [ "myapex" ], 2445 min_sdk_version: "29", 2446 } 2447 2448 cc_library { 2449 name: "libbar", 2450 stubs: { 2451 versions: ["29", "30"], 2452 }, 2453 } 2454 `, 2455 prepareForTestWithSantitizeHwaddress, 2456 ) 2457 expectLink := func(from, from_variant, to, to_variant string) { 2458 ld := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld") 2459 libFlags := ld.Args["libFlags"] 2460 ensureContains(t, libFlags, "android_arm64_armv8-a_"+to_variant+"/"+to+".so") 2461 } 2462 expectLink("libx", "shared_hwasan_apex29", "libbar", "shared_current") 2463} 2464 2465func TestQTargetApexUsesStaticUnwinder(t *testing.T) { 2466 t.Parallel() 2467 ctx := testApex(t, ` 2468 apex { 2469 name: "myapex", 2470 key: "myapex.key", 2471 native_shared_libs: ["libx"], 2472 min_sdk_version: "29", 2473 } 2474 2475 apex_key { 2476 name: "myapex.key", 2477 public_key: "testkey.avbpubkey", 2478 private_key: "testkey.pem", 2479 } 2480 2481 cc_library { 2482 name: "libx", 2483 apex_available: [ "myapex" ], 2484 min_sdk_version: "29", 2485 } 2486 `) 2487 2488 // ensure apex variant of c++ is linked with static unwinder 2489 cm := ctx.ModuleForTests("libc++", "android_arm64_armv8-a_shared_apex29").Module().(*cc.Module) 2490 ensureListContains(t, cm.Properties.AndroidMkStaticLibs, "libunwind") 2491 // note that platform variant is not. 2492 cm = ctx.ModuleForTests("libc++", "android_arm64_armv8-a_shared").Module().(*cc.Module) 2493 ensureListNotContains(t, cm.Properties.AndroidMkStaticLibs, "libunwind") 2494} 2495 2496func TestApexMinSdkVersion_ErrorIfIncompatibleVersion(t *testing.T) { 2497 t.Parallel() 2498 testApexError(t, `module "mylib".*: should support min_sdk_version\(29\)`, ` 2499 apex { 2500 name: "myapex", 2501 key: "myapex.key", 2502 native_shared_libs: ["mylib"], 2503 min_sdk_version: "29", 2504 } 2505 2506 apex_key { 2507 name: "myapex.key", 2508 public_key: "testkey.avbpubkey", 2509 private_key: "testkey.pem", 2510 } 2511 2512 cc_library { 2513 name: "mylib", 2514 srcs: ["mylib.cpp"], 2515 system_shared_libs: [], 2516 stl: "none", 2517 apex_available: [ 2518 "myapex", 2519 ], 2520 min_sdk_version: "30", 2521 } 2522 `) 2523 2524 testApexError(t, `module "libfoo.ffi".*: should support min_sdk_version\(29\)`, ` 2525 apex { 2526 name: "myapex", 2527 key: "myapex.key", 2528 native_shared_libs: ["libfoo.ffi"], 2529 min_sdk_version: "29", 2530 } 2531 2532 apex_key { 2533 name: "myapex.key", 2534 public_key: "testkey.avbpubkey", 2535 private_key: "testkey.pem", 2536 } 2537 2538 rust_ffi_shared { 2539 name: "libfoo.ffi", 2540 srcs: ["foo.rs"], 2541 crate_name: "foo", 2542 apex_available: [ 2543 "myapex", 2544 ], 2545 min_sdk_version: "30", 2546 } 2547 `) 2548 2549 testApexError(t, `module "libfoo".*: should support min_sdk_version\(29\)`, ` 2550 apex { 2551 name: "myapex", 2552 key: "myapex.key", 2553 java_libs: ["libfoo"], 2554 min_sdk_version: "29", 2555 } 2556 2557 apex_key { 2558 name: "myapex.key", 2559 public_key: "testkey.avbpubkey", 2560 private_key: "testkey.pem", 2561 } 2562 2563 java_import { 2564 name: "libfoo", 2565 jars: ["libfoo.jar"], 2566 apex_available: [ 2567 "myapex", 2568 ], 2569 min_sdk_version: "30", 2570 compile_dex: true, 2571 } 2572 `) 2573 2574 // Skip check for modules compiling against core API surface 2575 testApex(t, ` 2576 apex { 2577 name: "myapex", 2578 key: "myapex.key", 2579 java_libs: ["libfoo"], 2580 min_sdk_version: "29", 2581 } 2582 2583 apex_key { 2584 name: "myapex.key", 2585 public_key: "testkey.avbpubkey", 2586 private_key: "testkey.pem", 2587 } 2588 2589 java_library { 2590 name: "libfoo", 2591 srcs: ["Foo.java"], 2592 apex_available: [ 2593 "myapex", 2594 ], 2595 // Compile against core API surface 2596 sdk_version: "core_current", 2597 min_sdk_version: "30", 2598 compile_dex: true, 2599 } 2600 `) 2601 2602} 2603 2604func TestApexMinSdkVersion_Okay(t *testing.T) { 2605 t.Parallel() 2606 testApex(t, ` 2607 apex { 2608 name: "myapex", 2609 key: "myapex.key", 2610 native_shared_libs: ["libfoo"], 2611 java_libs: ["libbar"], 2612 min_sdk_version: "29", 2613 } 2614 2615 apex_key { 2616 name: "myapex.key", 2617 public_key: "testkey.avbpubkey", 2618 private_key: "testkey.pem", 2619 } 2620 2621 cc_library { 2622 name: "libfoo", 2623 srcs: ["mylib.cpp"], 2624 shared_libs: ["libfoo_dep"], 2625 apex_available: ["myapex"], 2626 min_sdk_version: "29", 2627 } 2628 2629 cc_library { 2630 name: "libfoo_dep", 2631 srcs: ["mylib.cpp"], 2632 apex_available: ["myapex"], 2633 min_sdk_version: "29", 2634 } 2635 2636 java_library { 2637 name: "libbar", 2638 sdk_version: "current", 2639 srcs: ["a.java"], 2640 static_libs: [ 2641 "libbar_dep", 2642 "libbar_import_dep", 2643 ], 2644 apex_available: ["myapex"], 2645 min_sdk_version: "29", 2646 compile_dex: true, 2647 } 2648 2649 java_library { 2650 name: "libbar_dep", 2651 sdk_version: "current", 2652 srcs: ["a.java"], 2653 apex_available: ["myapex"], 2654 min_sdk_version: "29", 2655 } 2656 2657 java_import { 2658 name: "libbar_import_dep", 2659 jars: ["libbar.jar"], 2660 apex_available: ["myapex"], 2661 min_sdk_version: "29", 2662 } 2663 `) 2664} 2665 2666func TestApexMinSdkVersion_MinApiForArch(t *testing.T) { 2667 t.Parallel() 2668 // Tests that an apex dependency with min_sdk_version higher than the 2669 // min_sdk_version of the apex is allowed as long as the dependency's 2670 // min_sdk_version is less than or equal to the api level that the 2671 // architecture was introduced in. In this case, arm64 didn't exist 2672 // until api level 21, so the arm64 code will never need to run on 2673 // an api level 20 device, even if other architectures of the apex 2674 // will. 2675 testApex(t, ` 2676 apex { 2677 name: "myapex", 2678 key: "myapex.key", 2679 native_shared_libs: ["libfoo"], 2680 min_sdk_version: "20", 2681 } 2682 2683 apex_key { 2684 name: "myapex.key", 2685 public_key: "testkey.avbpubkey", 2686 private_key: "testkey.pem", 2687 } 2688 2689 cc_library { 2690 name: "libfoo", 2691 srcs: ["mylib.cpp"], 2692 apex_available: ["myapex"], 2693 min_sdk_version: "21", 2694 stl: "none", 2695 } 2696 `) 2697} 2698 2699func TestJavaStableSdkVersion(t *testing.T) { 2700 t.Parallel() 2701 testCases := []struct { 2702 name string 2703 expectedError string 2704 bp string 2705 preparer android.FixturePreparer 2706 }{ 2707 { 2708 name: "Non-updatable apex with non-stable dep", 2709 bp: ` 2710 apex { 2711 name: "myapex", 2712 java_libs: ["myjar"], 2713 key: "myapex.key", 2714 updatable: false, 2715 } 2716 apex_key { 2717 name: "myapex.key", 2718 public_key: "testkey.avbpubkey", 2719 private_key: "testkey.pem", 2720 } 2721 java_library { 2722 name: "myjar", 2723 srcs: ["foo/bar/MyClass.java"], 2724 sdk_version: "test_current", 2725 apex_available: ["myapex"], 2726 compile_dex: true, 2727 } 2728 `, 2729 }, 2730 { 2731 name: "Updatable apex with stable dep", 2732 bp: ` 2733 apex { 2734 name: "myapex", 2735 java_libs: ["myjar"], 2736 key: "myapex.key", 2737 updatable: true, 2738 min_sdk_version: "29", 2739 } 2740 apex_key { 2741 name: "myapex.key", 2742 public_key: "testkey.avbpubkey", 2743 private_key: "testkey.pem", 2744 } 2745 java_library { 2746 name: "myjar", 2747 srcs: ["foo/bar/MyClass.java"], 2748 sdk_version: "current", 2749 apex_available: ["myapex"], 2750 min_sdk_version: "29", 2751 compile_dex: true, 2752 } 2753 `, 2754 }, 2755 { 2756 name: "Updatable apex with non-stable dep", 2757 expectedError: "cannot depend on \"myjar\"", 2758 bp: ` 2759 apex { 2760 name: "myapex", 2761 java_libs: ["myjar"], 2762 key: "myapex.key", 2763 updatable: true, 2764 } 2765 apex_key { 2766 name: "myapex.key", 2767 public_key: "testkey.avbpubkey", 2768 private_key: "testkey.pem", 2769 } 2770 java_library { 2771 name: "myjar", 2772 srcs: ["foo/bar/MyClass.java"], 2773 sdk_version: "test_current", 2774 apex_available: ["myapex"], 2775 compile_dex: true, 2776 } 2777 `, 2778 }, 2779 { 2780 name: "Updatable apex with non-stable legacy core platform dep", 2781 expectedError: `\Qcannot depend on "myjar-uses-legacy": non stable SDK core_platform_current - uses legacy core platform\E`, 2782 bp: ` 2783 apex { 2784 name: "myapex", 2785 java_libs: ["myjar-uses-legacy"], 2786 key: "myapex.key", 2787 updatable: true, 2788 } 2789 apex_key { 2790 name: "myapex.key", 2791 public_key: "testkey.avbpubkey", 2792 private_key: "testkey.pem", 2793 } 2794 java_library { 2795 name: "myjar-uses-legacy", 2796 srcs: ["foo/bar/MyClass.java"], 2797 sdk_version: "core_platform", 2798 apex_available: ["myapex"], 2799 compile_dex: true, 2800 } 2801 `, 2802 preparer: java.FixtureUseLegacyCorePlatformApi("myjar-uses-legacy"), 2803 }, 2804 { 2805 name: "Updatable apex with non-stable transitive dep", 2806 // This is not actually detecting that the transitive dependency is unstable, rather it is 2807 // detecting that the transitive dependency is building against a wider API surface than the 2808 // module that depends on it is using. 2809 expectedError: "compiles against Android API, but dependency \"transitive-jar\" is compiling against private API.", 2810 bp: ` 2811 apex { 2812 name: "myapex", 2813 java_libs: ["myjar"], 2814 key: "myapex.key", 2815 updatable: true, 2816 } 2817 apex_key { 2818 name: "myapex.key", 2819 public_key: "testkey.avbpubkey", 2820 private_key: "testkey.pem", 2821 } 2822 java_library { 2823 name: "myjar", 2824 srcs: ["foo/bar/MyClass.java"], 2825 sdk_version: "current", 2826 apex_available: ["myapex"], 2827 static_libs: ["transitive-jar"], 2828 compile_dex: true, 2829 } 2830 java_library { 2831 name: "transitive-jar", 2832 srcs: ["foo/bar/MyClass.java"], 2833 sdk_version: "core_platform", 2834 apex_available: ["myapex"], 2835 } 2836 `, 2837 }, 2838 } 2839 2840 for _, test := range testCases { 2841 if test.name != "Updatable apex with non-stable legacy core platform dep" { 2842 continue 2843 } 2844 t.Run(test.name, func(t *testing.T) { 2845 t.Parallel() 2846 errorHandler := android.FixtureExpectsNoErrors 2847 if test.expectedError != "" { 2848 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(test.expectedError) 2849 } 2850 android.GroupFixturePreparers( 2851 java.PrepareForTestWithJavaDefaultModules, 2852 PrepareForTestWithApexBuildComponents, 2853 prepareForTestWithMyapex, 2854 android.OptionalFixturePreparer(test.preparer), 2855 ). 2856 ExtendWithErrorHandler(errorHandler). 2857 RunTestWithBp(t, test.bp) 2858 }) 2859 } 2860} 2861 2862func TestApexMinSdkVersion_ErrorIfDepIsNewer(t *testing.T) { 2863 testApexError(t, `module "mylib2".*: should support min_sdk_version\(29\) for "myapex"`, ` 2864 apex { 2865 name: "myapex", 2866 key: "myapex.key", 2867 native_shared_libs: ["mylib"], 2868 min_sdk_version: "29", 2869 } 2870 2871 apex_key { 2872 name: "myapex.key", 2873 public_key: "testkey.avbpubkey", 2874 private_key: "testkey.pem", 2875 } 2876 2877 cc_library { 2878 name: "mylib", 2879 srcs: ["mylib.cpp"], 2880 shared_libs: ["mylib2"], 2881 system_shared_libs: [], 2882 stl: "none", 2883 apex_available: [ 2884 "myapex", 2885 ], 2886 min_sdk_version: "29", 2887 } 2888 2889 // indirect part of the apex 2890 cc_library { 2891 name: "mylib2", 2892 srcs: ["mylib.cpp"], 2893 system_shared_libs: [], 2894 stl: "none", 2895 apex_available: [ 2896 "myapex", 2897 ], 2898 min_sdk_version: "30", 2899 } 2900 `) 2901} 2902 2903func TestApexMinSdkVersion_ErrorIfDepIsNewer_Java(t *testing.T) { 2904 t.Parallel() 2905 testApexError(t, `module "bar".*: should support min_sdk_version\(29\) for "myapex"`, ` 2906 apex { 2907 name: "myapex", 2908 key: "myapex.key", 2909 apps: ["AppFoo"], 2910 min_sdk_version: "29", 2911 updatable: false, 2912 } 2913 2914 apex_key { 2915 name: "myapex.key", 2916 public_key: "testkey.avbpubkey", 2917 private_key: "testkey.pem", 2918 } 2919 2920 android_app { 2921 name: "AppFoo", 2922 srcs: ["foo/bar/MyClass.java"], 2923 sdk_version: "current", 2924 min_sdk_version: "29", 2925 system_modules: "none", 2926 stl: "none", 2927 static_libs: ["bar"], 2928 apex_available: [ "myapex" ], 2929 } 2930 2931 java_library { 2932 name: "bar", 2933 sdk_version: "current", 2934 srcs: ["a.java"], 2935 apex_available: [ "myapex" ], 2936 } 2937 `) 2938} 2939 2940func TestApexMinSdkVersion_OkayEvenWhenDepIsNewer_IfItSatisfiesApexMinSdkVersion(t *testing.T) { 2941 t.Parallel() 2942 ctx := testApex(t, ` 2943 apex { 2944 name: "myapex", 2945 key: "myapex.key", 2946 native_shared_libs: ["mylib"], 2947 min_sdk_version: "29", 2948 } 2949 2950 apex_key { 2951 name: "myapex.key", 2952 public_key: "testkey.avbpubkey", 2953 private_key: "testkey.pem", 2954 } 2955 2956 // mylib will link to mylib2#current 2957 cc_library { 2958 name: "mylib", 2959 srcs: ["mylib.cpp"], 2960 shared_libs: ["mylib2"], 2961 system_shared_libs: [], 2962 stl: "none", 2963 apex_available: ["myapex", "otherapex"], 2964 min_sdk_version: "29", 2965 } 2966 2967 cc_library { 2968 name: "mylib2", 2969 srcs: ["mylib.cpp"], 2970 system_shared_libs: [], 2971 stl: "none", 2972 apex_available: ["otherapex"], 2973 stubs: { versions: ["29", "30"] }, 2974 min_sdk_version: "30", 2975 } 2976 2977 apex { 2978 name: "otherapex", 2979 key: "myapex.key", 2980 native_shared_libs: ["mylib", "mylib2"], 2981 min_sdk_version: "30", 2982 } 2983 `) 2984 expectLink := func(from, from_variant, to, to_variant string) { 2985 ld := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld") 2986 libFlags := ld.Args["libFlags"] 2987 ensureContains(t, libFlags, "android_arm64_armv8-a_"+to_variant+"/"+to+".so") 2988 } 2989 expectLink("mylib", "shared_apex29", "mylib2", "shared_current") 2990 expectLink("mylib", "shared_apex30", "mylib2", "shared_current") 2991} 2992 2993func TestApexMinSdkVersion_WorksWithSdkCodename(t *testing.T) { 2994 t.Parallel() 2995 withSAsActiveCodeNames := android.FixtureModifyProductVariables( 2996 func(variables android.FixtureProductVariables) { 2997 variables.Platform_sdk_codename = proptools.StringPtr("S") 2998 variables.Platform_version_active_codenames = []string{"S"} 2999 }, 3000 ) 3001 testApexError(t, `libbar.*: should support min_sdk_version\(S\)`, ` 3002 apex { 3003 name: "myapex", 3004 key: "myapex.key", 3005 native_shared_libs: ["libfoo"], 3006 min_sdk_version: "S", 3007 } 3008 apex_key { 3009 name: "myapex.key", 3010 public_key: "testkey.avbpubkey", 3011 private_key: "testkey.pem", 3012 } 3013 cc_library { 3014 name: "libfoo", 3015 shared_libs: ["libbar"], 3016 apex_available: ["myapex"], 3017 min_sdk_version: "29", 3018 } 3019 cc_library { 3020 name: "libbar", 3021 apex_available: ["myapex"], 3022 } 3023 `, withSAsActiveCodeNames) 3024} 3025 3026func TestApexMinSdkVersion_WorksWithActiveCodenames(t *testing.T) { 3027 t.Parallel() 3028 withSAsActiveCodeNames := android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 3029 variables.Platform_sdk_codename = proptools.StringPtr("S") 3030 variables.Platform_version_active_codenames = []string{"S", "T"} 3031 }) 3032 ctx := testApex(t, ` 3033 apex { 3034 name: "myapex", 3035 key: "myapex.key", 3036 native_shared_libs: ["libfoo"], 3037 min_sdk_version: "S", 3038 } 3039 apex_key { 3040 name: "myapex.key", 3041 public_key: "testkey.avbpubkey", 3042 private_key: "testkey.pem", 3043 } 3044 cc_library { 3045 name: "libfoo", 3046 shared_libs: ["libbar"], 3047 apex_available: ["myapex"], 3048 min_sdk_version: "S", 3049 } 3050 cc_library { 3051 name: "libbar", 3052 stubs: { 3053 symbol_file: "libbar.map.txt", 3054 versions: ["30", "S", "T"], 3055 }, 3056 } 3057 `, withSAsActiveCodeNames) 3058 3059 // ensure libfoo is linked with current version of libbar stub 3060 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared_apex10000") 3061 libFlags := libfoo.Rule("ld").Args["libFlags"] 3062 ensureContains(t, libFlags, "android_arm64_armv8-a_shared_current/libbar.so") 3063} 3064 3065func TestFilesInSubDir(t *testing.T) { 3066 t.Parallel() 3067 ctx := testApex(t, ` 3068 apex { 3069 name: "myapex", 3070 key: "myapex.key", 3071 native_shared_libs: ["mylib"], 3072 binaries: ["mybin", "mybin.rust"], 3073 prebuilts: ["myetc"], 3074 compile_multilib: "both", 3075 updatable: false, 3076 } 3077 3078 apex_key { 3079 name: "myapex.key", 3080 public_key: "testkey.avbpubkey", 3081 private_key: "testkey.pem", 3082 } 3083 3084 prebuilt_etc { 3085 name: "myetc", 3086 src: "myprebuilt", 3087 sub_dir: "foo/bar", 3088 } 3089 3090 cc_library { 3091 name: "mylib", 3092 srcs: ["mylib.cpp"], 3093 relative_install_path: "foo/bar", 3094 system_shared_libs: [], 3095 stl: "none", 3096 apex_available: [ "myapex" ], 3097 } 3098 3099 cc_binary { 3100 name: "mybin", 3101 srcs: ["mylib.cpp"], 3102 relative_install_path: "foo/bar", 3103 system_shared_libs: [], 3104 stl: "none", 3105 apex_available: [ "myapex" ], 3106 } 3107 3108 rust_binary { 3109 name: "mybin.rust", 3110 srcs: ["foo.rs"], 3111 relative_install_path: "rust_subdir", 3112 apex_available: [ "myapex" ], 3113 } 3114 `) 3115 3116 generateFsRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("generateFsConfig") 3117 cmd := generateFsRule.RuleParams.Command 3118 3119 // Ensure that the subdirectories are all listed 3120 ensureContains(t, cmd, "/etc ") 3121 ensureContains(t, cmd, "/etc/foo ") 3122 ensureContains(t, cmd, "/etc/foo/bar ") 3123 ensureContains(t, cmd, "/lib64 ") 3124 ensureContains(t, cmd, "/lib64/foo ") 3125 ensureContains(t, cmd, "/lib64/foo/bar ") 3126 ensureContains(t, cmd, "/lib ") 3127 ensureContains(t, cmd, "/lib/foo ") 3128 ensureContains(t, cmd, "/lib/foo/bar ") 3129 ensureContains(t, cmd, "/bin ") 3130 ensureContains(t, cmd, "/bin/foo ") 3131 ensureContains(t, cmd, "/bin/foo/bar ") 3132 ensureContains(t, cmd, "/bin/rust_subdir ") 3133} 3134 3135func TestFilesInSubDirWhenNativeBridgeEnabled(t *testing.T) { 3136 t.Parallel() 3137 ctx := testApex(t, ` 3138 apex { 3139 name: "myapex", 3140 key: "myapex.key", 3141 multilib: { 3142 both: { 3143 native_shared_libs: ["mylib"], 3144 binaries: ["mybin"], 3145 }, 3146 }, 3147 compile_multilib: "both", 3148 native_bridge_supported: true, 3149 updatable: false, 3150 } 3151 3152 apex_key { 3153 name: "myapex.key", 3154 public_key: "testkey.avbpubkey", 3155 private_key: "testkey.pem", 3156 } 3157 3158 cc_library { 3159 name: "mylib", 3160 relative_install_path: "foo/bar", 3161 system_shared_libs: [], 3162 stl: "none", 3163 apex_available: [ "myapex" ], 3164 native_bridge_supported: true, 3165 } 3166 3167 cc_binary { 3168 name: "mybin", 3169 relative_install_path: "foo/bar", 3170 system_shared_libs: [], 3171 stl: "none", 3172 apex_available: [ "myapex" ], 3173 native_bridge_supported: true, 3174 compile_multilib: "both", // default is "first" for binary 3175 multilib: { 3176 lib64: { 3177 suffix: "64", 3178 }, 3179 }, 3180 } 3181 `, android.PrepareForNativeBridgeEnabled) 3182 ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{ 3183 "bin/foo/bar/mybin", 3184 "bin/foo/bar/mybin64", 3185 "bin/arm/foo/bar/mybin", 3186 "bin/arm64/foo/bar/mybin64", 3187 "lib/foo/bar/mylib.so", 3188 "lib/arm/foo/bar/mylib.so", 3189 "lib64/foo/bar/mylib.so", 3190 "lib64/arm64/foo/bar/mylib.so", 3191 }) 3192} 3193 3194func TestVendorApex(t *testing.T) { 3195 t.Parallel() 3196 result := android.GroupFixturePreparers( 3197 prepareForApexTest, 3198 android.FixtureModifyConfig(android.SetKatiEnabledForTests), 3199 ).RunTestWithBp(t, ` 3200 apex { 3201 name: "myapex", 3202 key: "myapex.key", 3203 binaries: ["mybin"], 3204 vendor: true, 3205 updatable: false, 3206 } 3207 apex_key { 3208 name: "myapex.key", 3209 public_key: "testkey.avbpubkey", 3210 private_key: "testkey.pem", 3211 } 3212 cc_binary { 3213 name: "mybin", 3214 vendor: true, 3215 shared_libs: ["libfoo"], 3216 } 3217 cc_library { 3218 name: "libfoo", 3219 proprietary: true, 3220 } 3221 `) 3222 3223 ensureExactContents(t, result.TestContext, "myapex", "android_common_myapex", []string{ 3224 "bin/mybin", 3225 "lib64/libfoo.so", 3226 // TODO(b/159195575): Add an option to use VNDK libs from VNDK APEX 3227 "lib64/libc++.so", 3228 }) 3229 3230 apexBundle := result.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle) 3231 data := android.AndroidMkDataForTest(t, result.TestContext, apexBundle) 3232 name := apexBundle.BaseModuleName() 3233 prefix := "TARGET_" 3234 var builder strings.Builder 3235 data.Custom(&builder, name, prefix, "", data) 3236 androidMk := android.StringRelativeToTop(result.Config, builder.String()) 3237 installPath := "out/target/product/test_device/vendor/apex" 3238 ensureContains(t, androidMk, "LOCAL_MODULE_PATH := "+installPath) 3239 3240 apexManifestRule := result.ModuleForTests("myapex", "android_common_myapex").Rule("apexManifestRule") 3241 requireNativeLibs := names(apexManifestRule.Args["requireNativeLibs"]) 3242 ensureListNotContains(t, requireNativeLibs, ":vndk") 3243} 3244 3245func TestProductVariant(t *testing.T) { 3246 t.Parallel() 3247 ctx := testApex(t, ` 3248 apex { 3249 name: "myapex", 3250 key: "myapex.key", 3251 updatable: false, 3252 product_specific: true, 3253 binaries: ["foo"], 3254 } 3255 3256 apex_key { 3257 name: "myapex.key", 3258 public_key: "testkey.avbpubkey", 3259 private_key: "testkey.pem", 3260 } 3261 3262 cc_binary { 3263 name: "foo", 3264 product_available: true, 3265 apex_available: ["myapex"], 3266 srcs: ["foo.cpp"], 3267 } 3268 `) 3269 3270 cflags := strings.Fields( 3271 ctx.ModuleForTests("foo", "android_product_arm64_armv8-a_apex10000").Rule("cc").Args["cFlags"]) 3272 ensureListContains(t, cflags, "-D__ANDROID_VNDK__") 3273 ensureListContains(t, cflags, "-D__ANDROID_APEX__") 3274 ensureListContains(t, cflags, "-D__ANDROID_PRODUCT__") 3275 ensureListNotContains(t, cflags, "-D__ANDROID_VENDOR__") 3276} 3277 3278func TestApex_withPrebuiltFirmware(t *testing.T) { 3279 t.Parallel() 3280 testCases := []struct { 3281 name string 3282 additionalProp string 3283 }{ 3284 {"system apex with prebuilt_firmware", ""}, 3285 {"vendor apex with prebuilt_firmware", "vendor: true,"}, 3286 } 3287 for _, tc := range testCases { 3288 t.Run(tc.name, func(t *testing.T) { 3289 t.Parallel() 3290 ctx := testApex(t, ` 3291 apex { 3292 name: "myapex", 3293 key: "myapex.key", 3294 prebuilts: ["myfirmware"], 3295 updatable: false, 3296 `+tc.additionalProp+` 3297 } 3298 apex_key { 3299 name: "myapex.key", 3300 public_key: "testkey.avbpubkey", 3301 private_key: "testkey.pem", 3302 } 3303 prebuilt_firmware { 3304 name: "myfirmware", 3305 src: "myfirmware.bin", 3306 filename_from_src: true, 3307 `+tc.additionalProp+` 3308 } 3309 `) 3310 ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{ 3311 "etc/firmware/myfirmware.bin", 3312 }) 3313 }) 3314 } 3315} 3316 3317func TestAndroidMk_VendorApexRequired(t *testing.T) { 3318 t.Parallel() 3319 ctx := testApex(t, ` 3320 apex { 3321 name: "myapex", 3322 key: "myapex.key", 3323 vendor: true, 3324 native_shared_libs: ["mylib"], 3325 updatable: false, 3326 } 3327 3328 apex_key { 3329 name: "myapex.key", 3330 public_key: "testkey.avbpubkey", 3331 private_key: "testkey.pem", 3332 } 3333 3334 cc_library { 3335 name: "mylib", 3336 vendor_available: true, 3337 } 3338 `) 3339 3340 apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle) 3341 data := android.AndroidMkDataForTest(t, ctx, apexBundle) 3342 name := apexBundle.BaseModuleName() 3343 prefix := "TARGET_" 3344 var builder strings.Builder 3345 data.Custom(&builder, name, prefix, "", data) 3346 androidMk := builder.String() 3347 ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := libc++.vendor.myapex:64 mylib.vendor.myapex:64 libc.vendor libm.vendor libdl.vendor\n") 3348} 3349 3350func TestAndroidMkWritesCommonProperties(t *testing.T) { 3351 ctx := testApex(t, ` 3352 apex { 3353 name: "myapex", 3354 key: "myapex.key", 3355 vintf_fragments: ["fragment.xml"], 3356 init_rc: ["init.rc"], 3357 updatable: false, 3358 } 3359 apex_key { 3360 name: "myapex.key", 3361 public_key: "testkey.avbpubkey", 3362 private_key: "testkey.pem", 3363 } 3364 cc_binary { 3365 name: "mybin", 3366 } 3367 `) 3368 3369 apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle) 3370 data := android.AndroidMkDataForTest(t, ctx, apexBundle) 3371 name := apexBundle.BaseModuleName() 3372 prefix := "TARGET_" 3373 var builder strings.Builder 3374 data.Custom(&builder, name, prefix, "", data) 3375 androidMk := builder.String() 3376 ensureContains(t, androidMk, "LOCAL_FULL_VINTF_FRAGMENTS := fragment.xml\n") 3377 ensureContains(t, androidMk, "LOCAL_FULL_INIT_RC := init.rc\n") 3378} 3379 3380func TestStaticLinking(t *testing.T) { 3381 t.Parallel() 3382 ctx := testApex(t, ` 3383 apex { 3384 name: "myapex", 3385 key: "myapex.key", 3386 native_shared_libs: ["mylib"], 3387 updatable: false, 3388 } 3389 3390 apex_key { 3391 name: "myapex.key", 3392 public_key: "testkey.avbpubkey", 3393 private_key: "testkey.pem", 3394 } 3395 3396 cc_library { 3397 name: "mylib", 3398 srcs: ["mylib.cpp"], 3399 system_shared_libs: [], 3400 stl: "none", 3401 stubs: { 3402 versions: ["1", "2", "3"], 3403 }, 3404 apex_available: ["myapex"], 3405 } 3406 3407 cc_binary { 3408 name: "not_in_apex", 3409 srcs: ["mylib.cpp"], 3410 static_libs: ["mylib"], 3411 static_executable: true, 3412 system_shared_libs: [], 3413 stl: "none", 3414 } 3415 `) 3416 3417 ldFlags := ctx.ModuleForTests("not_in_apex", "android_arm64_armv8-a").Rule("ld").Args["libFlags"] 3418 3419 // Ensure that not_in_apex is linking with the static variant of mylib 3420 ensureContains(t, ldFlags, "mylib/android_arm64_armv8-a_static/mylib.a") 3421} 3422 3423func TestKeys(t *testing.T) { 3424 t.Parallel() 3425 ctx := testApex(t, ` 3426 apex { 3427 name: "myapex_keytest", 3428 key: "myapex.key", 3429 certificate: ":myapex.certificate", 3430 native_shared_libs: ["mylib"], 3431 file_contexts: ":myapex-file_contexts", 3432 updatable: false, 3433 } 3434 3435 cc_library { 3436 name: "mylib", 3437 srcs: ["mylib.cpp"], 3438 system_shared_libs: [], 3439 stl: "none", 3440 apex_available: [ "myapex_keytest" ], 3441 } 3442 3443 apex_key { 3444 name: "myapex.key", 3445 public_key: "testkey.avbpubkey", 3446 private_key: "testkey.pem", 3447 } 3448 3449 android_app_certificate { 3450 name: "myapex.certificate", 3451 certificate: "testkey", 3452 } 3453 3454 android_app_certificate { 3455 name: "myapex.certificate.override", 3456 certificate: "testkey.override", 3457 } 3458 3459 `) 3460 3461 // check the APEX keys 3462 keys := ctx.ModuleForTests("myapex.key", "android_common").Module().(*apexKey) 3463 3464 if keys.publicKeyFile.String() != "vendor/foo/devkeys/testkey.avbpubkey" { 3465 t.Errorf("public key %q is not %q", keys.publicKeyFile.String(), 3466 "vendor/foo/devkeys/testkey.avbpubkey") 3467 } 3468 if keys.privateKeyFile.String() != "vendor/foo/devkeys/testkey.pem" { 3469 t.Errorf("private key %q is not %q", keys.privateKeyFile.String(), 3470 "vendor/foo/devkeys/testkey.pem") 3471 } 3472 3473 // check the APK certs. It should be overridden to myapex.certificate.override 3474 certs := ctx.ModuleForTests("myapex_keytest", "android_common_myapex_keytest").Rule("signapk").Args["certificates"] 3475 if certs != "testkey.override.x509.pem testkey.override.pk8" { 3476 t.Errorf("cert and private key %q are not %q", certs, 3477 "testkey.override.509.pem testkey.override.pk8") 3478 } 3479} 3480 3481func TestCertificate(t *testing.T) { 3482 t.Parallel() 3483 t.Run("if unspecified, it defaults to DefaultAppCertificate", func(t *testing.T) { 3484 t.Parallel() 3485 ctx := testApex(t, ` 3486 apex { 3487 name: "myapex", 3488 key: "myapex.key", 3489 updatable: false, 3490 } 3491 apex_key { 3492 name: "myapex.key", 3493 public_key: "testkey.avbpubkey", 3494 private_key: "testkey.pem", 3495 }`) 3496 rule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("signapk") 3497 expected := "vendor/foo/devkeys/test.x509.pem vendor/foo/devkeys/test.pk8" 3498 if actual := rule.Args["certificates"]; actual != expected { 3499 t.Errorf("certificates should be %q, not %q", expected, actual) 3500 } 3501 }) 3502 t.Run("override when unspecified", func(t *testing.T) { 3503 t.Parallel() 3504 ctx := testApex(t, ` 3505 apex { 3506 name: "myapex_keytest", 3507 key: "myapex.key", 3508 file_contexts: ":myapex-file_contexts", 3509 updatable: false, 3510 } 3511 apex_key { 3512 name: "myapex.key", 3513 public_key: "testkey.avbpubkey", 3514 private_key: "testkey.pem", 3515 } 3516 android_app_certificate { 3517 name: "myapex.certificate.override", 3518 certificate: "testkey.override", 3519 }`) 3520 rule := ctx.ModuleForTests("myapex_keytest", "android_common_myapex_keytest").Rule("signapk") 3521 expected := "testkey.override.x509.pem testkey.override.pk8" 3522 if actual := rule.Args["certificates"]; actual != expected { 3523 t.Errorf("certificates should be %q, not %q", expected, actual) 3524 } 3525 }) 3526 t.Run("if specified as :module, it respects the prop", func(t *testing.T) { 3527 t.Parallel() 3528 ctx := testApex(t, ` 3529 apex { 3530 name: "myapex", 3531 key: "myapex.key", 3532 certificate: ":myapex.certificate", 3533 updatable: false, 3534 } 3535 apex_key { 3536 name: "myapex.key", 3537 public_key: "testkey.avbpubkey", 3538 private_key: "testkey.pem", 3539 } 3540 android_app_certificate { 3541 name: "myapex.certificate", 3542 certificate: "testkey", 3543 }`) 3544 rule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("signapk") 3545 expected := "testkey.x509.pem testkey.pk8" 3546 if actual := rule.Args["certificates"]; actual != expected { 3547 t.Errorf("certificates should be %q, not %q", expected, actual) 3548 } 3549 }) 3550 t.Run("override when specifiec as <:module>", func(t *testing.T) { 3551 t.Parallel() 3552 ctx := testApex(t, ` 3553 apex { 3554 name: "myapex_keytest", 3555 key: "myapex.key", 3556 file_contexts: ":myapex-file_contexts", 3557 certificate: ":myapex.certificate", 3558 updatable: false, 3559 } 3560 apex_key { 3561 name: "myapex.key", 3562 public_key: "testkey.avbpubkey", 3563 private_key: "testkey.pem", 3564 } 3565 android_app_certificate { 3566 name: "myapex.certificate.override", 3567 certificate: "testkey.override", 3568 }`) 3569 rule := ctx.ModuleForTests("myapex_keytest", "android_common_myapex_keytest").Rule("signapk") 3570 expected := "testkey.override.x509.pem testkey.override.pk8" 3571 if actual := rule.Args["certificates"]; actual != expected { 3572 t.Errorf("certificates should be %q, not %q", expected, actual) 3573 } 3574 }) 3575 t.Run("if specified as name, finds it from DefaultDevKeyDir", func(t *testing.T) { 3576 t.Parallel() 3577 ctx := testApex(t, ` 3578 apex { 3579 name: "myapex", 3580 key: "myapex.key", 3581 certificate: "testkey", 3582 updatable: false, 3583 } 3584 apex_key { 3585 name: "myapex.key", 3586 public_key: "testkey.avbpubkey", 3587 private_key: "testkey.pem", 3588 }`) 3589 rule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("signapk") 3590 expected := "vendor/foo/devkeys/testkey.x509.pem vendor/foo/devkeys/testkey.pk8" 3591 if actual := rule.Args["certificates"]; actual != expected { 3592 t.Errorf("certificates should be %q, not %q", expected, actual) 3593 } 3594 }) 3595 t.Run("override when specified as <name>", func(t *testing.T) { 3596 t.Parallel() 3597 ctx := testApex(t, ` 3598 apex { 3599 name: "myapex_keytest", 3600 key: "myapex.key", 3601 file_contexts: ":myapex-file_contexts", 3602 certificate: "testkey", 3603 updatable: false, 3604 } 3605 apex_key { 3606 name: "myapex.key", 3607 public_key: "testkey.avbpubkey", 3608 private_key: "testkey.pem", 3609 } 3610 android_app_certificate { 3611 name: "myapex.certificate.override", 3612 certificate: "testkey.override", 3613 }`) 3614 rule := ctx.ModuleForTests("myapex_keytest", "android_common_myapex_keytest").Rule("signapk") 3615 expected := "testkey.override.x509.pem testkey.override.pk8" 3616 if actual := rule.Args["certificates"]; actual != expected { 3617 t.Errorf("certificates should be %q, not %q", expected, actual) 3618 } 3619 }) 3620} 3621 3622func TestMacro(t *testing.T) { 3623 t.Parallel() 3624 ctx := testApex(t, ` 3625 apex { 3626 name: "myapex", 3627 key: "myapex.key", 3628 native_shared_libs: ["mylib", "mylib2"], 3629 updatable: false, 3630 } 3631 3632 apex { 3633 name: "otherapex", 3634 key: "myapex.key", 3635 native_shared_libs: ["mylib", "mylib2"], 3636 min_sdk_version: "29", 3637 } 3638 3639 apex_key { 3640 name: "myapex.key", 3641 public_key: "testkey.avbpubkey", 3642 private_key: "testkey.pem", 3643 } 3644 3645 cc_library { 3646 name: "mylib", 3647 srcs: ["mylib.cpp"], 3648 system_shared_libs: [], 3649 stl: "none", 3650 apex_available: [ 3651 "myapex", 3652 "otherapex", 3653 ], 3654 recovery_available: true, 3655 min_sdk_version: "29", 3656 } 3657 cc_library { 3658 name: "mylib2", 3659 srcs: ["mylib.cpp"], 3660 system_shared_libs: [], 3661 stl: "none", 3662 apex_available: [ 3663 "myapex", 3664 "otherapex", 3665 ], 3666 static_libs: ["mylib3"], 3667 recovery_available: true, 3668 min_sdk_version: "29", 3669 } 3670 cc_library { 3671 name: "mylib3", 3672 srcs: ["mylib.cpp"], 3673 system_shared_libs: [], 3674 stl: "none", 3675 apex_available: [ 3676 "myapex", 3677 "otherapex", 3678 ], 3679 recovery_available: true, 3680 min_sdk_version: "29", 3681 } 3682 `) 3683 3684 // non-APEX variant does not have __ANDROID_APEX__ defined 3685 mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"] 3686 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__") 3687 3688 // APEX variant has __ANDROID_APEX__ and __ANDROID_APEX__ defined 3689 mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex10000").Rule("cc").Args["cFlags"] 3690 ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__") 3691 3692 // APEX variant has __ANDROID_APEX__ and __ANDROID_APEX__ defined 3693 mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex29").Rule("cc").Args["cFlags"] 3694 ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__") 3695 3696 // When a cc_library sets use_apex_name_macro: true each apex gets a unique variant and 3697 // each variant defines additional macros to distinguish which apex variant it is built for 3698 3699 // non-APEX variant does not have __ANDROID_APEX__ defined 3700 mylibCFlags = ctx.ModuleForTests("mylib3", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"] 3701 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__") 3702 3703 // recovery variant does not set __ANDROID_APEX__ 3704 mylibCFlags = ctx.ModuleForTests("mylib3", "android_recovery_arm64_armv8-a_static").Rule("cc").Args["cFlags"] 3705 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__") 3706 3707 // non-APEX variant does not have __ANDROID_APEX__ defined 3708 mylibCFlags = ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"] 3709 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__") 3710 3711 // recovery variant does not set __ANDROID_APEX__ 3712 mylibCFlags = ctx.ModuleForTests("mylib2", "android_recovery_arm64_armv8-a_static").Rule("cc").Args["cFlags"] 3713 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__") 3714} 3715 3716func TestHeaderLibsDependency(t *testing.T) { 3717 t.Parallel() 3718 ctx := testApex(t, ` 3719 apex { 3720 name: "myapex", 3721 key: "myapex.key", 3722 native_shared_libs: ["mylib"], 3723 updatable: false, 3724 } 3725 3726 apex_key { 3727 name: "myapex.key", 3728 public_key: "testkey.avbpubkey", 3729 private_key: "testkey.pem", 3730 } 3731 3732 cc_library_headers { 3733 name: "mylib_headers", 3734 export_include_dirs: ["my_include"], 3735 system_shared_libs: [], 3736 stl: "none", 3737 apex_available: [ "myapex" ], 3738 } 3739 3740 cc_library { 3741 name: "mylib", 3742 srcs: ["mylib.cpp"], 3743 system_shared_libs: [], 3744 stl: "none", 3745 header_libs: ["mylib_headers"], 3746 export_header_lib_headers: ["mylib_headers"], 3747 stubs: { 3748 versions: ["1", "2", "3"], 3749 }, 3750 apex_available: [ "myapex" ], 3751 } 3752 3753 cc_library { 3754 name: "otherlib", 3755 srcs: ["mylib.cpp"], 3756 system_shared_libs: [], 3757 stl: "none", 3758 shared_libs: ["mylib"], 3759 } 3760 `) 3761 3762 cFlags := ctx.ModuleForTests("otherlib", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"] 3763 3764 // Ensure that the include path of the header lib is exported to 'otherlib' 3765 ensureContains(t, cFlags, "-Imy_include") 3766} 3767 3768type fileInApex struct { 3769 path string // path in apex 3770 src string // src path 3771 isLink bool 3772} 3773 3774func (f fileInApex) String() string { 3775 return f.src + ":" + f.path 3776} 3777 3778func (f fileInApex) match(expectation string) bool { 3779 parts := strings.Split(expectation, ":") 3780 if len(parts) == 1 { 3781 match, _ := path.Match(parts[0], f.path) 3782 return match 3783 } 3784 if len(parts) == 2 { 3785 matchSrc, _ := path.Match(parts[0], f.src) 3786 matchDst, _ := path.Match(parts[1], f.path) 3787 return matchSrc && matchDst 3788 } 3789 panic("invalid expected file specification: " + expectation) 3790} 3791 3792func getFiles(t *testing.T, ctx *android.TestContext, moduleName, variant string) []fileInApex { 3793 t.Helper() 3794 module := ctx.ModuleForTests(moduleName, variant) 3795 apexRule := module.MaybeRule("apexRule") 3796 apexDir := "/image.apex/" 3797 copyCmds := apexRule.Args["copy_commands"] 3798 var ret []fileInApex 3799 for _, cmd := range strings.Split(copyCmds, "&&") { 3800 cmd = strings.TrimSpace(cmd) 3801 if cmd == "" { 3802 continue 3803 } 3804 terms := strings.Split(cmd, " ") 3805 var dst, src string 3806 var isLink bool 3807 switch terms[0] { 3808 case "mkdir": 3809 case "cp": 3810 if len(terms) != 3 && len(terms) != 4 { 3811 t.Fatal("copyCmds contains invalid cp command", cmd) 3812 } 3813 dst = terms[len(terms)-1] 3814 src = terms[len(terms)-2] 3815 isLink = false 3816 case "ln": 3817 if len(terms) != 3 && len(terms) != 4 { 3818 // ln LINK TARGET or ln -s LINK TARGET 3819 t.Fatal("copyCmds contains invalid ln command", cmd) 3820 } 3821 dst = terms[len(terms)-1] 3822 src = terms[len(terms)-2] 3823 isLink = true 3824 default: 3825 t.Fatalf("copyCmds should contain mkdir/cp commands only: %q", cmd) 3826 } 3827 if dst != "" { 3828 index := strings.Index(dst, apexDir) 3829 if index == -1 { 3830 t.Fatal("copyCmds should copy a file to "+apexDir, cmd) 3831 } 3832 dstFile := dst[index+len(apexDir):] 3833 ret = append(ret, fileInApex{path: dstFile, src: src, isLink: isLink}) 3834 } 3835 } 3836 return ret 3837} 3838 3839func assertFileListEquals(t *testing.T, expectedFiles []string, actualFiles []fileInApex) { 3840 t.Helper() 3841 var failed bool 3842 var surplus []string 3843 filesMatched := make(map[string]bool) 3844 for _, file := range actualFiles { 3845 matchFound := false 3846 for _, expected := range expectedFiles { 3847 if file.match(expected) { 3848 matchFound = true 3849 filesMatched[expected] = true 3850 break 3851 } 3852 } 3853 if !matchFound { 3854 surplus = append(surplus, file.String()) 3855 } 3856 } 3857 3858 if len(surplus) > 0 { 3859 sort.Strings(surplus) 3860 t.Log("surplus files", surplus) 3861 failed = true 3862 } 3863 3864 if len(expectedFiles) > len(filesMatched) { 3865 var missing []string 3866 for _, expected := range expectedFiles { 3867 if !filesMatched[expected] { 3868 missing = append(missing, expected) 3869 } 3870 } 3871 sort.Strings(missing) 3872 t.Log("missing files", missing) 3873 failed = true 3874 } 3875 if failed { 3876 t.Fail() 3877 } 3878} 3879 3880func ensureExactContents(t *testing.T, ctx *android.TestContext, moduleName, variant string, files []string) { 3881 assertFileListEquals(t, files, getFiles(t, ctx, moduleName, variant)) 3882} 3883 3884func ensureExactDeapexedContents(t *testing.T, ctx *android.TestContext, moduleName string, variant string, files []string) { 3885 deapexer := ctx.ModuleForTests(moduleName, variant).Description("deapex") 3886 outputs := make([]string, 0, len(deapexer.ImplicitOutputs)+1) 3887 if deapexer.Output != nil { 3888 outputs = append(outputs, deapexer.Output.String()) 3889 } 3890 for _, output := range deapexer.ImplicitOutputs { 3891 outputs = append(outputs, output.String()) 3892 } 3893 actualFiles := make([]fileInApex, 0, len(outputs)) 3894 for _, output := range outputs { 3895 dir := "/deapexer/" 3896 pos := strings.LastIndex(output, dir) 3897 if pos == -1 { 3898 t.Fatal("Unknown deapexer output ", output) 3899 } 3900 path := output[pos+len(dir):] 3901 actualFiles = append(actualFiles, fileInApex{path: path, src: "", isLink: false}) 3902 } 3903 assertFileListEquals(t, files, actualFiles) 3904} 3905 3906func vndkLibrariesTxtFiles(vers ...string) (result string) { 3907 for _, v := range vers { 3908 for _, txt := range []string{"llndk", "vndkcore", "vndksp", "vndkprivate", "vndkproduct"} { 3909 result += ` 3910 prebuilt_etc { 3911 name: "` + txt + `.libraries.` + v + `.txt", 3912 src: "dummy.txt", 3913 } 3914 ` 3915 } 3916 } 3917 return 3918} 3919 3920func TestVndkApexVersion(t *testing.T) { 3921 t.Parallel() 3922 ctx := testApex(t, ` 3923 apex_vndk { 3924 name: "com.android.vndk.v27", 3925 key: "myapex.key", 3926 file_contexts: ":myapex-file_contexts", 3927 vndk_version: "27", 3928 updatable: false, 3929 } 3930 3931 apex_key { 3932 name: "myapex.key", 3933 public_key: "testkey.avbpubkey", 3934 private_key: "testkey.pem", 3935 } 3936 3937 vndk_prebuilt_shared { 3938 name: "libvndk27", 3939 version: "27", 3940 vendor_available: true, 3941 product_available: true, 3942 vndk: { 3943 enabled: true, 3944 }, 3945 target_arch: "arm64", 3946 arch: { 3947 arm: { 3948 srcs: ["libvndk27_arm.so"], 3949 }, 3950 arm64: { 3951 srcs: ["libvndk27_arm64.so"], 3952 }, 3953 }, 3954 apex_available: [ "com.android.vndk.v27" ], 3955 } 3956 3957 vndk_prebuilt_shared { 3958 name: "libvndk27", 3959 version: "27", 3960 vendor_available: true, 3961 product_available: true, 3962 vndk: { 3963 enabled: true, 3964 }, 3965 target_arch: "x86_64", 3966 arch: { 3967 x86: { 3968 srcs: ["libvndk27_x86.so"], 3969 }, 3970 x86_64: { 3971 srcs: ["libvndk27_x86_64.so"], 3972 }, 3973 }, 3974 } 3975 `+vndkLibrariesTxtFiles("27"), 3976 withFiles(map[string][]byte{ 3977 "libvndk27_arm.so": nil, 3978 "libvndk27_arm64.so": nil, 3979 "libvndk27_x86.so": nil, 3980 "libvndk27_x86_64.so": nil, 3981 })) 3982 3983 ensureExactContents(t, ctx, "com.android.vndk.v27", "android_common", []string{ 3984 "lib/libvndk27_arm.so", 3985 "lib64/libvndk27_arm64.so", 3986 "etc/*", 3987 }) 3988} 3989 3990func TestVndkApexNameRule(t *testing.T) { 3991 t.Parallel() 3992 ctx := testApex(t, ` 3993 apex_vndk { 3994 name: "com.android.vndk.v29", 3995 key: "myapex.key", 3996 file_contexts: ":myapex-file_contexts", 3997 vndk_version: "29", 3998 updatable: false, 3999 } 4000 apex_vndk { 4001 name: "com.android.vndk.v28", 4002 key: "myapex.key", 4003 file_contexts: ":myapex-file_contexts", 4004 vndk_version: "28", 4005 updatable: false, 4006 } 4007 apex_key { 4008 name: "myapex.key", 4009 public_key: "testkey.avbpubkey", 4010 private_key: "testkey.pem", 4011 }`+vndkLibrariesTxtFiles("28", "29")) 4012 4013 assertApexName := func(expected, moduleName string) { 4014 module := ctx.ModuleForTests(moduleName, "android_common") 4015 apexManifestRule := module.Rule("apexManifestRule") 4016 ensureContains(t, apexManifestRule.Args["opt"], "-v name "+expected) 4017 } 4018 4019 assertApexName("com.android.vndk.v29", "com.android.vndk.v29") 4020 assertApexName("com.android.vndk.v28", "com.android.vndk.v28") 4021} 4022 4023func TestVndkApexDoesntSupportNativeBridgeSupported(t *testing.T) { 4024 t.Parallel() 4025 testApexError(t, `module "com.android.vndk.v30" .*: native_bridge_supported: .* doesn't support native bridge binary`, ` 4026 apex_vndk { 4027 name: "com.android.vndk.v30", 4028 key: "com.android.vndk.v30.key", 4029 file_contexts: ":myapex-file_contexts", 4030 native_bridge_supported: true, 4031 } 4032 4033 apex_key { 4034 name: "com.android.vndk.v30.key", 4035 public_key: "testkey.avbpubkey", 4036 private_key: "testkey.pem", 4037 } 4038 4039 vndk_prebuilt_shared { 4040 name: "libvndk", 4041 version: "30", 4042 target_arch: "arm", 4043 srcs: ["mylib.cpp"], 4044 vendor_available: true, 4045 product_available: true, 4046 native_bridge_supported: true, 4047 vndk: { 4048 enabled: true, 4049 }, 4050 } 4051 `) 4052} 4053 4054func TestVndkApexWithBinder32(t *testing.T) { 4055 t.Parallel() 4056 ctx := testApex(t, ` 4057 apex_vndk { 4058 name: "com.android.vndk.v27", 4059 key: "myapex.key", 4060 file_contexts: ":myapex-file_contexts", 4061 vndk_version: "27", 4062 updatable: false, 4063 } 4064 4065 apex_key { 4066 name: "myapex.key", 4067 public_key: "testkey.avbpubkey", 4068 private_key: "testkey.pem", 4069 } 4070 4071 vndk_prebuilt_shared { 4072 name: "libvndk27", 4073 version: "27", 4074 target_arch: "arm", 4075 vendor_available: true, 4076 product_available: true, 4077 vndk: { 4078 enabled: true, 4079 }, 4080 arch: { 4081 arm: { 4082 srcs: ["libvndk27.so"], 4083 } 4084 }, 4085 } 4086 4087 vndk_prebuilt_shared { 4088 name: "libvndk27", 4089 version: "27", 4090 target_arch: "arm", 4091 binder32bit: true, 4092 vendor_available: true, 4093 product_available: true, 4094 vndk: { 4095 enabled: true, 4096 }, 4097 arch: { 4098 arm: { 4099 srcs: ["libvndk27binder32.so"], 4100 } 4101 }, 4102 apex_available: [ "com.android.vndk.v27" ], 4103 } 4104 `+vndkLibrariesTxtFiles("27"), 4105 withFiles(map[string][]byte{ 4106 "libvndk27.so": nil, 4107 "libvndk27binder32.so": nil, 4108 }), 4109 withBinder32bit, 4110 android.FixtureModifyConfig(func(config android.Config) { 4111 target := android.Target{ 4112 Os: android.Android, 4113 Arch: android.Arch{ 4114 ArchType: android.Arm, 4115 ArchVariant: "armv7-a-neon", 4116 Abi: []string{"armeabi-v7a"}, 4117 }, 4118 NativeBridge: android.NativeBridgeDisabled, 4119 NativeBridgeHostArchName: "", 4120 NativeBridgeRelativePath: "", 4121 } 4122 config.Targets[android.Android] = []android.Target{target} 4123 config.AndroidFirstDeviceTarget = target 4124 }), 4125 ) 4126 4127 ensureExactContents(t, ctx, "com.android.vndk.v27", "android_common", []string{ 4128 "lib/libvndk27binder32.so", 4129 "etc/*", 4130 }) 4131} 4132 4133func TestDependenciesInApexManifest(t *testing.T) { 4134 t.Parallel() 4135 ctx := testApex(t, ` 4136 apex { 4137 name: "myapex_nodep", 4138 key: "myapex.key", 4139 native_shared_libs: ["lib_nodep"], 4140 compile_multilib: "both", 4141 file_contexts: ":myapex-file_contexts", 4142 updatable: false, 4143 } 4144 4145 apex { 4146 name: "myapex_dep", 4147 key: "myapex.key", 4148 native_shared_libs: ["lib_dep"], 4149 compile_multilib: "both", 4150 file_contexts: ":myapex-file_contexts", 4151 updatable: false, 4152 } 4153 4154 apex { 4155 name: "myapex_provider", 4156 key: "myapex.key", 4157 native_shared_libs: ["libfoo"], 4158 compile_multilib: "both", 4159 file_contexts: ":myapex-file_contexts", 4160 updatable: false, 4161 } 4162 4163 apex { 4164 name: "myapex_selfcontained", 4165 key: "myapex.key", 4166 native_shared_libs: ["lib_dep_on_bar", "libbar"], 4167 compile_multilib: "both", 4168 file_contexts: ":myapex-file_contexts", 4169 updatable: false, 4170 } 4171 4172 apex_key { 4173 name: "myapex.key", 4174 public_key: "testkey.avbpubkey", 4175 private_key: "testkey.pem", 4176 } 4177 4178 cc_library { 4179 name: "lib_nodep", 4180 srcs: ["mylib.cpp"], 4181 system_shared_libs: [], 4182 stl: "none", 4183 apex_available: [ "myapex_nodep" ], 4184 } 4185 4186 cc_library { 4187 name: "lib_dep", 4188 srcs: ["mylib.cpp"], 4189 shared_libs: ["libfoo"], 4190 system_shared_libs: [], 4191 stl: "none", 4192 apex_available: [ 4193 "myapex_dep", 4194 "myapex_provider", 4195 "myapex_selfcontained", 4196 ], 4197 } 4198 4199 cc_library { 4200 name: "lib_dep_on_bar", 4201 srcs: ["mylib.cpp"], 4202 shared_libs: ["libbar"], 4203 system_shared_libs: [], 4204 stl: "none", 4205 apex_available: [ 4206 "myapex_selfcontained", 4207 ], 4208 } 4209 4210 4211 cc_library { 4212 name: "libfoo", 4213 srcs: ["mytest.cpp"], 4214 stubs: { 4215 versions: ["1"], 4216 }, 4217 system_shared_libs: [], 4218 stl: "none", 4219 apex_available: [ 4220 "myapex_provider", 4221 ], 4222 } 4223 4224 cc_library { 4225 name: "libbar", 4226 srcs: ["mytest.cpp"], 4227 stubs: { 4228 versions: ["1"], 4229 }, 4230 system_shared_libs: [], 4231 stl: "none", 4232 apex_available: [ 4233 "myapex_selfcontained", 4234 ], 4235 } 4236 4237 `) 4238 4239 var apexManifestRule android.TestingBuildParams 4240 var provideNativeLibs, requireNativeLibs []string 4241 4242 apexManifestRule = ctx.ModuleForTests("myapex_nodep", "android_common_myapex_nodep").Rule("apexManifestRule") 4243 provideNativeLibs = names(apexManifestRule.Args["provideNativeLibs"]) 4244 requireNativeLibs = names(apexManifestRule.Args["requireNativeLibs"]) 4245 ensureListEmpty(t, provideNativeLibs) 4246 ensureListEmpty(t, requireNativeLibs) 4247 4248 apexManifestRule = ctx.ModuleForTests("myapex_dep", "android_common_myapex_dep").Rule("apexManifestRule") 4249 provideNativeLibs = names(apexManifestRule.Args["provideNativeLibs"]) 4250 requireNativeLibs = names(apexManifestRule.Args["requireNativeLibs"]) 4251 ensureListEmpty(t, provideNativeLibs) 4252 ensureListContains(t, requireNativeLibs, "libfoo.so") 4253 4254 apexManifestRule = ctx.ModuleForTests("myapex_provider", "android_common_myapex_provider").Rule("apexManifestRule") 4255 provideNativeLibs = names(apexManifestRule.Args["provideNativeLibs"]) 4256 requireNativeLibs = names(apexManifestRule.Args["requireNativeLibs"]) 4257 ensureListContains(t, provideNativeLibs, "libfoo.so") 4258 ensureListEmpty(t, requireNativeLibs) 4259 4260 apexManifestRule = ctx.ModuleForTests("myapex_selfcontained", "android_common_myapex_selfcontained").Rule("apexManifestRule") 4261 provideNativeLibs = names(apexManifestRule.Args["provideNativeLibs"]) 4262 requireNativeLibs = names(apexManifestRule.Args["requireNativeLibs"]) 4263 ensureListContains(t, provideNativeLibs, "libbar.so") 4264 ensureListEmpty(t, requireNativeLibs) 4265} 4266 4267func TestOverrideApexManifestDefaultVersion(t *testing.T) { 4268 t.Parallel() 4269 ctx := testApex(t, ` 4270 apex { 4271 name: "myapex", 4272 key: "myapex.key", 4273 native_shared_libs: ["mylib"], 4274 updatable: false, 4275 } 4276 4277 apex_key { 4278 name: "myapex.key", 4279 public_key: "testkey.avbpubkey", 4280 private_key: "testkey.pem", 4281 } 4282 4283 cc_library { 4284 name: "mylib", 4285 srcs: ["mylib.cpp"], 4286 system_shared_libs: [], 4287 stl: "none", 4288 apex_available: [ 4289 "//apex_available:platform", 4290 "myapex", 4291 ], 4292 } 4293 `, android.FixtureMergeEnv(map[string]string{ 4294 "OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION": "1234", 4295 })) 4296 4297 module := ctx.ModuleForTests("myapex", "android_common_myapex") 4298 apexManifestRule := module.Rule("apexManifestRule") 4299 ensureContains(t, apexManifestRule.Args["default_version"], "1234") 4300} 4301 4302func TestCompileMultilibProp(t *testing.T) { 4303 t.Parallel() 4304 testCases := []struct { 4305 compileMultiLibProp string 4306 containedLibs []string 4307 notContainedLibs []string 4308 }{ 4309 { 4310 containedLibs: []string{ 4311 "image.apex/lib64/mylib.so", 4312 "image.apex/lib/mylib.so", 4313 }, 4314 compileMultiLibProp: `compile_multilib: "both",`, 4315 }, 4316 { 4317 containedLibs: []string{"image.apex/lib64/mylib.so"}, 4318 notContainedLibs: []string{"image.apex/lib/mylib.so"}, 4319 compileMultiLibProp: `compile_multilib: "first",`, 4320 }, 4321 { 4322 containedLibs: []string{"image.apex/lib64/mylib.so"}, 4323 notContainedLibs: []string{"image.apex/lib/mylib.so"}, 4324 // compile_multilib, when unset, should result to the same output as when compile_multilib is "first" 4325 }, 4326 { 4327 containedLibs: []string{"image.apex/lib64/mylib.so"}, 4328 notContainedLibs: []string{"image.apex/lib/mylib.so"}, 4329 compileMultiLibProp: `compile_multilib: "64",`, 4330 }, 4331 { 4332 containedLibs: []string{"image.apex/lib/mylib.so"}, 4333 notContainedLibs: []string{"image.apex/lib64/mylib.so"}, 4334 compileMultiLibProp: `compile_multilib: "32",`, 4335 }, 4336 } 4337 for _, testCase := range testCases { 4338 ctx := testApex(t, fmt.Sprintf(` 4339 apex { 4340 name: "myapex", 4341 key: "myapex.key", 4342 %s 4343 native_shared_libs: ["mylib"], 4344 updatable: false, 4345 } 4346 apex_key { 4347 name: "myapex.key", 4348 public_key: "testkey.avbpubkey", 4349 private_key: "testkey.pem", 4350 } 4351 cc_library { 4352 name: "mylib", 4353 srcs: ["mylib.cpp"], 4354 apex_available: [ 4355 "//apex_available:platform", 4356 "myapex", 4357 ], 4358 } 4359 `, testCase.compileMultiLibProp), 4360 ) 4361 module := ctx.ModuleForTests("myapex", "android_common_myapex") 4362 apexRule := module.Rule("apexRule") 4363 copyCmds := apexRule.Args["copy_commands"] 4364 for _, containedLib := range testCase.containedLibs { 4365 ensureContains(t, copyCmds, containedLib) 4366 } 4367 for _, notContainedLib := range testCase.notContainedLibs { 4368 ensureNotContains(t, copyCmds, notContainedLib) 4369 } 4370 } 4371} 4372 4373func TestNonTestApex(t *testing.T) { 4374 t.Parallel() 4375 ctx := testApex(t, ` 4376 apex { 4377 name: "myapex", 4378 key: "myapex.key", 4379 native_shared_libs: ["mylib_common"], 4380 updatable: false, 4381 } 4382 4383 apex_key { 4384 name: "myapex.key", 4385 public_key: "testkey.avbpubkey", 4386 private_key: "testkey.pem", 4387 } 4388 4389 cc_library { 4390 name: "mylib_common", 4391 srcs: ["mylib.cpp"], 4392 system_shared_libs: [], 4393 stl: "none", 4394 apex_available: [ 4395 "//apex_available:platform", 4396 "myapex", 4397 ], 4398 } 4399 `) 4400 4401 module := ctx.ModuleForTests("myapex", "android_common_myapex") 4402 apexRule := module.Rule("apexRule") 4403 copyCmds := apexRule.Args["copy_commands"] 4404 4405 if apex, ok := module.Module().(*apexBundle); !ok || apex.testApex { 4406 t.Log("Apex was a test apex!") 4407 t.Fail() 4408 } 4409 // Ensure that main rule creates an output 4410 ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned") 4411 4412 // Ensure that apex variant is created for the direct dep 4413 ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared_apex10000") 4414 4415 // Ensure that both direct and indirect deps are copied into apex 4416 ensureContains(t, copyCmds, "image.apex/lib64/mylib_common.so") 4417 4418 // Ensure that the platform variant ends with _shared 4419 ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared") 4420 4421 if !ctx.ModuleForTests("mylib_common", "android_arm64_armv8-a_shared_apex10000").Module().(*cc.Module).InAnyApex() { 4422 t.Log("Found mylib_common not in any apex!") 4423 t.Fail() 4424 } 4425} 4426 4427func TestTestApex(t *testing.T) { 4428 t.Parallel() 4429 ctx := testApex(t, ` 4430 apex_test { 4431 name: "myapex", 4432 key: "myapex.key", 4433 native_shared_libs: ["mylib_common_test"], 4434 updatable: false, 4435 } 4436 4437 apex_key { 4438 name: "myapex.key", 4439 public_key: "testkey.avbpubkey", 4440 private_key: "testkey.pem", 4441 } 4442 4443 cc_library { 4444 name: "mylib_common_test", 4445 srcs: ["mylib.cpp"], 4446 system_shared_libs: [], 4447 stl: "none", 4448 // TODO: remove //apex_available:platform 4449 apex_available: [ 4450 "//apex_available:platform", 4451 "myapex", 4452 ], 4453 } 4454 `) 4455 4456 module := ctx.ModuleForTests("myapex", "android_common_myapex") 4457 apexRule := module.Rule("apexRule") 4458 copyCmds := apexRule.Args["copy_commands"] 4459 4460 if apex, ok := module.Module().(*apexBundle); !ok || !apex.testApex { 4461 t.Log("Apex was not a test apex!") 4462 t.Fail() 4463 } 4464 // Ensure that main rule creates an output 4465 ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned") 4466 4467 // Ensure that apex variant is created for the direct dep 4468 ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common_test"), "android_arm64_armv8-a_shared_apex10000") 4469 4470 // Ensure that both direct and indirect deps are copied into apex 4471 ensureContains(t, copyCmds, "image.apex/lib64/mylib_common_test.so") 4472 4473 // Ensure that the platform variant ends with _shared 4474 ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common_test"), "android_arm64_armv8-a_shared") 4475} 4476 4477func TestLibzVendorIsntStable(t *testing.T) { 4478 t.Parallel() 4479 ctx := testApex(t, ` 4480 apex { 4481 name: "myapex", 4482 key: "myapex.key", 4483 updatable: false, 4484 binaries: ["mybin"], 4485 } 4486 apex { 4487 name: "myvendorapex", 4488 key: "myapex.key", 4489 file_contexts: "myvendorapex_file_contexts", 4490 vendor: true, 4491 updatable: false, 4492 binaries: ["mybin"], 4493 } 4494 apex_key { 4495 name: "myapex.key", 4496 public_key: "testkey.avbpubkey", 4497 private_key: "testkey.pem", 4498 } 4499 cc_binary { 4500 name: "mybin", 4501 vendor_available: true, 4502 system_shared_libs: [], 4503 stl: "none", 4504 shared_libs: ["libz"], 4505 apex_available: ["//apex_available:anyapex"], 4506 } 4507 cc_library { 4508 name: "libz", 4509 vendor_available: true, 4510 system_shared_libs: [], 4511 stl: "none", 4512 stubs: { 4513 versions: ["28", "30"], 4514 }, 4515 target: { 4516 vendor: { 4517 no_stubs: true, 4518 }, 4519 }, 4520 } 4521 `, withFiles(map[string][]byte{ 4522 "myvendorapex_file_contexts": nil, 4523 })) 4524 4525 // libz provides stubs for core variant. 4526 { 4527 ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{ 4528 "bin/mybin", 4529 }) 4530 apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexManifestRule") 4531 android.AssertStringEquals(t, "should require libz", apexManifestRule.Args["requireNativeLibs"], "libz.so") 4532 } 4533 // libz doesn't provide stubs for vendor variant. 4534 { 4535 ensureExactContents(t, ctx, "myvendorapex", "android_common_myvendorapex", []string{ 4536 "bin/mybin", 4537 "lib64/libz.so", 4538 }) 4539 apexManifestRule := ctx.ModuleForTests("myvendorapex", "android_common_myvendorapex").Rule("apexManifestRule") 4540 android.AssertStringEquals(t, "should not require libz", apexManifestRule.Args["requireNativeLibs"], "") 4541 } 4542} 4543 4544func TestApexWithTarget(t *testing.T) { 4545 t.Parallel() 4546 ctx := testApex(t, ` 4547 apex { 4548 name: "myapex", 4549 key: "myapex.key", 4550 updatable: false, 4551 multilib: { 4552 first: { 4553 native_shared_libs: ["mylib_common"], 4554 } 4555 }, 4556 target: { 4557 android: { 4558 multilib: { 4559 first: { 4560 native_shared_libs: ["mylib"], 4561 } 4562 } 4563 }, 4564 host: { 4565 multilib: { 4566 first: { 4567 native_shared_libs: ["mylib2"], 4568 } 4569 } 4570 } 4571 } 4572 } 4573 4574 apex_key { 4575 name: "myapex.key", 4576 public_key: "testkey.avbpubkey", 4577 private_key: "testkey.pem", 4578 } 4579 4580 cc_library { 4581 name: "mylib", 4582 srcs: ["mylib.cpp"], 4583 system_shared_libs: [], 4584 stl: "none", 4585 // TODO: remove //apex_available:platform 4586 apex_available: [ 4587 "//apex_available:platform", 4588 "myapex", 4589 ], 4590 } 4591 4592 cc_library { 4593 name: "mylib_common", 4594 srcs: ["mylib.cpp"], 4595 system_shared_libs: [], 4596 stl: "none", 4597 compile_multilib: "first", 4598 // TODO: remove //apex_available:platform 4599 apex_available: [ 4600 "//apex_available:platform", 4601 "myapex", 4602 ], 4603 } 4604 4605 cc_library { 4606 name: "mylib2", 4607 srcs: ["mylib.cpp"], 4608 system_shared_libs: [], 4609 stl: "none", 4610 compile_multilib: "first", 4611 } 4612 `) 4613 4614 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule") 4615 copyCmds := apexRule.Args["copy_commands"] 4616 4617 // Ensure that main rule creates an output 4618 ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned") 4619 4620 // Ensure that apex variant is created for the direct dep 4621 ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_apex10000") 4622 ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared_apex10000") 4623 ensureListNotContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_apex10000") 4624 4625 // Ensure that both direct and indirect deps are copied into apex 4626 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") 4627 ensureContains(t, copyCmds, "image.apex/lib64/mylib_common.so") 4628 ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so") 4629 4630 // Ensure that the platform variant ends with _shared 4631 ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared") 4632 ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared") 4633 ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared") 4634} 4635 4636func TestApexWithArch(t *testing.T) { 4637 t.Parallel() 4638 ctx := testApex(t, ` 4639 apex { 4640 name: "myapex", 4641 key: "myapex.key", 4642 updatable: false, 4643 native_shared_libs: ["mylib.generic"], 4644 arch: { 4645 arm64: { 4646 native_shared_libs: ["mylib.arm64"], 4647 exclude_native_shared_libs: ["mylib.generic"], 4648 }, 4649 x86_64: { 4650 native_shared_libs: ["mylib.x64"], 4651 exclude_native_shared_libs: ["mylib.generic"], 4652 }, 4653 } 4654 } 4655 4656 apex_key { 4657 name: "myapex.key", 4658 public_key: "testkey.avbpubkey", 4659 private_key: "testkey.pem", 4660 } 4661 4662 cc_library { 4663 name: "mylib.generic", 4664 srcs: ["mylib.cpp"], 4665 system_shared_libs: [], 4666 stl: "none", 4667 // TODO: remove //apex_available:platform 4668 apex_available: [ 4669 "//apex_available:platform", 4670 "myapex", 4671 ], 4672 } 4673 4674 cc_library { 4675 name: "mylib.arm64", 4676 srcs: ["mylib.cpp"], 4677 system_shared_libs: [], 4678 stl: "none", 4679 // TODO: remove //apex_available:platform 4680 apex_available: [ 4681 "//apex_available:platform", 4682 "myapex", 4683 ], 4684 } 4685 4686 cc_library { 4687 name: "mylib.x64", 4688 srcs: ["mylib.cpp"], 4689 system_shared_libs: [], 4690 stl: "none", 4691 // TODO: remove //apex_available:platform 4692 apex_available: [ 4693 "//apex_available:platform", 4694 "myapex", 4695 ], 4696 } 4697 `) 4698 4699 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule") 4700 copyCmds := apexRule.Args["copy_commands"] 4701 4702 // Ensure that apex variant is created for the direct dep 4703 ensureListContains(t, ctx.ModuleVariantsForTests("mylib.arm64"), "android_arm64_armv8-a_shared_apex10000") 4704 ensureListNotContains(t, ctx.ModuleVariantsForTests("mylib.generic"), "android_arm64_armv8-a_shared_apex10000") 4705 ensureListNotContains(t, ctx.ModuleVariantsForTests("mylib.x64"), "android_arm64_armv8-a_shared_apex10000") 4706 4707 // Ensure that both direct and indirect deps are copied into apex 4708 ensureContains(t, copyCmds, "image.apex/lib64/mylib.arm64.so") 4709 ensureNotContains(t, copyCmds, "image.apex/lib64/mylib.x64.so") 4710} 4711 4712func TestApexWithShBinary(t *testing.T) { 4713 t.Parallel() 4714 ctx := testApex(t, ` 4715 apex { 4716 name: "myapex", 4717 key: "myapex.key", 4718 sh_binaries: ["myscript"], 4719 updatable: false, 4720 compile_multilib: "both", 4721 } 4722 4723 apex_key { 4724 name: "myapex.key", 4725 public_key: "testkey.avbpubkey", 4726 private_key: "testkey.pem", 4727 } 4728 4729 sh_binary { 4730 name: "myscript", 4731 src: "mylib.cpp", 4732 filename: "myscript.sh", 4733 sub_dir: "script", 4734 } 4735 `) 4736 4737 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule") 4738 copyCmds := apexRule.Args["copy_commands"] 4739 4740 ensureContains(t, copyCmds, "image.apex/bin/script/myscript.sh") 4741} 4742 4743func TestApexInVariousPartition(t *testing.T) { 4744 t.Parallel() 4745 testcases := []struct { 4746 propName, partition string 4747 }{ 4748 {"", "system"}, 4749 {"product_specific: true", "product"}, 4750 {"soc_specific: true", "vendor"}, 4751 {"proprietary: true", "vendor"}, 4752 {"vendor: true", "vendor"}, 4753 {"system_ext_specific: true", "system_ext"}, 4754 } 4755 for _, tc := range testcases { 4756 t.Run(tc.propName+":"+tc.partition, func(t *testing.T) { 4757 t.Parallel() 4758 ctx := testApex(t, ` 4759 apex { 4760 name: "myapex", 4761 key: "myapex.key", 4762 updatable: false, 4763 `+tc.propName+` 4764 } 4765 4766 apex_key { 4767 name: "myapex.key", 4768 public_key: "testkey.avbpubkey", 4769 private_key: "testkey.pem", 4770 } 4771 `) 4772 4773 apex := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle) 4774 expected := "out/soong/target/product/test_device/" + tc.partition + "/apex" 4775 actual := apex.installDir.RelativeToTop().String() 4776 if actual != expected { 4777 t.Errorf("wrong install path. expected %q. actual %q", expected, actual) 4778 } 4779 }) 4780 } 4781} 4782 4783func TestFileContexts_FindInDefaultLocationIfNotSet(t *testing.T) { 4784 t.Parallel() 4785 ctx := testApex(t, ` 4786 apex { 4787 name: "myapex", 4788 key: "myapex.key", 4789 updatable: false, 4790 } 4791 4792 apex_key { 4793 name: "myapex.key", 4794 public_key: "testkey.avbpubkey", 4795 private_key: "testkey.pem", 4796 } 4797 `) 4798 module := ctx.ModuleForTests("myapex", "android_common_myapex") 4799 rule := module.Output("file_contexts") 4800 ensureContains(t, rule.RuleParams.Command, "cat system/sepolicy/apex/myapex-file_contexts") 4801} 4802 4803func TestFileContexts_ShouldBeUnderSystemSepolicyForSystemApexes(t *testing.T) { 4804 t.Parallel() 4805 testApexError(t, `"myapex" .*: file_contexts: should be under system/sepolicy`, ` 4806 apex { 4807 name: "myapex", 4808 key: "myapex.key", 4809 file_contexts: "my_own_file_contexts", 4810 updatable: false, 4811 } 4812 4813 apex_key { 4814 name: "myapex.key", 4815 public_key: "testkey.avbpubkey", 4816 private_key: "testkey.pem", 4817 } 4818 `, withFiles(map[string][]byte{ 4819 "my_own_file_contexts": nil, 4820 })) 4821} 4822 4823func TestFileContexts_ProductSpecificApexes(t *testing.T) { 4824 t.Parallel() 4825 testApexError(t, `"myapex" .*: file_contexts: cannot find`, ` 4826 apex { 4827 name: "myapex", 4828 key: "myapex.key", 4829 product_specific: true, 4830 file_contexts: "product_specific_file_contexts", 4831 updatable: false, 4832 } 4833 4834 apex_key { 4835 name: "myapex.key", 4836 public_key: "testkey.avbpubkey", 4837 private_key: "testkey.pem", 4838 } 4839 `) 4840 4841 ctx := testApex(t, ` 4842 apex { 4843 name: "myapex", 4844 key: "myapex.key", 4845 product_specific: true, 4846 file_contexts: "product_specific_file_contexts", 4847 updatable: false, 4848 } 4849 4850 apex_key { 4851 name: "myapex.key", 4852 public_key: "testkey.avbpubkey", 4853 private_key: "testkey.pem", 4854 } 4855 `, withFiles(map[string][]byte{ 4856 "product_specific_file_contexts": nil, 4857 })) 4858 module := ctx.ModuleForTests("myapex", "android_common_myapex") 4859 rule := module.Output("file_contexts") 4860 ensureContains(t, rule.RuleParams.Command, "cat product_specific_file_contexts") 4861} 4862 4863func TestFileContexts_SetViaFileGroup(t *testing.T) { 4864 t.Parallel() 4865 ctx := testApex(t, ` 4866 apex { 4867 name: "myapex", 4868 key: "myapex.key", 4869 product_specific: true, 4870 file_contexts: ":my-file-contexts", 4871 updatable: false, 4872 } 4873 4874 apex_key { 4875 name: "myapex.key", 4876 public_key: "testkey.avbpubkey", 4877 private_key: "testkey.pem", 4878 } 4879 4880 filegroup { 4881 name: "my-file-contexts", 4882 srcs: ["product_specific_file_contexts"], 4883 } 4884 `, withFiles(map[string][]byte{ 4885 "product_specific_file_contexts": nil, 4886 })) 4887 module := ctx.ModuleForTests("myapex", "android_common_myapex") 4888 rule := module.Output("file_contexts") 4889 ensureContains(t, rule.RuleParams.Command, "cat product_specific_file_contexts") 4890} 4891 4892func TestApexKeyFromOtherModule(t *testing.T) { 4893 t.Parallel() 4894 ctx := testApex(t, ` 4895 apex_key { 4896 name: "myapex.key", 4897 public_key: ":my.avbpubkey", 4898 private_key: ":my.pem", 4899 product_specific: true, 4900 } 4901 4902 filegroup { 4903 name: "my.avbpubkey", 4904 srcs: ["testkey2.avbpubkey"], 4905 } 4906 4907 filegroup { 4908 name: "my.pem", 4909 srcs: ["testkey2.pem"], 4910 } 4911 `) 4912 4913 apex_key := ctx.ModuleForTests("myapex.key", "android_common").Module().(*apexKey) 4914 expected_pubkey := "testkey2.avbpubkey" 4915 actual_pubkey := apex_key.publicKeyFile.String() 4916 if actual_pubkey != expected_pubkey { 4917 t.Errorf("wrong public key path. expected %q. actual %q", expected_pubkey, actual_pubkey) 4918 } 4919 expected_privkey := "testkey2.pem" 4920 actual_privkey := apex_key.privateKeyFile.String() 4921 if actual_privkey != expected_privkey { 4922 t.Errorf("wrong private key path. expected %q. actual %q", expected_privkey, actual_privkey) 4923 } 4924} 4925 4926func TestPrebuilt(t *testing.T) { 4927 t.Parallel() 4928 ctx := testApex(t, ` 4929 prebuilt_apex { 4930 name: "myapex", 4931 arch: { 4932 arm64: { 4933 src: "myapex-arm64.apex", 4934 }, 4935 arm: { 4936 src: "myapex-arm.apex", 4937 }, 4938 }, 4939 } 4940 `) 4941 4942 testingModule := ctx.ModuleForTests("myapex", "android_common_myapex") 4943 prebuilt := testingModule.Module().(*Prebuilt) 4944 4945 expectedInput := "myapex-arm64.apex" 4946 if prebuilt.inputApex.String() != expectedInput { 4947 t.Errorf("inputApex invalid. expected: %q, actual: %q", expectedInput, prebuilt.inputApex.String()) 4948 } 4949 android.AssertStringDoesContain(t, "Invalid provenance metadata file", 4950 prebuilt.ProvenanceMetaDataFile().String(), "soong/.intermediates/provenance_metadata/myapex/provenance_metadata.textproto") 4951 rule := testingModule.Rule("genProvenanceMetaData") 4952 android.AssertStringEquals(t, "Invalid input", "myapex-arm64.apex", rule.Inputs[0].String()) 4953 android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/myapex/provenance_metadata.textproto", rule.Output.String()) 4954 android.AssertStringEquals(t, "Invalid args", "myapex", rule.Args["module_name"]) 4955 android.AssertStringEquals(t, "Invalid args", "/system/apex/myapex.apex", rule.Args["install_path"]) 4956 4957 entries := android.AndroidMkEntriesForTest(t, ctx, testingModule.Module())[0] 4958 android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "prebuilt_apex", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0]) 4959} 4960 4961func TestPrebuiltMissingSrc(t *testing.T) { 4962 t.Parallel() 4963 testApexError(t, `module "myapex" variant "android_common_myapex".*: prebuilt_apex does not support "arm64_armv8-a"`, ` 4964 prebuilt_apex { 4965 name: "myapex", 4966 } 4967 `) 4968} 4969 4970func TestPrebuiltFilenameOverride(t *testing.T) { 4971 t.Parallel() 4972 ctx := testApex(t, ` 4973 prebuilt_apex { 4974 name: "myapex", 4975 src: "myapex-arm.apex", 4976 filename: "notmyapex.apex", 4977 } 4978 `) 4979 4980 testingModule := ctx.ModuleForTests("myapex", "android_common_myapex") 4981 p := testingModule.Module().(*Prebuilt) 4982 4983 expected := "notmyapex.apex" 4984 if p.installFilename != expected { 4985 t.Errorf("installFilename invalid. expected: %q, actual: %q", expected, p.installFilename) 4986 } 4987 rule := testingModule.Rule("genProvenanceMetaData") 4988 android.AssertStringEquals(t, "Invalid input", "myapex-arm.apex", rule.Inputs[0].String()) 4989 android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/myapex/provenance_metadata.textproto", rule.Output.String()) 4990 android.AssertStringEquals(t, "Invalid args", "myapex", rule.Args["module_name"]) 4991 android.AssertStringEquals(t, "Invalid args", "/system/apex/notmyapex.apex", rule.Args["install_path"]) 4992} 4993 4994func TestApexSetFilenameOverride(t *testing.T) { 4995 t.Parallel() 4996 testApex(t, ` 4997 apex_set { 4998 name: "com.company.android.myapex", 4999 apex_name: "com.android.myapex", 5000 set: "company-myapex.apks", 5001 filename: "com.company.android.myapex.apex" 5002 } 5003 `).ModuleForTests("com.company.android.myapex", "android_common_com.android.myapex") 5004 5005 testApex(t, ` 5006 apex_set { 5007 name: "com.company.android.myapex", 5008 apex_name: "com.android.myapex", 5009 set: "company-myapex.apks", 5010 filename: "com.company.android.myapex.capex" 5011 } 5012 `).ModuleForTests("com.company.android.myapex", "android_common_com.android.myapex") 5013 5014 testApexError(t, `filename should end in .apex or .capex for apex_set`, ` 5015 apex_set { 5016 name: "com.company.android.myapex", 5017 apex_name: "com.android.myapex", 5018 set: "company-myapex.apks", 5019 filename: "some-random-suffix" 5020 } 5021 `) 5022} 5023 5024func TestPrebuiltOverrides(t *testing.T) { 5025 t.Parallel() 5026 ctx := testApex(t, ` 5027 prebuilt_apex { 5028 name: "myapex.prebuilt", 5029 src: "myapex-arm.apex", 5030 overrides: [ 5031 "myapex", 5032 ], 5033 } 5034 `) 5035 5036 testingModule := ctx.ModuleForTests("myapex.prebuilt", "android_common_myapex.prebuilt") 5037 p := testingModule.Module().(*Prebuilt) 5038 5039 expected := []string{"myapex"} 5040 actual := android.AndroidMkEntriesForTest(t, ctx, p)[0].EntryMap["LOCAL_OVERRIDES_MODULES"] 5041 if !reflect.DeepEqual(actual, expected) { 5042 t.Errorf("Incorrect LOCAL_OVERRIDES_MODULES value '%s', expected '%s'", actual, expected) 5043 } 5044 rule := testingModule.Rule("genProvenanceMetaData") 5045 android.AssertStringEquals(t, "Invalid input", "myapex-arm.apex", rule.Inputs[0].String()) 5046 android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/myapex.prebuilt/provenance_metadata.textproto", rule.Output.String()) 5047 android.AssertStringEquals(t, "Invalid args", "myapex.prebuilt", rule.Args["module_name"]) 5048 android.AssertStringEquals(t, "Invalid args", "/system/apex/myapex.prebuilt.apex", rule.Args["install_path"]) 5049} 5050 5051func TestPrebuiltApexName(t *testing.T) { 5052 t.Parallel() 5053 testApex(t, ` 5054 prebuilt_apex { 5055 name: "com.company.android.myapex", 5056 apex_name: "com.android.myapex", 5057 src: "company-myapex-arm.apex", 5058 } 5059 `).ModuleForTests("com.company.android.myapex", "android_common_com.android.myapex") 5060 5061 testApex(t, ` 5062 apex_set { 5063 name: "com.company.android.myapex", 5064 apex_name: "com.android.myapex", 5065 set: "company-myapex.apks", 5066 } 5067 `).ModuleForTests("com.company.android.myapex", "android_common_com.android.myapex") 5068} 5069 5070func TestPrebuiltApexNameWithPlatformBootclasspath(t *testing.T) { 5071 t.Parallel() 5072 _ = android.GroupFixturePreparers( 5073 java.PrepareForTestWithJavaDefaultModules, 5074 PrepareForTestWithApexBuildComponents, 5075 android.FixtureWithRootAndroidBp(` 5076 platform_bootclasspath { 5077 name: "platform-bootclasspath", 5078 fragments: [ 5079 { 5080 apex: "com.android.art", 5081 module: "art-bootclasspath-fragment", 5082 }, 5083 ], 5084 } 5085 5086 prebuilt_apex { 5087 name: "com.company.android.art", 5088 apex_name: "com.android.art", 5089 src: "com.company.android.art-arm.apex", 5090 exported_bootclasspath_fragments: ["art-bootclasspath-fragment"], 5091 } 5092 5093 prebuilt_bootclasspath_fragment { 5094 name: "art-bootclasspath-fragment", 5095 image_name: "art", 5096 contents: ["core-oj"], 5097 hidden_api: { 5098 annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", 5099 metadata: "my-bootclasspath-fragment/metadata.csv", 5100 index: "my-bootclasspath-fragment/index.csv", 5101 stub_flags: "my-bootclasspath-fragment/stub-flags.csv", 5102 all_flags: "my-bootclasspath-fragment/all-flags.csv", 5103 }, 5104 } 5105 5106 java_import { 5107 name: "core-oj", 5108 jars: ["prebuilt.jar"], 5109 } 5110 `), 5111 ).RunTest(t) 5112} 5113 5114// A minimal context object for use with DexJarBuildPath 5115type moduleErrorfTestCtx struct { 5116} 5117 5118func (ctx moduleErrorfTestCtx) ModuleErrorf(format string, args ...interface{}) { 5119} 5120 5121func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { 5122 t.Parallel() 5123 preparer := android.GroupFixturePreparers( 5124 java.FixtureConfigureApexBootJars("myapex:libfoo", "myapex:libbar"), 5125 // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding 5126 // is disabled. 5127 android.FixtureAddTextFile("frameworks/base/Android.bp", ""), 5128 5129 // Make sure that we have atleast one platform library so that we can check the monolithic hiddenapi 5130 // file creation. 5131 java.FixtureConfigureBootJars("platform:foo"), 5132 android.FixtureModifyMockFS(func(fs android.MockFS) { 5133 fs["platform/Android.bp"] = []byte(` 5134 java_library { 5135 name: "foo", 5136 srcs: ["Test.java"], 5137 compile_dex: true, 5138 } 5139 `) 5140 fs["platform/Test.java"] = nil 5141 }), 5142 ) 5143 5144 checkHiddenAPIIndexFromClassesInputs := func(t *testing.T, ctx *android.TestContext, expectedIntermediateInputs string) { 5145 t.Helper() 5146 platformBootclasspath := ctx.ModuleForTests("platform-bootclasspath", "android_common") 5147 var rule android.TestingBuildParams 5148 5149 rule = platformBootclasspath.Output("hiddenapi-monolithic/index-from-classes.csv") 5150 java.CheckHiddenAPIRuleInputs(t, "intermediate index", expectedIntermediateInputs, rule) 5151 } 5152 5153 checkHiddenAPIIndexFromFlagsInputs := func(t *testing.T, ctx *android.TestContext, expectedIntermediateInputs string) { 5154 t.Helper() 5155 platformBootclasspath := ctx.ModuleForTests("platform-bootclasspath", "android_common") 5156 var rule android.TestingBuildParams 5157 5158 rule = platformBootclasspath.Output("hiddenapi-index.csv") 5159 java.CheckHiddenAPIRuleInputs(t, "monolithic index", expectedIntermediateInputs, rule) 5160 } 5161 5162 fragment := java.ApexVariantReference{ 5163 Apex: proptools.StringPtr("myapex"), 5164 Module: proptools.StringPtr("my-bootclasspath-fragment"), 5165 } 5166 5167 t.Run("prebuilt only", func(t *testing.T) { 5168 t.Parallel() 5169 bp := ` 5170 prebuilt_apex { 5171 name: "myapex", 5172 arch: { 5173 arm64: { 5174 src: "myapex-arm64.apex", 5175 }, 5176 arm: { 5177 src: "myapex-arm.apex", 5178 }, 5179 }, 5180 exported_bootclasspath_fragments: ["my-bootclasspath-fragment"], 5181 } 5182 5183 prebuilt_bootclasspath_fragment { 5184 name: "my-bootclasspath-fragment", 5185 contents: ["libfoo", "libbar"], 5186 apex_available: ["myapex"], 5187 hidden_api: { 5188 annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", 5189 metadata: "my-bootclasspath-fragment/metadata.csv", 5190 index: "my-bootclasspath-fragment/index.csv", 5191 signature_patterns: "my-bootclasspath-fragment/signature-patterns.csv", 5192 filtered_stub_flags: "my-bootclasspath-fragment/filtered-stub-flags.csv", 5193 filtered_flags: "my-bootclasspath-fragment/filtered-flags.csv", 5194 }, 5195 } 5196 5197 java_sdk_library_import { 5198 name: "libfoo", 5199 public: { 5200 jars: ["libfoo.jar"], 5201 }, 5202 apex_available: ["myapex"], 5203 shared_library: false, 5204 permitted_packages: ["foo"], 5205 } 5206 5207 java_sdk_library_import { 5208 name: "libbar", 5209 public: { 5210 jars: ["libbar.jar"], 5211 }, 5212 apex_available: ["myapex"], 5213 shared_library: false, 5214 permitted_packages: ["bar"], 5215 } 5216 ` 5217 5218 ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment) 5219 5220 // Verify the correct module jars contribute to the hiddenapi index file. 5221 checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`) 5222 checkHiddenAPIIndexFromFlagsInputs(t, ctx, ` 5223 my-bootclasspath-fragment/index.csv 5224 out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv 5225 out/soong/.intermediates/packages/modules/com.android.art/art-bootclasspath-fragment/android_common_apex10000/modular-hiddenapi/index.csv 5226 `) 5227 }) 5228 5229 t.Run("apex_set only", func(t *testing.T) { 5230 t.Parallel() 5231 bp := ` 5232 apex_set { 5233 name: "myapex", 5234 set: "myapex.apks", 5235 exported_bootclasspath_fragments: ["my-bootclasspath-fragment"], 5236 exported_systemserverclasspath_fragments: ["my-systemserverclasspath-fragment"], 5237 } 5238 5239 prebuilt_bootclasspath_fragment { 5240 name: "my-bootclasspath-fragment", 5241 contents: ["libfoo", "libbar"], 5242 apex_available: ["myapex"], 5243 hidden_api: { 5244 annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", 5245 metadata: "my-bootclasspath-fragment/metadata.csv", 5246 index: "my-bootclasspath-fragment/index.csv", 5247 signature_patterns: "my-bootclasspath-fragment/signature-patterns.csv", 5248 filtered_stub_flags: "my-bootclasspath-fragment/filtered-stub-flags.csv", 5249 filtered_flags: "my-bootclasspath-fragment/filtered-flags.csv", 5250 }, 5251 } 5252 5253 prebuilt_systemserverclasspath_fragment { 5254 name: "my-systemserverclasspath-fragment", 5255 contents: ["libbaz"], 5256 apex_available: ["myapex"], 5257 } 5258 5259 java_sdk_library_import { 5260 name: "libfoo", 5261 public: { 5262 jars: ["libfoo.jar"], 5263 }, 5264 apex_available: ["myapex"], 5265 shared_library: false, 5266 permitted_packages: ["libfoo"], 5267 } 5268 5269 5270 java_sdk_library_import { 5271 name: "libbar", 5272 public: { 5273 jars: ["libbar.jar"], 5274 }, 5275 apex_available: ["myapex"], 5276 shared_library: false, 5277 permitted_packages: ["bar"], 5278 } 5279 5280 java_sdk_library_import { 5281 name: "libbaz", 5282 public: { 5283 jars: ["libbaz.jar"], 5284 }, 5285 apex_available: ["myapex"], 5286 shared_library: false, 5287 permitted_packages: ["baz"], 5288 } 5289 ` 5290 5291 ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment) 5292 5293 // Verify the correct module jars contribute to the hiddenapi index file. 5294 checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`) 5295 checkHiddenAPIIndexFromFlagsInputs(t, ctx, ` 5296 my-bootclasspath-fragment/index.csv 5297 out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv 5298 out/soong/.intermediates/packages/modules/com.android.art/art-bootclasspath-fragment/android_common_apex10000/modular-hiddenapi/index.csv 5299 `) 5300 5301 myApex := ctx.ModuleForTests("myapex", "android_common_myapex").Module() 5302 5303 overrideNames := []string{ 5304 "", 5305 "myjavalib.myapex", 5306 "libfoo.myapex", 5307 "libbar.myapex", 5308 "libbaz.myapex", 5309 } 5310 mkEntries := android.AndroidMkEntriesForTest(t, ctx, myApex) 5311 for i, e := range mkEntries { 5312 g := e.OverrideName 5313 if w := overrideNames[i]; w != g { 5314 t.Errorf("Expected override name %q, got %q", w, g) 5315 } 5316 } 5317 5318 }) 5319 5320 t.Run("prebuilt with source library preferred", func(t *testing.T) { 5321 t.Parallel() 5322 bp := ` 5323 prebuilt_apex { 5324 name: "myapex", 5325 arch: { 5326 arm64: { 5327 src: "myapex-arm64.apex", 5328 }, 5329 arm: { 5330 src: "myapex-arm.apex", 5331 }, 5332 }, 5333 exported_bootclasspath_fragments: ["my-bootclasspath-fragment"], 5334 } 5335 5336 prebuilt_bootclasspath_fragment { 5337 name: "my-bootclasspath-fragment", 5338 contents: ["libfoo", "libbar"], 5339 apex_available: ["myapex"], 5340 hidden_api: { 5341 annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", 5342 metadata: "my-bootclasspath-fragment/metadata.csv", 5343 index: "my-bootclasspath-fragment/index.csv", 5344 stub_flags: "my-bootclasspath-fragment/stub-flags.csv", 5345 all_flags: "my-bootclasspath-fragment/all-flags.csv", 5346 }, 5347 } 5348 5349 java_import { 5350 name: "libfoo", 5351 jars: ["libfoo.jar"], 5352 apex_available: ["myapex"], 5353 sdk_version: "core_current", 5354 } 5355 5356 java_library { 5357 name: "libfoo", 5358 srcs: ["foo/bar/MyClass.java"], 5359 apex_available: ["myapex"], 5360 sdk_version: "core_current", 5361 } 5362 5363 java_sdk_library_import { 5364 name: "libbar", 5365 public: { 5366 jars: ["libbar.jar"], 5367 }, 5368 apex_available: ["myapex"], 5369 shared_library: false, 5370 } 5371 5372 java_sdk_library { 5373 name: "libbar", 5374 srcs: ["foo/bar/MyClass.java"], 5375 unsafe_ignore_missing_latest_api: true, 5376 apex_available: ["myapex"], 5377 } 5378 ` 5379 5380 // In this test the source (java_library) libfoo is active since the 5381 // prebuilt (java_import) defaults to prefer:false. However the 5382 // prebuilt_apex module always depends on the prebuilt, and so it doesn't 5383 // find the dex boot jar in it. We either need to disable the source libfoo 5384 // or make the prebuilt libfoo preferred. 5385 testDexpreoptWithApexes(t, bp, "module libfoo does not provide a dex boot jar", preparer, fragment) 5386 // dexbootjar check is skipped if AllowMissingDependencies is true 5387 preparerAllowMissingDeps := android.GroupFixturePreparers( 5388 preparer, 5389 android.PrepareForTestWithAllowMissingDependencies, 5390 ) 5391 testDexpreoptWithApexes(t, bp, "", preparerAllowMissingDeps, fragment) 5392 }) 5393 5394 t.Run("prebuilt library preferred with source", func(t *testing.T) { 5395 t.Parallel() 5396 bp := ` 5397 apex { 5398 name: "myapex", 5399 key: "myapex.key", 5400 updatable: false, 5401 bootclasspath_fragments: ["my-bootclasspath-fragment"], 5402 } 5403 5404 apex_key { 5405 name: "myapex.key", 5406 public_key: "testkey.avbpubkey", 5407 private_key: "testkey.pem", 5408 } 5409 5410 bootclasspath_fragment { 5411 name: "my-bootclasspath-fragment", 5412 contents: ["libfoo", "libbar"], 5413 apex_available: ["myapex"], 5414 hidden_api: { 5415 split_packages: ["*"], 5416 }, 5417 } 5418 5419 prebuilt_apex { 5420 name: "myapex", 5421 arch: { 5422 arm64: { 5423 src: "myapex-arm64.apex", 5424 }, 5425 arm: { 5426 src: "myapex-arm.apex", 5427 }, 5428 }, 5429 exported_bootclasspath_fragments: ["my-bootclasspath-fragment"], 5430 } 5431 5432 prebuilt_bootclasspath_fragment { 5433 name: "my-bootclasspath-fragment", 5434 prefer: true, 5435 contents: ["libfoo", "libbar"], 5436 apex_available: ["myapex"], 5437 hidden_api: { 5438 annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", 5439 metadata: "my-bootclasspath-fragment/metadata.csv", 5440 index: "my-bootclasspath-fragment/index.csv", 5441 signature_patterns: "my-bootclasspath-fragment/signature-patterns.csv", 5442 filtered_stub_flags: "my-bootclasspath-fragment/filtered-stub-flags.csv", 5443 filtered_flags: "my-bootclasspath-fragment/filtered-flags.csv", 5444 }, 5445 } 5446 5447 java_sdk_library_import { 5448 name: "libfoo", 5449 prefer: true, 5450 public: { 5451 jars: ["libfoo.jar"], 5452 }, 5453 apex_available: ["myapex"], 5454 shared_library: false, 5455 permitted_packages: ["libfoo"], 5456 } 5457 5458 java_library { 5459 name: "libfoo", 5460 srcs: ["foo/bar/MyClass.java"], 5461 apex_available: ["myapex"], 5462 installable: true, 5463 sdk_version: "core_current", 5464 } 5465 5466 java_sdk_library_import { 5467 name: "libbar", 5468 prefer: true, 5469 public: { 5470 jars: ["libbar.jar"], 5471 }, 5472 apex_available: ["myapex"], 5473 shared_library: false, 5474 permitted_packages: ["bar"], 5475 } 5476 5477 java_sdk_library { 5478 name: "libbar", 5479 srcs: ["foo/bar/MyClass.java"], 5480 unsafe_ignore_missing_latest_api: true, 5481 apex_available: ["myapex"], 5482 compile_dex: true, 5483 } 5484 ` 5485 5486 ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment) 5487 5488 // Verify the correct module jars contribute to the hiddenapi index file. 5489 checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`) 5490 checkHiddenAPIIndexFromFlagsInputs(t, ctx, ` 5491 my-bootclasspath-fragment/index.csv 5492 out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv 5493 out/soong/.intermediates/packages/modules/com.android.art/art-bootclasspath-fragment/android_common_apex10000/modular-hiddenapi/index.csv 5494 `) 5495 }) 5496 5497 t.Run("prebuilt with source apex preferred", func(t *testing.T) { 5498 t.Parallel() 5499 bp := ` 5500 apex { 5501 name: "myapex", 5502 key: "myapex.key", 5503 updatable: false, 5504 bootclasspath_fragments: ["my-bootclasspath-fragment"], 5505 } 5506 5507 apex_key { 5508 name: "myapex.key", 5509 public_key: "testkey.avbpubkey", 5510 private_key: "testkey.pem", 5511 } 5512 5513 bootclasspath_fragment { 5514 name: "my-bootclasspath-fragment", 5515 contents: ["libfoo", "libbar"], 5516 apex_available: ["myapex"], 5517 hidden_api: { 5518 split_packages: ["*"], 5519 }, 5520 } 5521 5522 prebuilt_apex { 5523 name: "myapex", 5524 arch: { 5525 arm64: { 5526 src: "myapex-arm64.apex", 5527 }, 5528 arm: { 5529 src: "myapex-arm.apex", 5530 }, 5531 }, 5532 exported_bootclasspath_fragments: ["my-bootclasspath-fragment"], 5533 } 5534 5535 prebuilt_bootclasspath_fragment { 5536 name: "my-bootclasspath-fragment", 5537 contents: ["libfoo", "libbar"], 5538 apex_available: ["myapex"], 5539 hidden_api: { 5540 annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", 5541 metadata: "my-bootclasspath-fragment/metadata.csv", 5542 index: "my-bootclasspath-fragment/index.csv", 5543 signature_patterns: "my-bootclasspath-fragment/signature-patterns.csv", 5544 filtered_stub_flags: "my-bootclasspath-fragment/filtered-stub-flags.csv", 5545 filtered_flags: "my-bootclasspath-fragment/filtered-flags.csv", 5546 }, 5547 } 5548 5549 java_import { 5550 name: "libfoo", 5551 jars: ["libfoo.jar"], 5552 apex_available: ["myapex"], 5553 sdk_version: "core_current", 5554 } 5555 5556 java_library { 5557 name: "libfoo", 5558 srcs: ["foo/bar/MyClass.java"], 5559 apex_available: ["myapex"], 5560 permitted_packages: ["foo"], 5561 installable: true, 5562 sdk_version: "core_current", 5563 } 5564 5565 java_sdk_library_import { 5566 name: "libbar", 5567 public: { 5568 jars: ["libbar.jar"], 5569 }, 5570 apex_available: ["myapex"], 5571 shared_library: false, 5572 } 5573 5574 java_sdk_library { 5575 name: "libbar", 5576 srcs: ["foo/bar/MyClass.java"], 5577 unsafe_ignore_missing_latest_api: true, 5578 apex_available: ["myapex"], 5579 permitted_packages: ["bar"], 5580 compile_dex: true, 5581 sdk_version: "core_current", 5582 } 5583 ` 5584 5585 ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment) 5586 5587 // Verify the correct module jars contribute to the hiddenapi index file. 5588 checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`) 5589 checkHiddenAPIIndexFromFlagsInputs(t, ctx, ` 5590 out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv 5591 out/soong/.intermediates/my-bootclasspath-fragment/android_common_myapex/modular-hiddenapi/index.csv 5592 out/soong/.intermediates/packages/modules/com.android.art/art-bootclasspath-fragment/android_common_apex10000/modular-hiddenapi/index.csv 5593 `) 5594 }) 5595 5596 t.Run("prebuilt preferred with source apex disabled", func(t *testing.T) { 5597 t.Parallel() 5598 bp := ` 5599 apex { 5600 name: "myapex", 5601 enabled: false, 5602 key: "myapex.key", 5603 bootclasspath_fragments: ["my-bootclasspath-fragment"], 5604 } 5605 5606 apex_key { 5607 name: "myapex.key", 5608 public_key: "testkey.avbpubkey", 5609 private_key: "testkey.pem", 5610 } 5611 5612 bootclasspath_fragment { 5613 name: "my-bootclasspath-fragment", 5614 enabled: false, 5615 contents: ["libfoo", "libbar"], 5616 apex_available: ["myapex"], 5617 hidden_api: { 5618 split_packages: ["*"], 5619 }, 5620 } 5621 5622 prebuilt_apex { 5623 name: "myapex", 5624 arch: { 5625 arm64: { 5626 src: "myapex-arm64.apex", 5627 }, 5628 arm: { 5629 src: "myapex-arm.apex", 5630 }, 5631 }, 5632 exported_bootclasspath_fragments: ["my-bootclasspath-fragment"], 5633 } 5634 5635 prebuilt_bootclasspath_fragment { 5636 name: "my-bootclasspath-fragment", 5637 contents: ["libfoo", "libbar"], 5638 apex_available: ["myapex"], 5639 hidden_api: { 5640 annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", 5641 metadata: "my-bootclasspath-fragment/metadata.csv", 5642 index: "my-bootclasspath-fragment/index.csv", 5643 signature_patterns: "my-bootclasspath-fragment/signature-patterns.csv", 5644 filtered_stub_flags: "my-bootclasspath-fragment/filtered-stub-flags.csv", 5645 filtered_flags: "my-bootclasspath-fragment/filtered-flags.csv", 5646 }, 5647 } 5648 5649 java_import { 5650 name: "libfoo", 5651 jars: ["libfoo.jar"], 5652 apex_available: ["myapex"], 5653 permitted_packages: ["foo"], 5654 } 5655 5656 java_library { 5657 name: "libfoo", 5658 enabled: false, 5659 srcs: ["foo/bar/MyClass.java"], 5660 apex_available: ["myapex"], 5661 installable: true, 5662 } 5663 5664 java_sdk_library_import { 5665 name: "libbar", 5666 public: { 5667 jars: ["libbar.jar"], 5668 }, 5669 apex_available: ["myapex"], 5670 shared_library: false, 5671 permitted_packages: ["bar"], 5672 prefer: true, 5673 } 5674 5675 java_sdk_library { 5676 name: "libbar", 5677 srcs: ["foo/bar/MyClass.java"], 5678 unsafe_ignore_missing_latest_api: true, 5679 apex_available: ["myapex"], 5680 compile_dex: true, 5681 } 5682 ` 5683 // This test disables libbar, which causes the ComponentDepsMutator to add 5684 // deps on libbar.stubs and other sub-modules that don't exist. We can 5685 // enable AllowMissingDependencies to work around that, but enabling that 5686 // causes extra checks for missing source files to dex_bootjars, so add those 5687 // to the mock fs as well. 5688 preparer2 := android.GroupFixturePreparers( 5689 preparer, 5690 android.PrepareForTestWithAllowMissingDependencies, 5691 android.FixtureMergeMockFs(map[string][]byte{ 5692 "build/soong/scripts/check_boot_jars/package_allowed_list.txt": nil, 5693 "frameworks/base/boot/boot-profile.txt": nil, 5694 }), 5695 ) 5696 5697 ctx := testDexpreoptWithApexes(t, bp, "", preparer2, fragment) 5698 5699 // Verify the correct module jars contribute to the hiddenapi index file. 5700 checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`) 5701 checkHiddenAPIIndexFromFlagsInputs(t, ctx, ` 5702 my-bootclasspath-fragment/index.csv 5703 out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv 5704 out/soong/.intermediates/packages/modules/com.android.art/art-bootclasspath-fragment/android_common_apex10000/modular-hiddenapi/index.csv 5705 `) 5706 }) 5707 5708 t.Run("Co-existing unflagged apexes should create a duplicate module error", func(t *testing.T) { 5709 t.Parallel() 5710 bp := ` 5711 // Source 5712 apex { 5713 name: "myapex", 5714 enabled: false, 5715 key: "myapex.key", 5716 bootclasspath_fragments: ["my-bootclasspath-fragment"], 5717 } 5718 5719 apex_key { 5720 name: "myapex.key", 5721 public_key: "testkey.avbpubkey", 5722 private_key: "testkey.pem", 5723 } 5724 5725 // Prebuilt 5726 prebuilt_apex { 5727 name: "myapex.v1", 5728 source_apex_name: "myapex", 5729 arch: { 5730 arm64: { 5731 src: "myapex-arm64.apex", 5732 }, 5733 arm: { 5734 src: "myapex-arm.apex", 5735 }, 5736 }, 5737 exported_bootclasspath_fragments: ["my-bootclasspath-fragment"], 5738 prefer: true, 5739 } 5740 prebuilt_apex { 5741 name: "myapex.v2", 5742 source_apex_name: "myapex", 5743 arch: { 5744 arm64: { 5745 src: "myapex-arm64.apex", 5746 }, 5747 arm: { 5748 src: "myapex-arm.apex", 5749 }, 5750 }, 5751 exported_bootclasspath_fragments: ["my-bootclasspath-fragment"], 5752 prefer: true, 5753 } 5754 5755 prebuilt_bootclasspath_fragment { 5756 name: "my-bootclasspath-fragment", 5757 contents: ["libfoo", "libbar"], 5758 apex_available: ["myapex"], 5759 hidden_api: { 5760 annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", 5761 metadata: "my-bootclasspath-fragment/metadata.csv", 5762 index: "my-bootclasspath-fragment/index.csv", 5763 stub_flags: "my-bootclasspath-fragment/stub-flags.csv", 5764 all_flags: "my-bootclasspath-fragment/all-flags.csv", 5765 }, 5766 prefer: true, 5767 } 5768 5769 java_import { 5770 name: "libfoo", 5771 jars: ["libfoo.jar"], 5772 apex_available: ["myapex"], 5773 prefer: true, 5774 } 5775 java_import { 5776 name: "libbar", 5777 jars: ["libbar.jar"], 5778 apex_available: ["myapex"], 5779 prefer: true, 5780 } 5781 ` 5782 5783 testDexpreoptWithApexes(t, bp, "Multiple prebuilt modules prebuilt_myapex.v1 and prebuilt_myapex.v2 have been marked as preferred for this source module", preparer, fragment) 5784 }) 5785 5786} 5787 5788func TestApexWithTests(t *testing.T) { 5789 t.Parallel() 5790 ctx := testApex(t, ` 5791 apex_test { 5792 name: "myapex", 5793 key: "myapex.key", 5794 updatable: false, 5795 tests: [ 5796 "mytest", 5797 ], 5798 } 5799 5800 apex_key { 5801 name: "myapex.key", 5802 public_key: "testkey.avbpubkey", 5803 private_key: "testkey.pem", 5804 } 5805 5806 filegroup { 5807 name: "fg", 5808 srcs: [ 5809 "baz", 5810 "bar/baz" 5811 ], 5812 } 5813 5814 cc_test { 5815 name: "mytest", 5816 gtest: false, 5817 srcs: ["mytest.cpp"], 5818 relative_install_path: "test", 5819 shared_libs: ["mylib"], 5820 system_shared_libs: [], 5821 static_executable: true, 5822 stl: "none", 5823 data: [":fg"], 5824 } 5825 5826 cc_library { 5827 name: "mylib", 5828 srcs: ["mylib.cpp"], 5829 system_shared_libs: [], 5830 stl: "none", 5831 } 5832 5833 filegroup { 5834 name: "fg2", 5835 srcs: [ 5836 "testdata/baz" 5837 ], 5838 } 5839 `) 5840 5841 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule") 5842 copyCmds := apexRule.Args["copy_commands"] 5843 5844 // Ensure that test dep (and their transitive dependencies) are copied into apex. 5845 ensureContains(t, copyCmds, "image.apex/bin/test/mytest") 5846 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") 5847 5848 //Ensure that test data are copied into apex. 5849 ensureContains(t, copyCmds, "image.apex/bin/test/baz") 5850 ensureContains(t, copyCmds, "image.apex/bin/test/bar/baz") 5851 5852 // Ensure the module is correctly translated. 5853 bundle := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle) 5854 data := android.AndroidMkDataForTest(t, ctx, bundle) 5855 name := bundle.BaseModuleName() 5856 prefix := "TARGET_" 5857 var builder strings.Builder 5858 data.Custom(&builder, name, prefix, "", data) 5859 androidMk := builder.String() 5860 ensureContains(t, androidMk, "LOCAL_MODULE := mytest.myapex\n") 5861 ensureContains(t, androidMk, "LOCAL_MODULE := myapex\n") 5862} 5863 5864func TestErrorsIfDepsAreNotEnabled(t *testing.T) { 5865 t.Parallel() 5866 testApexError(t, `module "myapex" .* depends on disabled module "libfoo"`, ` 5867 apex { 5868 name: "myapex", 5869 key: "myapex.key", 5870 native_shared_libs: ["libfoo"], 5871 } 5872 5873 apex_key { 5874 name: "myapex.key", 5875 public_key: "testkey.avbpubkey", 5876 private_key: "testkey.pem", 5877 } 5878 5879 cc_library { 5880 name: "libfoo", 5881 stl: "none", 5882 system_shared_libs: [], 5883 enabled: false, 5884 apex_available: ["myapex"], 5885 } 5886 `) 5887 testApexError(t, `module "myapex" .* depends on disabled module "myjar"`, ` 5888 apex { 5889 name: "myapex", 5890 key: "myapex.key", 5891 java_libs: ["myjar"], 5892 } 5893 5894 apex_key { 5895 name: "myapex.key", 5896 public_key: "testkey.avbpubkey", 5897 private_key: "testkey.pem", 5898 } 5899 5900 java_library { 5901 name: "myjar", 5902 srcs: ["foo/bar/MyClass.java"], 5903 sdk_version: "none", 5904 system_modules: "none", 5905 enabled: false, 5906 apex_available: ["myapex"], 5907 compile_dex: true, 5908 } 5909 `) 5910} 5911 5912func TestApexWithJavaImport(t *testing.T) { 5913 ctx := testApex(t, ` 5914 apex { 5915 name: "myapex", 5916 key: "myapex.key", 5917 java_libs: ["myjavaimport"], 5918 updatable: false, 5919 } 5920 5921 apex_key { 5922 name: "myapex.key", 5923 public_key: "testkey.avbpubkey", 5924 private_key: "testkey.pem", 5925 } 5926 5927 java_import { 5928 name: "myjavaimport", 5929 apex_available: ["myapex"], 5930 jars: ["my.jar"], 5931 compile_dex: true, 5932 } 5933 `) 5934 5935 module := ctx.ModuleForTests("myapex", "android_common_myapex") 5936 apexRule := module.Rule("apexRule") 5937 copyCmds := apexRule.Args["copy_commands"] 5938 ensureContains(t, copyCmds, "image.apex/javalib/myjavaimport.jar") 5939} 5940 5941func TestApexWithApps(t *testing.T) { 5942 t.Parallel() 5943 ctx := testApex(t, ` 5944 apex { 5945 name: "myapex", 5946 key: "myapex.key", 5947 apps: [ 5948 "AppFoo", 5949 "AppFooPriv", 5950 ], 5951 updatable: false, 5952 } 5953 5954 apex_key { 5955 name: "myapex.key", 5956 public_key: "testkey.avbpubkey", 5957 private_key: "testkey.pem", 5958 } 5959 5960 android_app { 5961 name: "AppFoo", 5962 srcs: ["foo/bar/MyClass.java"], 5963 sdk_version: "current", 5964 system_modules: "none", 5965 use_embedded_native_libs: true, 5966 jni_libs: ["libjni"], 5967 stl: "none", 5968 apex_available: [ "myapex" ], 5969 } 5970 5971 android_app { 5972 name: "AppFooPriv", 5973 srcs: ["foo/bar/MyClass.java"], 5974 sdk_version: "current", 5975 system_modules: "none", 5976 privileged: true, 5977 privapp_allowlist: "privapp_allowlist_com.android.AppFooPriv.xml", 5978 stl: "none", 5979 apex_available: [ "myapex" ], 5980 } 5981 5982 cc_library_shared { 5983 name: "libjni", 5984 srcs: ["mylib.cpp"], 5985 shared_libs: ["libfoo"], 5986 stl: "none", 5987 system_shared_libs: [], 5988 apex_available: [ "myapex" ], 5989 sdk_version: "current", 5990 } 5991 5992 cc_library_shared { 5993 name: "libfoo", 5994 stl: "none", 5995 system_shared_libs: [], 5996 apex_available: [ "myapex" ], 5997 sdk_version: "current", 5998 } 5999 `) 6000 6001 module := ctx.ModuleForTests("myapex", "android_common_myapex") 6002 apexRule := module.Rule("apexRule") 6003 copyCmds := apexRule.Args["copy_commands"] 6004 6005 ensureContains(t, copyCmds, "image.apex/app/AppFoo@TEST.BUILD_ID/AppFoo.apk") 6006 ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPriv@TEST.BUILD_ID/AppFooPriv.apk") 6007 ensureContains(t, copyCmds, "image.apex/etc/permissions/privapp_allowlist_com.android.AppFooPriv.xml") 6008 6009 appZipRule := ctx.ModuleForTests("AppFoo", "android_common_apex10000").Description("zip jni libs") 6010 // JNI libraries are uncompressed 6011 if args := appZipRule.Args["jarArgs"]; !strings.Contains(args, "-L 0") { 6012 t.Errorf("jni libs are not uncompressed for AppFoo") 6013 } 6014 // JNI libraries including transitive deps are 6015 for _, jni := range []string{"libjni", "libfoo"} { 6016 jniOutput := ctx.ModuleForTests(jni, "android_arm64_armv8-a_sdk_shared_apex10000").Module().(*cc.Module).OutputFile().RelativeToTop() 6017 // ... embedded inside APK (jnilibs.zip) 6018 ensureListContains(t, appZipRule.Implicits.Strings(), jniOutput.String()) 6019 // ... and not directly inside the APEX 6020 ensureNotContains(t, copyCmds, "image.apex/lib64/"+jni+".so") 6021 } 6022 6023 apexBundle := module.Module().(*apexBundle) 6024 data := android.AndroidMkDataForTest(t, ctx, apexBundle) 6025 var builder strings.Builder 6026 data.Custom(&builder, apexBundle.Name(), "TARGET_", "", data) 6027 androidMk := builder.String() 6028 ensureContains(t, androidMk, "LOCAL_MODULE := AppFooPriv.myapex") 6029 ensureContains(t, androidMk, "LOCAL_MODULE := AppFoo.myapex") 6030 ensureMatches(t, androidMk, "LOCAL_SOONG_INSTALLED_MODULE := \\S+AppFooPriv.apk") 6031 ensureMatches(t, androidMk, "LOCAL_SOONG_INSTALLED_MODULE := \\S+AppFoo.apk") 6032 ensureMatches(t, androidMk, "LOCAL_SOONG_INSTALL_PAIRS := \\S+AppFooPriv.apk") 6033 ensureContains(t, androidMk, "LOCAL_SOONG_INSTALL_PAIRS := privapp_allowlist_com.android.AppFooPriv.xml:$(PRODUCT_OUT)/apex/myapex/etc/permissions/privapp_allowlist_com.android.AppFooPriv.xml") 6034} 6035 6036func TestApexWithAppImportBuildId(t *testing.T) { 6037 t.Parallel() 6038 invalidBuildIds := []string{"../", "a b", "a/b", "a/b/../c", "/a"} 6039 for _, id := range invalidBuildIds { 6040 message := fmt.Sprintf("Unable to use build id %s as filename suffix", id) 6041 fixture := android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 6042 variables.BuildId = proptools.StringPtr(id) 6043 }) 6044 testApexError(t, message, `apex { 6045 name: "myapex", 6046 key: "myapex.key", 6047 apps: ["AppFooPrebuilt"], 6048 updatable: false, 6049 } 6050 6051 apex_key { 6052 name: "myapex.key", 6053 public_key: "testkey.avbpubkey", 6054 private_key: "testkey.pem", 6055 } 6056 6057 android_app_import { 6058 name: "AppFooPrebuilt", 6059 apk: "PrebuiltAppFoo.apk", 6060 presigned: true, 6061 apex_available: ["myapex"], 6062 } 6063 `, fixture) 6064 } 6065} 6066 6067func TestApexWithAppImports(t *testing.T) { 6068 t.Parallel() 6069 ctx := testApex(t, ` 6070 apex { 6071 name: "myapex", 6072 key: "myapex.key", 6073 apps: [ 6074 "AppFooPrebuilt", 6075 "AppFooPrivPrebuilt", 6076 ], 6077 updatable: false, 6078 } 6079 6080 apex_key { 6081 name: "myapex.key", 6082 public_key: "testkey.avbpubkey", 6083 private_key: "testkey.pem", 6084 } 6085 6086 android_app_import { 6087 name: "AppFooPrebuilt", 6088 apk: "PrebuiltAppFoo.apk", 6089 presigned: true, 6090 dex_preopt: { 6091 enabled: false, 6092 }, 6093 apex_available: ["myapex"], 6094 } 6095 6096 android_app_import { 6097 name: "AppFooPrivPrebuilt", 6098 apk: "PrebuiltAppFooPriv.apk", 6099 privileged: true, 6100 presigned: true, 6101 dex_preopt: { 6102 enabled: false, 6103 }, 6104 filename: "AwesomePrebuiltAppFooPriv.apk", 6105 apex_available: ["myapex"], 6106 } 6107 `) 6108 6109 module := ctx.ModuleForTests("myapex", "android_common_myapex") 6110 apexRule := module.Rule("apexRule") 6111 copyCmds := apexRule.Args["copy_commands"] 6112 6113 ensureContains(t, copyCmds, "image.apex/app/AppFooPrebuilt@TEST.BUILD_ID/AppFooPrebuilt.apk") 6114 ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPrivPrebuilt@TEST.BUILD_ID/AwesomePrebuiltAppFooPriv.apk") 6115} 6116 6117func TestApexWithAppImportsPrefer(t *testing.T) { 6118 t.Parallel() 6119 ctx := testApex(t, ` 6120 apex { 6121 name: "myapex", 6122 key: "myapex.key", 6123 apps: [ 6124 "AppFoo", 6125 ], 6126 updatable: false, 6127 } 6128 6129 apex_key { 6130 name: "myapex.key", 6131 public_key: "testkey.avbpubkey", 6132 private_key: "testkey.pem", 6133 } 6134 6135 android_app { 6136 name: "AppFoo", 6137 srcs: ["foo/bar/MyClass.java"], 6138 sdk_version: "none", 6139 system_modules: "none", 6140 apex_available: [ "myapex" ], 6141 } 6142 6143 android_app_import { 6144 name: "AppFoo", 6145 apk: "AppFooPrebuilt.apk", 6146 filename: "AppFooPrebuilt.apk", 6147 presigned: true, 6148 prefer: true, 6149 apex_available: ["myapex"], 6150 } 6151 `, withFiles(map[string][]byte{ 6152 "AppFooPrebuilt.apk": nil, 6153 })) 6154 6155 ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{ 6156 "app/AppFoo@TEST.BUILD_ID/AppFooPrebuilt.apk", 6157 }) 6158} 6159 6160func TestApexWithTestHelperApp(t *testing.T) { 6161 t.Parallel() 6162 ctx := testApex(t, ` 6163 apex { 6164 name: "myapex", 6165 key: "myapex.key", 6166 apps: [ 6167 "TesterHelpAppFoo", 6168 ], 6169 updatable: false, 6170 } 6171 6172 apex_key { 6173 name: "myapex.key", 6174 public_key: "testkey.avbpubkey", 6175 private_key: "testkey.pem", 6176 } 6177 6178 android_test_helper_app { 6179 name: "TesterHelpAppFoo", 6180 srcs: ["foo/bar/MyClass.java"], 6181 apex_available: [ "myapex" ], 6182 sdk_version: "test_current", 6183 } 6184 6185 `) 6186 6187 module := ctx.ModuleForTests("myapex", "android_common_myapex") 6188 apexRule := module.Rule("apexRule") 6189 copyCmds := apexRule.Args["copy_commands"] 6190 6191 ensureContains(t, copyCmds, "image.apex/app/TesterHelpAppFoo@TEST.BUILD_ID/TesterHelpAppFoo.apk") 6192} 6193 6194func TestApexPropertiesShouldBeDefaultable(t *testing.T) { 6195 t.Parallel() 6196 // libfoo's apex_available comes from cc_defaults 6197 testApexError(t, `requires "libfoo" that doesn't list the APEX under 'apex_available'.`, ` 6198 apex { 6199 name: "myapex", 6200 key: "myapex.key", 6201 native_shared_libs: ["libfoo"], 6202 updatable: false, 6203 } 6204 6205 apex_key { 6206 name: "myapex.key", 6207 public_key: "testkey.avbpubkey", 6208 private_key: "testkey.pem", 6209 } 6210 6211 apex { 6212 name: "otherapex", 6213 key: "myapex.key", 6214 native_shared_libs: ["libfoo"], 6215 updatable: false, 6216 } 6217 6218 cc_defaults { 6219 name: "libfoo-defaults", 6220 apex_available: ["otherapex"], 6221 } 6222 6223 cc_library { 6224 name: "libfoo", 6225 defaults: ["libfoo-defaults"], 6226 stl: "none", 6227 system_shared_libs: [], 6228 }`) 6229} 6230 6231func TestApexAvailable_DirectDep(t *testing.T) { 6232 t.Parallel() 6233 // libfoo is not available to myapex, but only to otherapex 6234 testApexError(t, "requires \"libfoo\" that doesn't list the APEX under 'apex_available'.", ` 6235 apex { 6236 name: "myapex", 6237 key: "myapex.key", 6238 native_shared_libs: ["libfoo"], 6239 updatable: false, 6240 } 6241 6242 apex_key { 6243 name: "myapex.key", 6244 public_key: "testkey.avbpubkey", 6245 private_key: "testkey.pem", 6246 } 6247 6248 apex { 6249 name: "otherapex", 6250 key: "otherapex.key", 6251 native_shared_libs: ["libfoo"], 6252 updatable: false, 6253 } 6254 6255 apex_key { 6256 name: "otherapex.key", 6257 public_key: "testkey.avbpubkey", 6258 private_key: "testkey.pem", 6259 } 6260 6261 cc_library { 6262 name: "libfoo", 6263 stl: "none", 6264 system_shared_libs: [], 6265 apex_available: ["otherapex"], 6266 }`) 6267 6268 // 'apex_available' check is bypassed for /product apex with a specific prefix. 6269 // TODO: b/352818241 - Remove below two cases after APEX availability is enforced for /product APEXes. 6270 testApex(t, ` 6271 apex { 6272 name: "com.sdv.myapex", 6273 key: "myapex.key", 6274 native_shared_libs: ["libfoo"], 6275 updatable: false, 6276 product_specific: true, 6277 } 6278 6279 apex_key { 6280 name: "myapex.key", 6281 public_key: "testkey.avbpubkey", 6282 private_key: "testkey.pem", 6283 } 6284 6285 apex { 6286 name: "com.any.otherapex", 6287 key: "otherapex.key", 6288 native_shared_libs: ["libfoo"], 6289 updatable: false, 6290 } 6291 6292 apex_key { 6293 name: "otherapex.key", 6294 public_key: "testkey.avbpubkey", 6295 private_key: "testkey.pem", 6296 } 6297 6298 cc_library { 6299 name: "libfoo", 6300 stl: "none", 6301 system_shared_libs: [], 6302 apex_available: ["com.any.otherapex"], 6303 product_specific: true, 6304 }`, 6305 android.FixtureMergeMockFs(android.MockFS{ 6306 "system/sepolicy/apex/com.sdv.myapex-file_contexts": nil, 6307 "system/sepolicy/apex/com.any.otherapex-file_contexts": nil, 6308 })) 6309 6310 // 'apex_available' check is not bypassed for non-product apex with a specific prefix. 6311 testApexError(t, "requires \"libfoo\" that doesn't list the APEX under 'apex_available'.", ` 6312 apex { 6313 name: "com.sdv.myapex", 6314 key: "myapex.key", 6315 native_shared_libs: ["libfoo"], 6316 updatable: false, 6317 } 6318 6319 apex_key { 6320 name: "myapex.key", 6321 public_key: "testkey.avbpubkey", 6322 private_key: "testkey.pem", 6323 } 6324 6325 apex { 6326 name: "com.any.otherapex", 6327 key: "otherapex.key", 6328 native_shared_libs: ["libfoo"], 6329 updatable: false, 6330 } 6331 6332 apex_key { 6333 name: "otherapex.key", 6334 public_key: "testkey.avbpubkey", 6335 private_key: "testkey.pem", 6336 } 6337 6338 cc_library { 6339 name: "libfoo", 6340 stl: "none", 6341 system_shared_libs: [], 6342 apex_available: ["com.any.otherapex"], 6343 }`, 6344 android.FixtureMergeMockFs(android.MockFS{ 6345 "system/sepolicy/apex/com.sdv.myapex-file_contexts": nil, 6346 "system/sepolicy/apex/com.any.otherapex-file_contexts": nil, 6347 })) 6348} 6349 6350func TestApexAvailable_IndirectDep(t *testing.T) { 6351 t.Parallel() 6352 // libbbaz is an indirect dep 6353 testApexError(t, `requires "libbaz" that doesn't list the APEX under 'apex_available'.\n\nDependency path: 6354.*via tag apex\.dependencyTag\{"sharedLib"\} 6355.*-> libfoo.*link:shared.* 6356.*via tag cc\.libraryDependencyTag.*Kind:sharedLibraryDependency.* 6357.*-> libbar.*link:shared.* 6358.*via tag cc\.libraryDependencyTag.*Kind:sharedLibraryDependency.* 6359.*-> libbaz.*link:shared.*`, ` 6360 apex { 6361 name: "myapex", 6362 key: "myapex.key", 6363 native_shared_libs: ["libfoo"], 6364 updatable: false, 6365 } 6366 6367 apex_key { 6368 name: "myapex.key", 6369 public_key: "testkey.avbpubkey", 6370 private_key: "testkey.pem", 6371 } 6372 6373 cc_library { 6374 name: "libfoo", 6375 stl: "none", 6376 shared_libs: ["libbar"], 6377 system_shared_libs: [], 6378 apex_available: ["myapex"], 6379 } 6380 6381 cc_library { 6382 name: "libbar", 6383 stl: "none", 6384 shared_libs: ["libbaz"], 6385 system_shared_libs: [], 6386 apex_available: ["myapex"], 6387 } 6388 6389 cc_library { 6390 name: "libbaz", 6391 stl: "none", 6392 system_shared_libs: [], 6393 }`) 6394 6395 // 'apex_available' check is bypassed for /product apex with a specific prefix. 6396 // TODO: b/352818241 - Remove below two cases after APEX availability is enforced for /product APEXes. 6397 testApex(t, ` 6398 apex { 6399 name: "com.sdv.myapex", 6400 key: "myapex.key", 6401 native_shared_libs: ["libfoo"], 6402 updatable: false, 6403 product_specific: true, 6404 } 6405 6406 apex_key { 6407 name: "myapex.key", 6408 public_key: "testkey.avbpubkey", 6409 private_key: "testkey.pem", 6410 } 6411 6412 cc_library { 6413 name: "libfoo", 6414 stl: "none", 6415 shared_libs: ["libbar"], 6416 system_shared_libs: [], 6417 apex_available: ["com.sdv.myapex"], 6418 product_specific: true, 6419 } 6420 6421 cc_library { 6422 name: "libbar", 6423 stl: "none", 6424 shared_libs: ["libbaz"], 6425 system_shared_libs: [], 6426 apex_available: ["com.sdv.myapex"], 6427 product_specific: true, 6428 } 6429 6430 cc_library { 6431 name: "libbaz", 6432 stl: "none", 6433 system_shared_libs: [], 6434 product_specific: true, 6435 }`, 6436 android.FixtureMergeMockFs(android.MockFS{ 6437 "system/sepolicy/apex/com.sdv.myapex-file_contexts": nil, 6438 })) 6439 6440 // 'apex_available' check is not bypassed for non-product apex with a specific prefix. 6441 testApexError(t, `requires "libbaz" that doesn't list the APEX under 'apex_available'.`, ` 6442 apex { 6443 name: "com.sdv.myapex", 6444 key: "myapex.key", 6445 native_shared_libs: ["libfoo"], 6446 updatable: false, 6447 } 6448 6449 apex_key { 6450 name: "myapex.key", 6451 public_key: "testkey.avbpubkey", 6452 private_key: "testkey.pem", 6453 } 6454 6455 cc_library { 6456 name: "libfoo", 6457 stl: "none", 6458 shared_libs: ["libbar"], 6459 system_shared_libs: [], 6460 apex_available: ["com.sdv.myapex"], 6461 } 6462 6463 cc_library { 6464 name: "libbar", 6465 stl: "none", 6466 shared_libs: ["libbaz"], 6467 system_shared_libs: [], 6468 apex_available: ["com.sdv.myapex"], 6469 } 6470 6471 cc_library { 6472 name: "libbaz", 6473 stl: "none", 6474 system_shared_libs: [], 6475 }`, 6476 android.FixtureMergeMockFs(android.MockFS{ 6477 "system/sepolicy/apex/com.sdv.myapex-file_contexts": nil, 6478 })) 6479} 6480 6481func TestApexAvailable_IndirectStaticDep(t *testing.T) { 6482 t.Parallel() 6483 testApex(t, ` 6484 apex { 6485 name: "myapex", 6486 key: "myapex.key", 6487 native_shared_libs: ["libfoo"], 6488 updatable: false, 6489 } 6490 6491 apex_key { 6492 name: "myapex.key", 6493 public_key: "testkey.avbpubkey", 6494 private_key: "testkey.pem", 6495 } 6496 6497 cc_library { 6498 name: "libfoo", 6499 stl: "none", 6500 static_libs: ["libbar"], 6501 system_shared_libs: [], 6502 apex_available: ["myapex"], 6503 } 6504 6505 cc_library { 6506 name: "libbar", 6507 stl: "none", 6508 shared_libs: ["libbaz"], 6509 system_shared_libs: [], 6510 apex_available: ["myapex"], 6511 } 6512 6513 cc_library { 6514 name: "libbaz", 6515 stl: "none", 6516 system_shared_libs: [], 6517 }`) 6518 6519 testApexError(t, `requires "libbar" that doesn't list the APEX under 'apex_available'.`, ` 6520 apex { 6521 name: "myapex", 6522 key: "myapex.key", 6523 native_shared_libs: ["libfoo"], 6524 updatable: false, 6525 } 6526 6527 apex_key { 6528 name: "myapex.key", 6529 public_key: "testkey.avbpubkey", 6530 private_key: "testkey.pem", 6531 } 6532 6533 cc_library { 6534 name: "libfoo", 6535 stl: "none", 6536 static_libs: ["libbar"], 6537 system_shared_libs: [], 6538 apex_available: ["myapex"], 6539 } 6540 6541 cc_library { 6542 name: "libbar", 6543 stl: "none", 6544 system_shared_libs: [], 6545 }`) 6546} 6547 6548func TestApexAvailable_InvalidApexName(t *testing.T) { 6549 t.Parallel() 6550 testApexError(t, "\"otherapex\" is not a valid module name", ` 6551 apex { 6552 name: "myapex", 6553 key: "myapex.key", 6554 native_shared_libs: ["libfoo"], 6555 updatable: false, 6556 } 6557 6558 apex_key { 6559 name: "myapex.key", 6560 public_key: "testkey.avbpubkey", 6561 private_key: "testkey.pem", 6562 } 6563 6564 cc_library { 6565 name: "libfoo", 6566 stl: "none", 6567 system_shared_libs: [], 6568 apex_available: ["otherapex"], 6569 }`) 6570 6571 testApex(t, ` 6572 apex { 6573 name: "myapex", 6574 key: "myapex.key", 6575 native_shared_libs: ["libfoo", "libbar"], 6576 updatable: false, 6577 } 6578 6579 apex_key { 6580 name: "myapex.key", 6581 public_key: "testkey.avbpubkey", 6582 private_key: "testkey.pem", 6583 } 6584 6585 cc_library { 6586 name: "libfoo", 6587 stl: "none", 6588 system_shared_libs: [], 6589 runtime_libs: ["libbaz"], 6590 apex_available: ["myapex"], 6591 } 6592 6593 cc_library { 6594 name: "libbar", 6595 stl: "none", 6596 system_shared_libs: [], 6597 apex_available: ["//apex_available:anyapex"], 6598 } 6599 6600 cc_library { 6601 name: "libbaz", 6602 stl: "none", 6603 system_shared_libs: [], 6604 stubs: { 6605 versions: ["10", "20", "30"], 6606 }, 6607 }`) 6608} 6609 6610func TestApexAvailable_ApexAvailableNameWithVersionCodeError(t *testing.T) { 6611 t.Parallel() 6612 t.Run("negative variant_version produces error", func(t *testing.T) { 6613 t.Parallel() 6614 testApexError(t, "expected an integer between 0-9; got -1", ` 6615 apex { 6616 name: "myapex", 6617 key: "myapex.key", 6618 apex_available_name: "com.android.foo", 6619 variant_version: "-1", 6620 updatable: false, 6621 } 6622 apex_key { 6623 name: "myapex.key", 6624 public_key: "testkey.avbpubkey", 6625 private_key: "testkey.pem", 6626 } 6627 `) 6628 }) 6629 6630 t.Run("variant_version greater than 9 produces error", func(t *testing.T) { 6631 t.Parallel() 6632 testApexError(t, "expected an integer between 0-9; got 10", ` 6633 apex { 6634 name: "myapex", 6635 key: "myapex.key", 6636 apex_available_name: "com.android.foo", 6637 variant_version: "10", 6638 updatable: false, 6639 } 6640 apex_key { 6641 name: "myapex.key", 6642 public_key: "testkey.avbpubkey", 6643 private_key: "testkey.pem", 6644 } 6645 `) 6646 }) 6647} 6648 6649func TestApexAvailable_ApexAvailableNameWithVersionCode(t *testing.T) { 6650 t.Parallel() 6651 context := android.GroupFixturePreparers( 6652 android.PrepareForIntegrationTestWithAndroid, 6653 PrepareForTestWithApexBuildComponents, 6654 android.FixtureMergeMockFs(android.MockFS{ 6655 "system/sepolicy/apex/foo-file_contexts": nil, 6656 "system/sepolicy/apex/bar-file_contexts": nil, 6657 }), 6658 ) 6659 result := context.RunTestWithBp(t, ` 6660 apex { 6661 name: "foo", 6662 key: "myapex.key", 6663 apex_available_name: "com.android.foo", 6664 variant_version: "0", 6665 updatable: false, 6666 } 6667 apex { 6668 name: "bar", 6669 key: "myapex.key", 6670 apex_available_name: "com.android.foo", 6671 variant_version: "3", 6672 updatable: false, 6673 } 6674 apex_key { 6675 name: "myapex.key", 6676 public_key: "testkey.avbpubkey", 6677 private_key: "testkey.pem", 6678 } 6679 override_apex { 6680 name: "myoverrideapex", 6681 base: "bar", 6682 } 6683 `) 6684 6685 fooManifestRule := result.ModuleForTests("foo", "android_common_foo").Rule("apexManifestRule") 6686 fooExpectedDefaultVersion := testDefaultUpdatableModuleVersion 6687 fooActualDefaultVersion := fooManifestRule.Args["default_version"] 6688 if fooActualDefaultVersion != fooExpectedDefaultVersion { 6689 t.Errorf("expected to find defaultVersion %q; got %q", fooExpectedDefaultVersion, fooActualDefaultVersion) 6690 } 6691 6692 barManifestRule := result.ModuleForTests("bar", "android_common_bar").Rule("apexManifestRule") 6693 defaultVersionInt, _ := strconv.Atoi(testDefaultUpdatableModuleVersion) 6694 barExpectedDefaultVersion := fmt.Sprint(defaultVersionInt + 3) 6695 barActualDefaultVersion := barManifestRule.Args["default_version"] 6696 if barActualDefaultVersion != barExpectedDefaultVersion { 6697 t.Errorf("expected to find defaultVersion %q; got %q", barExpectedDefaultVersion, barActualDefaultVersion) 6698 } 6699 6700 overrideBarManifestRule := result.ModuleForTests("bar", "android_common_myoverrideapex_myoverrideapex").Rule("apexManifestRule") 6701 overrideBarActualDefaultVersion := overrideBarManifestRule.Args["default_version"] 6702 if overrideBarActualDefaultVersion != barExpectedDefaultVersion { 6703 t.Errorf("expected to find defaultVersion %q; got %q", barExpectedDefaultVersion, barActualDefaultVersion) 6704 } 6705} 6706 6707func TestApexAvailable_ApexAvailableName(t *testing.T) { 6708 t.Parallel() 6709 t.Run("using name of apex that sets apex_available_name is not allowed", func(t *testing.T) { 6710 t.Parallel() 6711 testApexError(t, "Consider adding \"myapex\" to 'apex_available' property of \"AppFoo\"", ` 6712 apex { 6713 name: "myapex_sminus", 6714 key: "myapex.key", 6715 apps: ["AppFoo"], 6716 apex_available_name: "myapex", 6717 updatable: false, 6718 } 6719 apex { 6720 name: "myapex", 6721 key: "myapex.key", 6722 apps: ["AppFoo"], 6723 updatable: false, 6724 } 6725 apex_key { 6726 name: "myapex.key", 6727 public_key: "testkey.avbpubkey", 6728 private_key: "testkey.pem", 6729 } 6730 android_app { 6731 name: "AppFoo", 6732 srcs: ["foo/bar/MyClass.java"], 6733 sdk_version: "none", 6734 system_modules: "none", 6735 apex_available: [ "myapex_sminus" ], 6736 }`, 6737 android.FixtureMergeMockFs(android.MockFS{ 6738 "system/sepolicy/apex/myapex_sminus-file_contexts": nil, 6739 }), 6740 ) 6741 }) 6742 6743 t.Run("apex_available_name allows module to be used in two different apexes", func(t *testing.T) { 6744 t.Parallel() 6745 testApex(t, ` 6746 apex { 6747 name: "myapex_sminus", 6748 key: "myapex.key", 6749 apps: ["AppFoo"], 6750 apex_available_name: "myapex", 6751 updatable: false, 6752 } 6753 apex { 6754 name: "myapex", 6755 key: "myapex.key", 6756 apps: ["AppFoo"], 6757 updatable: false, 6758 } 6759 apex_key { 6760 name: "myapex.key", 6761 public_key: "testkey.avbpubkey", 6762 private_key: "testkey.pem", 6763 } 6764 android_app { 6765 name: "AppFoo", 6766 srcs: ["foo/bar/MyClass.java"], 6767 sdk_version: "none", 6768 system_modules: "none", 6769 apex_available: [ "myapex" ], 6770 }`, 6771 android.FixtureMergeMockFs(android.MockFS{ 6772 "system/sepolicy/apex/myapex_sminus-file_contexts": nil, 6773 }), 6774 ) 6775 }) 6776 6777 t.Run("override_apexes work with apex_available_name", func(t *testing.T) { 6778 t.Parallel() 6779 testApex(t, ` 6780 override_apex { 6781 name: "myoverrideapex_sminus", 6782 base: "myapex_sminus", 6783 key: "myapex.key", 6784 apps: ["AppFooOverride"], 6785 } 6786 override_apex { 6787 name: "myoverrideapex", 6788 base: "myapex", 6789 key: "myapex.key", 6790 apps: ["AppFooOverride"], 6791 } 6792 apex { 6793 name: "myapex_sminus", 6794 key: "myapex.key", 6795 apps: ["AppFoo"], 6796 apex_available_name: "myapex", 6797 updatable: false, 6798 } 6799 apex { 6800 name: "myapex", 6801 key: "myapex.key", 6802 apps: ["AppFoo"], 6803 updatable: false, 6804 } 6805 apex_key { 6806 name: "myapex.key", 6807 public_key: "testkey.avbpubkey", 6808 private_key: "testkey.pem", 6809 } 6810 android_app { 6811 name: "AppFooOverride", 6812 srcs: ["foo/bar/MyClass.java"], 6813 sdk_version: "none", 6814 system_modules: "none", 6815 apex_available: [ "myapex" ], 6816 } 6817 android_app { 6818 name: "AppFoo", 6819 srcs: ["foo/bar/MyClass.java"], 6820 sdk_version: "none", 6821 system_modules: "none", 6822 apex_available: [ "myapex" ], 6823 }`, 6824 android.FixtureMergeMockFs(android.MockFS{ 6825 "system/sepolicy/apex/myapex_sminus-file_contexts": nil, 6826 }), 6827 ) 6828 }) 6829} 6830 6831func TestApexAvailable_ApexAvailableNameWithOverrides(t *testing.T) { 6832 t.Parallel() 6833 context := android.GroupFixturePreparers( 6834 android.PrepareForIntegrationTestWithAndroid, 6835 PrepareForTestWithApexBuildComponents, 6836 java.PrepareForTestWithDexpreopt, 6837 android.FixtureMergeMockFs(android.MockFS{ 6838 "system/sepolicy/apex/myapex-file_contexts": nil, 6839 "system/sepolicy/apex/myapex_sminus-file_contexts": nil, 6840 }), 6841 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 6842 variables.BuildId = proptools.StringPtr("buildid") 6843 }), 6844 ) 6845 context.RunTestWithBp(t, ` 6846 override_apex { 6847 name: "myoverrideapex_sminus", 6848 base: "myapex_sminus", 6849 } 6850 override_apex { 6851 name: "myoverrideapex", 6852 base: "myapex", 6853 } 6854 apex { 6855 name: "myapex", 6856 key: "myapex.key", 6857 apps: ["AppFoo"], 6858 updatable: false, 6859 } 6860 apex { 6861 name: "myapex_sminus", 6862 apex_available_name: "myapex", 6863 key: "myapex.key", 6864 apps: ["AppFoo_sminus"], 6865 updatable: false, 6866 } 6867 apex_key { 6868 name: "myapex.key", 6869 public_key: "testkey.avbpubkey", 6870 private_key: "testkey.pem", 6871 } 6872 android_app { 6873 name: "AppFoo", 6874 srcs: ["foo/bar/MyClass.java"], 6875 sdk_version: "none", 6876 system_modules: "none", 6877 apex_available: [ "myapex" ], 6878 } 6879 android_app { 6880 name: "AppFoo_sminus", 6881 srcs: ["foo/bar/MyClass.java"], 6882 sdk_version: "none", 6883 min_sdk_version: "29", 6884 system_modules: "none", 6885 apex_available: [ "myapex" ], 6886 }`) 6887} 6888 6889func TestApexAvailable_CheckForPlatform(t *testing.T) { 6890 t.Parallel() 6891 ctx := testApex(t, ` 6892 apex { 6893 name: "myapex", 6894 key: "myapex.key", 6895 native_shared_libs: ["libbar", "libbaz"], 6896 updatable: false, 6897 } 6898 6899 apex_key { 6900 name: "myapex.key", 6901 public_key: "testkey.avbpubkey", 6902 private_key: "testkey.pem", 6903 } 6904 6905 cc_library { 6906 name: "libfoo", 6907 stl: "none", 6908 system_shared_libs: [], 6909 shared_libs: ["libbar"], 6910 apex_available: ["//apex_available:platform"], 6911 } 6912 6913 cc_library { 6914 name: "libfoo2", 6915 stl: "none", 6916 system_shared_libs: [], 6917 shared_libs: ["libbaz"], 6918 apex_available: ["//apex_available:platform"], 6919 } 6920 6921 cc_library { 6922 name: "libbar", 6923 stl: "none", 6924 system_shared_libs: [], 6925 apex_available: ["myapex"], 6926 } 6927 6928 cc_library { 6929 name: "libbaz", 6930 stl: "none", 6931 system_shared_libs: [], 6932 apex_available: ["myapex"], 6933 stubs: { 6934 versions: ["1"], 6935 }, 6936 }`) 6937 6938 // libfoo shouldn't be available to platform even though it has "//apex_available:platform", 6939 // because it depends on libbar which isn't available to platform 6940 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module().(*cc.Module) 6941 if libfoo.NotAvailableForPlatform() != true { 6942 t.Errorf("%q shouldn't be available to platform", libfoo.String()) 6943 } 6944 6945 // libfoo2 however can be available to platform because it depends on libbaz which provides 6946 // stubs 6947 libfoo2 := ctx.ModuleForTests("libfoo2", "android_arm64_armv8-a_shared").Module().(*cc.Module) 6948 if libfoo2.NotAvailableForPlatform() == true { 6949 t.Errorf("%q should be available to platform", libfoo2.String()) 6950 } 6951} 6952 6953func TestApexAvailable_CreatedForApex(t *testing.T) { 6954 t.Parallel() 6955 ctx := testApex(t, ` 6956 apex { 6957 name: "myapex", 6958 key: "myapex.key", 6959 native_shared_libs: ["libfoo"], 6960 updatable: false, 6961 } 6962 6963 apex_key { 6964 name: "myapex.key", 6965 public_key: "testkey.avbpubkey", 6966 private_key: "testkey.pem", 6967 } 6968 6969 cc_library { 6970 name: "libfoo", 6971 stl: "none", 6972 system_shared_libs: [], 6973 apex_available: ["myapex"], 6974 static: { 6975 apex_available: ["//apex_available:platform"], 6976 }, 6977 }`) 6978 6979 libfooShared := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module().(*cc.Module) 6980 if libfooShared.NotAvailableForPlatform() != true { 6981 t.Errorf("%q shouldn't be available to platform", libfooShared.String()) 6982 } 6983 libfooStatic := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Module().(*cc.Module) 6984 if libfooStatic.NotAvailableForPlatform() != false { 6985 t.Errorf("%q should be available to platform", libfooStatic.String()) 6986 } 6987} 6988 6989func TestApexAvailable_PrefixMatch(t *testing.T) { 6990 t.Parallel() 6991 6992 for _, tc := range []struct { 6993 name string 6994 apexAvailable string 6995 expectedError string 6996 }{ 6997 { 6998 name: "prefix matches correctly", 6999 apexAvailable: "com.foo.*", 7000 }, 7001 { 7002 name: "prefix doesn't match", 7003 apexAvailable: "com.bar.*", 7004 expectedError: `Consider .* "com.foo\.\*"`, 7005 }, 7006 { 7007 name: "short prefix", 7008 apexAvailable: "com.*", 7009 expectedError: "requires two or more components", 7010 }, 7011 { 7012 name: "wildcard not in the end", 7013 apexAvailable: "com.*.foo", 7014 expectedError: "should end with .*", 7015 }, 7016 { 7017 name: "wildcard in the middle", 7018 apexAvailable: "com.foo*.*", 7019 expectedError: "not allowed in the middle", 7020 }, 7021 { 7022 name: "hint with prefix pattern", 7023 apexAvailable: "//apex_available:platform", 7024 expectedError: "Consider adding \"com.foo.bar\" or \"com.foo.*\"", 7025 }, 7026 } { 7027 t.Run(tc.name, func(t *testing.T) { 7028 t.Parallel() 7029 errorHandler := android.FixtureExpectsNoErrors 7030 if tc.expectedError != "" { 7031 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(tc.expectedError) 7032 } 7033 context := android.GroupFixturePreparers( 7034 prepareForApexTest, 7035 android.FixtureMergeMockFs(android.MockFS{ 7036 "system/sepolicy/apex/com.foo.bar-file_contexts": nil, 7037 }), 7038 ).ExtendWithErrorHandler(errorHandler) 7039 7040 context.RunTestWithBp(t, ` 7041 apex { 7042 name: "com.foo.bar", 7043 key: "myapex.key", 7044 native_shared_libs: ["libfoo"], 7045 updatable: false, 7046 } 7047 7048 apex_key { 7049 name: "myapex.key", 7050 public_key: "testkey.avbpubkey", 7051 private_key: "testkey.pem", 7052 } 7053 7054 cc_library { 7055 name: "libfoo", 7056 stl: "none", 7057 system_shared_libs: [], 7058 apex_available: ["`+tc.apexAvailable+`"], 7059 }`) 7060 }) 7061 } 7062 testApexError(t, `Consider adding "com.foo" to`, ` 7063 apex { 7064 name: "com.foo", // too short for a partner apex 7065 key: "myapex.key", 7066 native_shared_libs: ["libfoo"], 7067 updatable: false, 7068 } 7069 7070 apex_key { 7071 name: "myapex.key", 7072 public_key: "testkey.avbpubkey", 7073 private_key: "testkey.pem", 7074 } 7075 7076 cc_library { 7077 name: "libfoo", 7078 stl: "none", 7079 system_shared_libs: [], 7080 } 7081 `) 7082} 7083 7084func TestApexValidation_TestApexCanSkipInitRcCheck(t *testing.T) { 7085 t.Parallel() 7086 ctx := testApex(t, ` 7087 apex_test { 7088 name: "myapex", 7089 key: "myapex.key", 7090 skip_validations: { 7091 host_apex_verifier: true, 7092 }, 7093 updatable: false, 7094 } 7095 apex_key { 7096 name: "myapex.key", 7097 public_key: "testkey.avbpubkey", 7098 private_key: "testkey.pem", 7099 } 7100 `) 7101 7102 validations := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("signapk").Validations.Strings() 7103 if android.SuffixInList(validations, "host_apex_verifier.timestamp") { 7104 t.Error("should not run host_apex_verifier") 7105 } 7106} 7107 7108func TestApexValidation_TestApexCheckInitRc(t *testing.T) { 7109 t.Parallel() 7110 ctx := testApex(t, ` 7111 apex_test { 7112 name: "myapex", 7113 key: "myapex.key", 7114 updatable: false, 7115 } 7116 apex_key { 7117 name: "myapex.key", 7118 public_key: "testkey.avbpubkey", 7119 private_key: "testkey.pem", 7120 } 7121 `) 7122 7123 validations := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("signapk").Validations.Strings() 7124 if !android.SuffixInList(validations, "host_apex_verifier.timestamp") { 7125 t.Error("should run host_apex_verifier") 7126 } 7127} 7128 7129func TestOverrideApex(t *testing.T) { 7130 t.Parallel() 7131 ctx := testApex(t, ` 7132 apex { 7133 name: "myapex", 7134 key: "myapex.key", 7135 apps: ["app"], 7136 bpfs: ["bpf"], 7137 prebuilts: ["myetc"], 7138 overrides: ["oldapex"], 7139 updatable: false, 7140 } 7141 7142 override_apex { 7143 name: "override_myapex", 7144 base: "myapex", 7145 apps: ["override_app"], 7146 bpfs: ["overrideBpf"], 7147 prebuilts: ["override_myetc"], 7148 overrides: ["unknownapex"], 7149 compile_multilib: "first", 7150 multilib: { 7151 lib32: { 7152 native_shared_libs: ["mylib32"], 7153 }, 7154 lib64: { 7155 native_shared_libs: ["mylib64"], 7156 }, 7157 }, 7158 logging_parent: "com.foo.bar", 7159 package_name: "test.overridden.package", 7160 key: "mynewapex.key", 7161 certificate: ":myapex.certificate", 7162 } 7163 7164 apex_key { 7165 name: "myapex.key", 7166 public_key: "testkey.avbpubkey", 7167 private_key: "testkey.pem", 7168 } 7169 7170 apex_key { 7171 name: "mynewapex.key", 7172 public_key: "testkey2.avbpubkey", 7173 private_key: "testkey2.pem", 7174 } 7175 7176 android_app_certificate { 7177 name: "myapex.certificate", 7178 certificate: "testkey", 7179 } 7180 7181 android_app { 7182 name: "app", 7183 srcs: ["foo/bar/MyClass.java"], 7184 package_name: "foo", 7185 sdk_version: "none", 7186 system_modules: "none", 7187 apex_available: [ "myapex" ], 7188 } 7189 7190 override_android_app { 7191 name: "override_app", 7192 base: "app", 7193 package_name: "bar", 7194 } 7195 7196 bpf { 7197 name: "bpf", 7198 srcs: ["bpf.c"], 7199 } 7200 7201 bpf { 7202 name: "overrideBpf", 7203 srcs: ["overrideBpf.c"], 7204 } 7205 7206 prebuilt_etc { 7207 name: "myetc", 7208 src: "myprebuilt", 7209 } 7210 7211 prebuilt_etc { 7212 name: "override_myetc", 7213 src: "override_myprebuilt", 7214 } 7215 7216 cc_library { 7217 name: "mylib32", 7218 apex_available: [ "myapex" ], 7219 } 7220 7221 cc_library { 7222 name: "mylib64", 7223 apex_available: [ "myapex" ], 7224 } 7225 `, withManifestPackageNameOverrides([]string{"myapex:com.android.myapex"})) 7226 7227 originalVariant := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(android.OverridableModule) 7228 overriddenVariant := ctx.ModuleForTests("myapex", "android_common_override_myapex_override_myapex").Module().(android.OverridableModule) 7229 if originalVariant.GetOverriddenBy() != "" { 7230 t.Errorf("GetOverriddenBy should be empty, but was %q", originalVariant.GetOverriddenBy()) 7231 } 7232 if overriddenVariant.GetOverriddenBy() != "override_myapex" { 7233 t.Errorf("GetOverriddenBy should be \"override_myapex\", but was %q", overriddenVariant.GetOverriddenBy()) 7234 } 7235 7236 module := ctx.ModuleForTests("myapex", "android_common_override_myapex_override_myapex") 7237 apexRule := module.Rule("apexRule") 7238 copyCmds := apexRule.Args["copy_commands"] 7239 7240 ensureNotContains(t, copyCmds, "image.apex/app/app@TEST.BUILD_ID/app.apk") 7241 ensureContains(t, copyCmds, "image.apex/app/override_app@TEST.BUILD_ID/override_app.apk") 7242 7243 ensureNotContains(t, copyCmds, "image.apex/etc/bpf/bpf.o") 7244 ensureContains(t, copyCmds, "image.apex/etc/bpf/overrideBpf.o") 7245 7246 ensureNotContains(t, copyCmds, "image.apex/etc/myetc") 7247 ensureContains(t, copyCmds, "image.apex/etc/override_myetc") 7248 7249 apexBundle := module.Module().(*apexBundle) 7250 name := apexBundle.Name() 7251 if name != "override_myapex" { 7252 t.Errorf("name should be \"override_myapex\", but was %q", name) 7253 } 7254 7255 if apexBundle.overridableProperties.Logging_parent != "com.foo.bar" { 7256 t.Errorf("override_myapex should have logging parent (com.foo.bar), but was %q.", apexBundle.overridableProperties.Logging_parent) 7257 } 7258 7259 optFlags := apexRule.Args["opt_flags"] 7260 ensureContains(t, optFlags, "--override_apk_package_name test.overridden.package") 7261 ensureContains(t, optFlags, "--pubkey testkey2.avbpubkey") 7262 7263 signApkRule := module.Rule("signapk") 7264 ensureEquals(t, signApkRule.Args["certificates"], "testkey.x509.pem testkey.pk8") 7265 7266 data := android.AndroidMkDataForTest(t, ctx, apexBundle) 7267 var builder strings.Builder 7268 data.Custom(&builder, name, "TARGET_", "", data) 7269 androidMk := builder.String() 7270 ensureContains(t, androidMk, "LOCAL_MODULE := override_app.override_myapex") 7271 ensureContains(t, androidMk, "LOCAL_MODULE := overrideBpf.o.override_myapex") 7272 ensureContains(t, androidMk, "LOCAL_MODULE_STEM := override_myapex.apex") 7273 ensureContains(t, androidMk, "LOCAL_OVERRIDES_MODULES := unknownapex myapex") 7274 ensureNotContains(t, androidMk, "LOCAL_MODULE := app.myapex") 7275 ensureNotContains(t, androidMk, "LOCAL_MODULE := bpf.myapex") 7276 ensureNotContains(t, androidMk, "LOCAL_MODULE := override_app.myapex") 7277 ensureNotContains(t, androidMk, "LOCAL_MODULE_STEM := myapex.apex") 7278} 7279 7280func TestMinSdkVersionOverride(t *testing.T) { 7281 t.Parallel() 7282 // Override from 29 to 31 7283 minSdkOverride31 := "31" 7284 ctx := testApex(t, ` 7285 apex { 7286 name: "myapex", 7287 key: "myapex.key", 7288 native_shared_libs: ["mylib"], 7289 updatable: true, 7290 min_sdk_version: "29" 7291 } 7292 7293 override_apex { 7294 name: "override_myapex", 7295 base: "myapex", 7296 logging_parent: "com.foo.bar", 7297 package_name: "test.overridden.package" 7298 } 7299 7300 apex_key { 7301 name: "myapex.key", 7302 public_key: "testkey.avbpubkey", 7303 private_key: "testkey.pem", 7304 } 7305 7306 cc_library { 7307 name: "mylib", 7308 srcs: ["mylib.cpp"], 7309 runtime_libs: ["libbar"], 7310 system_shared_libs: [], 7311 stl: "none", 7312 apex_available: [ "myapex" ], 7313 min_sdk_version: "apex_inherit" 7314 } 7315 7316 cc_library { 7317 name: "libbar", 7318 srcs: ["mylib.cpp"], 7319 system_shared_libs: [], 7320 stl: "none", 7321 apex_available: [ "myapex" ], 7322 min_sdk_version: "apex_inherit" 7323 } 7324 7325 `, withApexGlobalMinSdkVersionOverride(&minSdkOverride31)) 7326 7327 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule") 7328 copyCmds := apexRule.Args["copy_commands"] 7329 7330 // Ensure that direct non-stubs dep is always included 7331 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") 7332 7333 // Ensure that runtime_libs dep in included 7334 ensureContains(t, copyCmds, "image.apex/lib64/libbar.so") 7335 7336 // Ensure libraries target overridden min_sdk_version value 7337 ensureListContains(t, ctx.ModuleVariantsForTests("libbar"), "android_arm64_armv8-a_shared_apex31") 7338} 7339 7340func TestMinSdkVersionOverrideToLowerVersionNoOp(t *testing.T) { 7341 t.Parallel() 7342 // Attempt to override from 31 to 29, should be a NOOP 7343 minSdkOverride29 := "29" 7344 ctx := testApex(t, ` 7345 apex { 7346 name: "myapex", 7347 key: "myapex.key", 7348 native_shared_libs: ["mylib"], 7349 updatable: true, 7350 min_sdk_version: "31" 7351 } 7352 7353 override_apex { 7354 name: "override_myapex", 7355 base: "myapex", 7356 logging_parent: "com.foo.bar", 7357 package_name: "test.overridden.package" 7358 } 7359 7360 apex_key { 7361 name: "myapex.key", 7362 public_key: "testkey.avbpubkey", 7363 private_key: "testkey.pem", 7364 } 7365 7366 cc_library { 7367 name: "mylib", 7368 srcs: ["mylib.cpp"], 7369 runtime_libs: ["libbar"], 7370 system_shared_libs: [], 7371 stl: "none", 7372 apex_available: [ "myapex" ], 7373 min_sdk_version: "apex_inherit" 7374 } 7375 7376 cc_library { 7377 name: "libbar", 7378 srcs: ["mylib.cpp"], 7379 system_shared_libs: [], 7380 stl: "none", 7381 apex_available: [ "myapex" ], 7382 min_sdk_version: "apex_inherit" 7383 } 7384 7385 `, withApexGlobalMinSdkVersionOverride(&minSdkOverride29)) 7386 7387 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule") 7388 copyCmds := apexRule.Args["copy_commands"] 7389 7390 // Ensure that direct non-stubs dep is always included 7391 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") 7392 7393 // Ensure that runtime_libs dep in included 7394 ensureContains(t, copyCmds, "image.apex/lib64/libbar.so") 7395 7396 // Ensure libraries target the original min_sdk_version value rather than the overridden 7397 ensureListContains(t, ctx.ModuleVariantsForTests("libbar"), "android_arm64_armv8-a_shared_apex31") 7398} 7399 7400func TestLegacyAndroid10Support(t *testing.T) { 7401 t.Parallel() 7402 ctx := testApex(t, ` 7403 apex { 7404 name: "myapex", 7405 key: "myapex.key", 7406 native_shared_libs: ["mylib"], 7407 min_sdk_version: "29", 7408 } 7409 7410 apex_key { 7411 name: "myapex.key", 7412 public_key: "testkey.avbpubkey", 7413 private_key: "testkey.pem", 7414 } 7415 7416 cc_library { 7417 name: "mylib", 7418 srcs: ["mylib.cpp"], 7419 stl: "libc++", 7420 system_shared_libs: [], 7421 apex_available: [ "myapex" ], 7422 min_sdk_version: "29", 7423 } 7424 `, withUnbundledBuild) 7425 7426 module := ctx.ModuleForTests("myapex", "android_common_myapex") 7427 args := module.Rule("apexRule").Args 7428 ensureContains(t, args["opt_flags"], "--manifest_json "+module.Output("apex_manifest.json").Output.String()) 7429 7430 // The copies of the libraries in the apex should have one more dependency than 7431 // the ones outside the apex, namely the unwinder. Ideally we should check 7432 // the dependency names directly here but for some reason the names are blank in 7433 // this test. 7434 for _, lib := range []string{"libc++", "mylib"} { 7435 apexImplicits := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared_apex29").Rule("ld").Implicits 7436 nonApexImplicits := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld").Implicits 7437 if len(apexImplicits) != len(nonApexImplicits)+1 { 7438 t.Errorf("%q missing unwinder dep", lib) 7439 } 7440 } 7441} 7442 7443var filesForSdkLibrary = android.MockFS{ 7444 "api/current.txt": nil, 7445 "api/removed.txt": nil, 7446 "api/system-current.txt": nil, 7447 "api/system-removed.txt": nil, 7448 "api/test-current.txt": nil, 7449 "api/test-removed.txt": nil, 7450 7451 "100/public/api/foo.txt": nil, 7452 "100/public/api/foo-removed.txt": nil, 7453 "100/system/api/foo.txt": nil, 7454 "100/system/api/foo-removed.txt": nil, 7455 7456 // For java_sdk_library_import 7457 "a.jar": nil, 7458} 7459 7460func TestJavaSDKLibrary(t *testing.T) { 7461 t.Parallel() 7462 ctx := testApex(t, ` 7463 apex { 7464 name: "myapex", 7465 key: "myapex.key", 7466 java_libs: ["foo"], 7467 updatable: false, 7468 } 7469 7470 apex_key { 7471 name: "myapex.key", 7472 public_key: "testkey.avbpubkey", 7473 private_key: "testkey.pem", 7474 } 7475 7476 java_sdk_library { 7477 name: "foo", 7478 srcs: ["a.java"], 7479 api_packages: ["foo"], 7480 apex_available: [ "myapex" ], 7481 } 7482 7483 prebuilt_apis { 7484 name: "sdk", 7485 api_dirs: ["100"], 7486 } 7487 `, withFiles(filesForSdkLibrary)) 7488 7489 // java_sdk_library installs both impl jar and permission XML 7490 ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{ 7491 "javalib/foo.jar", 7492 "etc/permissions/foo.xml", 7493 }) 7494 // Permission XML should point to the activated path of impl jar of java_sdk_library 7495 sdkLibrary := ctx.ModuleForTests("foo.xml", "android_common_myapex").Output("foo.xml") 7496 contents := android.ContentFromFileRuleForTests(t, ctx, sdkLibrary) 7497 ensureMatches(t, contents, "<library\\n\\s+name=\\\"foo\\\"\\n\\s+file=\\\"/apex/myapex/javalib/foo.jar\\\"") 7498} 7499 7500func TestJavaSDKLibraryOverrideApexes(t *testing.T) { 7501 t.Parallel() 7502 ctx := testApex(t, ` 7503 override_apex { 7504 name: "mycompanyapex", 7505 base: "myapex", 7506 } 7507 apex { 7508 name: "myapex", 7509 key: "myapex.key", 7510 java_libs: ["foo"], 7511 updatable: false, 7512 } 7513 7514 apex_key { 7515 name: "myapex.key", 7516 public_key: "testkey.avbpubkey", 7517 private_key: "testkey.pem", 7518 } 7519 7520 java_sdk_library { 7521 name: "foo", 7522 srcs: ["a.java"], 7523 api_packages: ["foo"], 7524 apex_available: [ "myapex" ], 7525 } 7526 7527 prebuilt_apis { 7528 name: "sdk", 7529 api_dirs: ["100"], 7530 } 7531 `, withFiles(filesForSdkLibrary)) 7532 7533 // Permission XML should point to the activated path of impl jar of java_sdk_library. 7534 // Since override variants (com.mycompany.android.foo) are installed in the same package as the overridden variant 7535 // (com.android.foo), the filepath should not contain override apex name. 7536 sdkLibrary := ctx.ModuleForTests("foo.xml", "android_common_mycompanyapex").Output("foo.xml") 7537 contents := android.ContentFromFileRuleForTests(t, ctx, sdkLibrary) 7538 ensureMatches(t, contents, "<library\\n\\s+name=\\\"foo\\\"\\n\\s+file=\\\"/apex/myapex/javalib/foo.jar\\\"") 7539} 7540 7541func TestJavaSDKLibrary_WithinApex(t *testing.T) { 7542 t.Parallel() 7543 ctx := testApex(t, ` 7544 apex { 7545 name: "myapex", 7546 key: "myapex.key", 7547 java_libs: ["foo", "bar"], 7548 updatable: false, 7549 } 7550 7551 apex_key { 7552 name: "myapex.key", 7553 public_key: "testkey.avbpubkey", 7554 private_key: "testkey.pem", 7555 } 7556 7557 java_sdk_library { 7558 name: "foo", 7559 srcs: ["a.java"], 7560 api_packages: ["foo"], 7561 apex_available: ["myapex"], 7562 sdk_version: "none", 7563 system_modules: "none", 7564 compile_dex: true, 7565 } 7566 7567 java_library { 7568 name: "bar", 7569 srcs: ["a.java"], 7570 libs: ["foo.impl"], 7571 apex_available: ["myapex"], 7572 sdk_version: "none", 7573 system_modules: "none", 7574 compile_dex: true, 7575 } 7576 7577 prebuilt_apis { 7578 name: "sdk", 7579 api_dirs: ["100"], 7580 } 7581 `, withFiles(filesForSdkLibrary)) 7582 7583 // java_sdk_library installs both impl jar and permission XML 7584 ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{ 7585 "javalib/bar.jar", 7586 "javalib/foo.jar", 7587 "etc/permissions/foo.xml", 7588 }) 7589 7590 // The bar library should depend on the implementation jar. 7591 barLibrary := ctx.ModuleForTests("bar", "android_common_myapex").Rule("javac") 7592 if expected, actual := `^-classpath [^:]*/turbine-combined/foo\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { 7593 t.Errorf("expected %q, found %#q", expected, actual) 7594 } 7595} 7596 7597func TestJavaSDKLibrary_CrossBoundary(t *testing.T) { 7598 t.Parallel() 7599 ctx := testApex(t, ` 7600 apex { 7601 name: "myapex", 7602 key: "myapex.key", 7603 java_libs: ["foo"], 7604 updatable: false, 7605 } 7606 7607 apex_key { 7608 name: "myapex.key", 7609 public_key: "testkey.avbpubkey", 7610 private_key: "testkey.pem", 7611 } 7612 7613 java_sdk_library { 7614 name: "foo", 7615 srcs: ["a.java"], 7616 api_packages: ["foo"], 7617 apex_available: ["myapex"], 7618 sdk_version: "none", 7619 system_modules: "none", 7620 } 7621 7622 java_library { 7623 name: "bar", 7624 srcs: ["a.java"], 7625 libs: ["foo.stubs"], 7626 sdk_version: "none", 7627 system_modules: "none", 7628 } 7629 7630 prebuilt_apis { 7631 name: "sdk", 7632 api_dirs: ["100"], 7633 } 7634 `, withFiles(filesForSdkLibrary)) 7635 7636 // java_sdk_library installs both impl jar and permission XML 7637 ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{ 7638 "javalib/foo.jar", 7639 "etc/permissions/foo.xml", 7640 }) 7641 7642 // The bar library should depend on the stubs jar. 7643 barLibrary := ctx.ModuleForTests("bar", "android_common").Rule("javac") 7644 if expected, actual := `^-classpath [^:]*/turbine-combined/foo\.stubs\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { 7645 t.Errorf("expected %q, found %#q", expected, actual) 7646 } 7647} 7648 7649func TestJavaSDKLibrary_ImportPreferred(t *testing.T) { 7650 t.Parallel() 7651 ctx := testApex(t, ` 7652 prebuilt_apis { 7653 name: "sdk", 7654 api_dirs: ["100"], 7655 }`, 7656 withFiles(map[string][]byte{ 7657 "apex/a.java": nil, 7658 "apex/apex_manifest.json": nil, 7659 "apex/Android.bp": []byte(` 7660 package { 7661 default_visibility: ["//visibility:private"], 7662 } 7663 7664 apex { 7665 name: "myapex", 7666 key: "myapex.key", 7667 java_libs: ["foo", "bar"], 7668 updatable: false, 7669 } 7670 7671 apex_key { 7672 name: "myapex.key", 7673 public_key: "testkey.avbpubkey", 7674 private_key: "testkey.pem", 7675 } 7676 7677 java_library { 7678 name: "bar", 7679 srcs: ["a.java"], 7680 libs: ["foo.impl"], 7681 apex_available: ["myapex"], 7682 sdk_version: "none", 7683 system_modules: "none", 7684 compile_dex: true, 7685 } 7686`), 7687 "source/a.java": nil, 7688 "source/api/current.txt": nil, 7689 "source/api/removed.txt": nil, 7690 "source/Android.bp": []byte(` 7691 package { 7692 default_visibility: ["//visibility:private"], 7693 } 7694 7695 java_sdk_library { 7696 name: "foo", 7697 visibility: ["//apex"], 7698 srcs: ["a.java"], 7699 api_packages: ["foo"], 7700 apex_available: ["myapex"], 7701 sdk_version: "none", 7702 system_modules: "none", 7703 public: { 7704 enabled: true, 7705 }, 7706 compile_dex: true, 7707 } 7708`), 7709 "prebuilt/a.jar": nil, 7710 "prebuilt/Android.bp": []byte(` 7711 package { 7712 default_visibility: ["//visibility:private"], 7713 } 7714 7715 java_sdk_library_import { 7716 name: "foo", 7717 visibility: ["//apex", "//source"], 7718 apex_available: ["myapex"], 7719 prefer: true, 7720 public: { 7721 jars: ["a.jar"], 7722 }, 7723 compile_dex: true, 7724 } 7725`), 7726 }), withFiles(filesForSdkLibrary), 7727 ) 7728 7729 // java_sdk_library installs both impl jar and permission XML 7730 ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{ 7731 "javalib/bar.jar", 7732 "javalib/foo.jar", 7733 "etc/permissions/foo.xml", 7734 }) 7735 7736 // The bar library should depend on the implementation jar. 7737 barLibrary := ctx.ModuleForTests("bar", "android_common_myapex").Rule("javac") 7738 if expected, actual := `^-classpath [^:]*/turbine-combined/foo\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { 7739 t.Errorf("expected %q, found %#q", expected, actual) 7740 } 7741} 7742 7743func TestJavaSDKLibrary_ImportOnly(t *testing.T) { 7744 t.Parallel() 7745 testApexError(t, `java_libs: "foo" is not configured to be compiled into dex`, ` 7746 apex { 7747 name: "myapex", 7748 key: "myapex.key", 7749 java_libs: ["foo"], 7750 updatable: false, 7751 } 7752 7753 apex_key { 7754 name: "myapex.key", 7755 public_key: "testkey.avbpubkey", 7756 private_key: "testkey.pem", 7757 } 7758 7759 java_sdk_library_import { 7760 name: "foo", 7761 apex_available: ["myapex"], 7762 prefer: true, 7763 public: { 7764 jars: ["a.jar"], 7765 }, 7766 } 7767 7768 `, withFiles(filesForSdkLibrary)) 7769} 7770 7771func TestCompatConfig(t *testing.T) { 7772 t.Parallel() 7773 result := android.GroupFixturePreparers( 7774 prepareForApexTest, 7775 java.PrepareForTestWithPlatformCompatConfig, 7776 ).RunTestWithBp(t, ` 7777 apex { 7778 name: "myapex", 7779 key: "myapex.key", 7780 compat_configs: ["myjar-platform-compat-config"], 7781 java_libs: ["myjar"], 7782 updatable: false, 7783 } 7784 7785 apex_key { 7786 name: "myapex.key", 7787 public_key: "testkey.avbpubkey", 7788 private_key: "testkey.pem", 7789 } 7790 7791 platform_compat_config { 7792 name: "myjar-platform-compat-config", 7793 src: ":myjar", 7794 } 7795 7796 java_library { 7797 name: "myjar", 7798 srcs: ["foo/bar/MyClass.java"], 7799 sdk_version: "none", 7800 system_modules: "none", 7801 apex_available: [ "myapex" ], 7802 compile_dex: true, 7803 } 7804 7805 // Make sure that a preferred prebuilt does not affect the apex contents. 7806 prebuilt_platform_compat_config { 7807 name: "myjar-platform-compat-config", 7808 metadata: "compat-config/metadata.xml", 7809 prefer: true, 7810 } 7811 `) 7812 ctx := result.TestContext 7813 ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{ 7814 "etc/compatconfig/myjar-platform-compat-config.xml", 7815 "javalib/myjar.jar", 7816 }) 7817} 7818 7819func TestNoDupeApexFiles(t *testing.T) { 7820 t.Parallel() 7821 android.GroupFixturePreparers( 7822 android.PrepareForTestWithAndroidBuildComponents, 7823 PrepareForTestWithApexBuildComponents, 7824 prepareForTestWithMyapex, 7825 prebuilt_etc.PrepareForTestWithPrebuiltEtc, 7826 ). 7827 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern("is provided by two different files")). 7828 RunTestWithBp(t, ` 7829 apex { 7830 name: "myapex", 7831 key: "myapex.key", 7832 prebuilts: ["foo", "bar"], 7833 updatable: false, 7834 } 7835 7836 apex_key { 7837 name: "myapex.key", 7838 public_key: "testkey.avbpubkey", 7839 private_key: "testkey.pem", 7840 } 7841 7842 prebuilt_etc { 7843 name: "foo", 7844 src: "myprebuilt", 7845 filename_from_src: true, 7846 } 7847 7848 prebuilt_etc { 7849 name: "bar", 7850 src: "myprebuilt", 7851 filename_from_src: true, 7852 } 7853 `) 7854} 7855 7856func TestApexUnwantedTransitiveDeps(t *testing.T) { 7857 t.Parallel() 7858 bp := ` 7859 apex { 7860 name: "myapex", 7861 key: "myapex.key", 7862 native_shared_libs: ["libfoo"], 7863 updatable: false, 7864 unwanted_transitive_deps: ["libbar"], 7865 } 7866 7867 apex_key { 7868 name: "myapex.key", 7869 public_key: "testkey.avbpubkey", 7870 private_key: "testkey.pem", 7871 } 7872 7873 cc_library { 7874 name: "libfoo", 7875 srcs: ["foo.cpp"], 7876 shared_libs: ["libbar"], 7877 apex_available: ["myapex"], 7878 } 7879 7880 cc_library { 7881 name: "libbar", 7882 srcs: ["bar.cpp"], 7883 apex_available: ["myapex"], 7884 }` 7885 ctx := testApex(t, bp) 7886 ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{ 7887 "*/libc++.so", 7888 "*/libfoo.so", 7889 // not libbar.so 7890 }) 7891} 7892 7893func TestRejectNonInstallableJavaLibrary(t *testing.T) { 7894 t.Parallel() 7895 testApexError(t, `"myjar" is not configured to be compiled into dex`, ` 7896 apex { 7897 name: "myapex", 7898 key: "myapex.key", 7899 java_libs: ["myjar"], 7900 updatable: false, 7901 } 7902 7903 apex_key { 7904 name: "myapex.key", 7905 public_key: "testkey.avbpubkey", 7906 private_key: "testkey.pem", 7907 } 7908 7909 java_library { 7910 name: "myjar", 7911 srcs: ["foo/bar/MyClass.java"], 7912 sdk_version: "none", 7913 system_modules: "none", 7914 compile_dex: false, 7915 apex_available: ["myapex"], 7916 } 7917 `) 7918} 7919 7920func TestSymlinksFromApexToSystem(t *testing.T) { 7921 t.Parallel() 7922 bp := ` 7923 apex { 7924 name: "myapex", 7925 key: "myapex.key", 7926 native_shared_libs: ["mylib"], 7927 java_libs: ["myjar"], 7928 updatable: false, 7929 } 7930 7931 apex { 7932 name: "myapex.updatable", 7933 key: "myapex.key", 7934 native_shared_libs: ["mylib"], 7935 java_libs: ["myjar"], 7936 updatable: true, 7937 min_sdk_version: "33", 7938 } 7939 7940 apex_key { 7941 name: "myapex.key", 7942 public_key: "testkey.avbpubkey", 7943 private_key: "testkey.pem", 7944 } 7945 7946 cc_library { 7947 name: "mylib", 7948 srcs: ["mylib.cpp"], 7949 shared_libs: [ 7950 "myotherlib", 7951 "myotherlib_ext", 7952 ], 7953 system_shared_libs: [], 7954 stl: "none", 7955 apex_available: [ 7956 "myapex", 7957 "myapex.updatable", 7958 "//apex_available:platform", 7959 ], 7960 min_sdk_version: "33", 7961 } 7962 7963 cc_library { 7964 name: "myotherlib", 7965 srcs: ["mylib.cpp"], 7966 system_shared_libs: [], 7967 stl: "none", 7968 apex_available: [ 7969 "myapex", 7970 "myapex.updatable", 7971 "//apex_available:platform", 7972 ], 7973 min_sdk_version: "33", 7974 } 7975 7976 cc_library { 7977 name: "myotherlib_ext", 7978 srcs: ["mylib.cpp"], 7979 system_shared_libs: [], 7980 system_ext_specific: true, 7981 stl: "none", 7982 apex_available: [ 7983 "myapex", 7984 "myapex.updatable", 7985 "//apex_available:platform", 7986 ], 7987 min_sdk_version: "33", 7988 } 7989 7990 java_library { 7991 name: "myjar", 7992 srcs: ["foo/bar/MyClass.java"], 7993 sdk_version: "none", 7994 system_modules: "none", 7995 static_libs: ["myotherjar"], 7996 apex_available: [ 7997 "myapex", 7998 "myapex.updatable", 7999 "//apex_available:platform", 8000 ], 8001 min_sdk_version: "33", 8002 compile_dex: true, 8003 } 8004 8005 java_library { 8006 name: "myotherjar", 8007 srcs: ["foo/bar/MyClass.java"], 8008 sdk_version: "none", 8009 system_modules: "none", 8010 apex_available: [ 8011 "myapex", 8012 "myapex.updatable", 8013 "//apex_available:platform", 8014 ], 8015 min_sdk_version: "33", 8016 } 8017 ` 8018 8019 ensureRealfileExists := func(t *testing.T, files []fileInApex, file string) { 8020 for _, f := range files { 8021 if f.path == file { 8022 if f.isLink { 8023 t.Errorf("%q is not a real file", file) 8024 } 8025 return 8026 } 8027 } 8028 t.Errorf("%q is not found", file) 8029 } 8030 8031 ensureSymlinkExists := func(t *testing.T, files []fileInApex, file string, target string) { 8032 for _, f := range files { 8033 if f.path == file { 8034 if !f.isLink { 8035 t.Errorf("%q is not a symlink", file) 8036 } 8037 if f.src != target { 8038 t.Errorf("expected symlink target to be %q, got %q", target, f.src) 8039 } 8040 return 8041 } 8042 } 8043 t.Errorf("%q is not found", file) 8044 } 8045 8046 // For unbundled build, symlink shouldn't exist regardless of whether an APEX 8047 // is updatable or not 8048 ctx := testApex(t, bp, withUnbundledBuild) 8049 files := getFiles(t, ctx, "myapex", "android_common_myapex") 8050 ensureRealfileExists(t, files, "javalib/myjar.jar") 8051 ensureRealfileExists(t, files, "lib64/mylib.so") 8052 ensureRealfileExists(t, files, "lib64/myotherlib.so") 8053 ensureRealfileExists(t, files, "lib64/myotherlib_ext.so") 8054 8055 files = getFiles(t, ctx, "myapex.updatable", "android_common_myapex.updatable") 8056 ensureRealfileExists(t, files, "javalib/myjar.jar") 8057 ensureRealfileExists(t, files, "lib64/mylib.so") 8058 ensureRealfileExists(t, files, "lib64/myotherlib.so") 8059 ensureRealfileExists(t, files, "lib64/myotherlib_ext.so") 8060 8061 // For bundled build, symlink to the system for the non-updatable APEXes only 8062 ctx = testApex(t, bp) 8063 files = getFiles(t, ctx, "myapex", "android_common_myapex") 8064 ensureRealfileExists(t, files, "javalib/myjar.jar") 8065 ensureRealfileExists(t, files, "lib64/mylib.so") 8066 ensureSymlinkExists(t, files, "lib64/myotherlib.so", "/system/lib64/myotherlib.so") // this is symlink 8067 ensureSymlinkExists(t, files, "lib64/myotherlib_ext.so", "/system_ext/lib64/myotherlib_ext.so") // this is symlink 8068 8069 files = getFiles(t, ctx, "myapex.updatable", "android_common_myapex.updatable") 8070 ensureRealfileExists(t, files, "javalib/myjar.jar") 8071 ensureRealfileExists(t, files, "lib64/mylib.so") 8072 ensureRealfileExists(t, files, "lib64/myotherlib.so") // this is a real file 8073 ensureRealfileExists(t, files, "lib64/myotherlib_ext.so") // this is a real file 8074} 8075 8076func TestSymlinksFromApexToSystemRequiredModuleNames(t *testing.T) { 8077 t.Parallel() 8078 ctx := testApex(t, ` 8079 apex { 8080 name: "myapex", 8081 key: "myapex.key", 8082 native_shared_libs: ["mylib"], 8083 updatable: false, 8084 } 8085 8086 apex_key { 8087 name: "myapex.key", 8088 public_key: "testkey.avbpubkey", 8089 private_key: "testkey.pem", 8090 } 8091 8092 cc_library_shared { 8093 name: "mylib", 8094 srcs: ["mylib.cpp"], 8095 shared_libs: ["myotherlib"], 8096 system_shared_libs: [], 8097 stl: "none", 8098 apex_available: [ 8099 "myapex", 8100 "//apex_available:platform", 8101 ], 8102 } 8103 8104 cc_prebuilt_library_shared { 8105 name: "myotherlib", 8106 srcs: ["prebuilt.so"], 8107 system_shared_libs: [], 8108 stl: "none", 8109 apex_available: [ 8110 "myapex", 8111 "//apex_available:platform", 8112 ], 8113 } 8114 `) 8115 8116 apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle) 8117 data := android.AndroidMkDataForTest(t, ctx, apexBundle) 8118 var builder strings.Builder 8119 data.Custom(&builder, apexBundle.BaseModuleName(), "TARGET_", "", data) 8120 androidMk := builder.String() 8121 // `myotherlib` is added to `myapex` as symlink 8122 ensureContains(t, androidMk, "LOCAL_MODULE := mylib.myapex\n") 8123 ensureNotContains(t, androidMk, "LOCAL_MODULE := prebuilt_myotherlib.myapex\n") 8124 ensureNotContains(t, androidMk, "LOCAL_MODULE := myotherlib.myapex\n") 8125 // `myapex` should have `myotherlib` in its required line, not `prebuilt_myotherlib` 8126 ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := mylib.myapex:64 myotherlib:64\n") 8127} 8128 8129func TestApexWithJniLibs(t *testing.T) { 8130 t.Parallel() 8131 ctx := testApex(t, ` 8132 apex { 8133 name: "myapex", 8134 key: "myapex.key", 8135 binaries: ["mybin"], 8136 jni_libs: ["mylib", "mylib3", "libfoo.rust"], 8137 updatable: false, 8138 } 8139 8140 apex_key { 8141 name: "myapex.key", 8142 public_key: "testkey.avbpubkey", 8143 private_key: "testkey.pem", 8144 } 8145 8146 cc_library { 8147 name: "mylib", 8148 srcs: ["mylib.cpp"], 8149 shared_libs: ["mylib2"], 8150 system_shared_libs: [], 8151 stl: "none", 8152 apex_available: [ "myapex" ], 8153 } 8154 8155 cc_library { 8156 name: "mylib2", 8157 srcs: ["mylib.cpp"], 8158 system_shared_libs: [], 8159 stl: "none", 8160 apex_available: [ "myapex" ], 8161 } 8162 8163 // Used as both a JNI library and a regular shared library. 8164 cc_library { 8165 name: "mylib3", 8166 srcs: ["mylib.cpp"], 8167 system_shared_libs: [], 8168 stl: "none", 8169 apex_available: [ "myapex" ], 8170 } 8171 8172 cc_binary { 8173 name: "mybin", 8174 srcs: ["mybin.cpp"], 8175 shared_libs: ["mylib3"], 8176 system_shared_libs: [], 8177 stl: "none", 8178 apex_available: [ "myapex" ], 8179 } 8180 8181 rust_ffi_shared { 8182 name: "libfoo.rust", 8183 crate_name: "foo", 8184 srcs: ["foo.rs"], 8185 shared_libs: ["libfoo.shared_from_rust"], 8186 prefer_rlib: true, 8187 apex_available: ["myapex"], 8188 } 8189 8190 cc_library_shared { 8191 name: "libfoo.shared_from_rust", 8192 srcs: ["mylib.cpp"], 8193 system_shared_libs: [], 8194 stl: "none", 8195 stubs: { 8196 versions: ["10", "11", "12"], 8197 }, 8198 } 8199 8200 `) 8201 8202 rule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexManifestRule") 8203 // Notice mylib2.so (transitive dep) is not added as a jni_lib 8204 ensureEquals(t, rule.Args["opt"], "-a jniLibs libfoo.rust.so mylib.so mylib3.so") 8205 ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{ 8206 "bin/mybin", 8207 "lib64/mylib.so", 8208 "lib64/mylib2.so", 8209 "lib64/mylib3.so", 8210 "lib64/libfoo.rust.so", 8211 "lib64/libc++.so", // auto-added to libfoo.rust by Soong 8212 "lib64/liblog.so", // auto-added to libfoo.rust by Soong 8213 }) 8214 8215 // b/220397949 8216 ensureListContains(t, names(rule.Args["requireNativeLibs"]), "libfoo.shared_from_rust.so") 8217} 8218 8219func TestApexMutatorsDontRunIfDisabled(t *testing.T) { 8220 t.Parallel() 8221 ctx := testApex(t, ` 8222 apex { 8223 name: "myapex", 8224 key: "myapex.key", 8225 updatable: false, 8226 } 8227 apex_key { 8228 name: "myapex.key", 8229 public_key: "testkey.avbpubkey", 8230 private_key: "testkey.pem", 8231 } 8232 `, 8233 android.FixtureModifyConfig(func(config android.Config) { 8234 delete(config.Targets, android.Android) 8235 config.AndroidCommonTarget = android.Target{} 8236 }), 8237 ) 8238 8239 if expected, got := []string{""}, ctx.ModuleVariantsForTests("myapex"); !reflect.DeepEqual(expected, got) { 8240 t.Errorf("Expected variants: %v, but got: %v", expected, got) 8241 } 8242} 8243 8244func TestAppBundle(t *testing.T) { 8245 t.Parallel() 8246 ctx := testApex(t, ` 8247 apex { 8248 name: "myapex", 8249 key: "myapex.key", 8250 apps: ["AppFoo"], 8251 updatable: false, 8252 } 8253 8254 apex_key { 8255 name: "myapex.key", 8256 public_key: "testkey.avbpubkey", 8257 private_key: "testkey.pem", 8258 } 8259 8260 android_app { 8261 name: "AppFoo", 8262 srcs: ["foo/bar/MyClass.java"], 8263 sdk_version: "none", 8264 system_modules: "none", 8265 apex_available: [ "myapex" ], 8266 } 8267 `, withManifestPackageNameOverrides([]string{"AppFoo:com.android.foo"})) 8268 8269 bundleConfigRule := ctx.ModuleForTests("myapex", "android_common_myapex").Output("bundle_config.json") 8270 content := android.ContentFromFileRuleForTests(t, ctx, bundleConfigRule) 8271 8272 ensureContains(t, content, `"compression":{"uncompressed_glob":["apex_payload.img","apex_manifest.*"]}`) 8273 ensureContains(t, content, `"apex_config":{"apex_embedded_apk_config":[{"package_name":"com.android.foo","path":"app/AppFoo@TEST.BUILD_ID/AppFoo.apk"}]}`) 8274} 8275 8276func TestAppSetBundle(t *testing.T) { 8277 t.Parallel() 8278 ctx := testApex(t, ` 8279 apex { 8280 name: "myapex", 8281 key: "myapex.key", 8282 apps: ["AppSet"], 8283 updatable: false, 8284 } 8285 8286 apex_key { 8287 name: "myapex.key", 8288 public_key: "testkey.avbpubkey", 8289 private_key: "testkey.pem", 8290 } 8291 8292 android_app_set { 8293 name: "AppSet", 8294 set: "AppSet.apks", 8295 }`) 8296 mod := ctx.ModuleForTests("myapex", "android_common_myapex") 8297 bundleConfigRule := mod.Output("bundle_config.json") 8298 content := android.ContentFromFileRuleForTests(t, ctx, bundleConfigRule) 8299 ensureContains(t, content, `"compression":{"uncompressed_glob":["apex_payload.img","apex_manifest.*"]}`) 8300 s := mod.Rule("apexRule").Args["copy_commands"] 8301 copyCmds := regexp.MustCompile(" *&& *").Split(s, -1) 8302 if len(copyCmds) != 4 { 8303 t.Fatalf("Expected 4 commands, got %d in:\n%s", len(copyCmds), s) 8304 } 8305 ensureMatches(t, copyCmds[0], "^rm -rf .*/app/AppSet@TEST.BUILD_ID$") 8306 ensureMatches(t, copyCmds[1], "^mkdir -p .*/app/AppSet@TEST.BUILD_ID$") 8307 ensureMatches(t, copyCmds[2], "^cp -f .*/app/AppSet@TEST.BUILD_ID/AppSet.apk$") 8308 ensureMatches(t, copyCmds[3], "^unzip .*-d .*/app/AppSet@TEST.BUILD_ID .*/AppSet.zip$") 8309 8310 // Ensure that canned_fs_config has an entry for the app set zip file 8311 generateFsRule := mod.Rule("generateFsConfig") 8312 cmd := generateFsRule.RuleParams.Command 8313 ensureContains(t, cmd, "AppSet.zip") 8314} 8315 8316func TestAppSetBundlePrebuilt(t *testing.T) { 8317 bp := ` 8318 apex_set { 8319 name: "myapex", 8320 filename: "foo_v2.apex", 8321 sanitized: { 8322 none: { set: "myapex.apks", }, 8323 hwaddress: { set: "myapex.hwasan.apks", }, 8324 }, 8325 } 8326 ` 8327 ctx := testApex(t, bp, prepareForTestWithSantitizeHwaddress) 8328 8329 // Check that the extractor produces the correct output file from the correct input file. 8330 extractorOutput := "out/soong/.intermediates/myapex/android_common_myapex/extracted/myapex.hwasan.apks" 8331 8332 m := ctx.ModuleForTests("myapex", "android_common_myapex") 8333 extractedApex := m.Output(extractorOutput) 8334 8335 android.AssertArrayString(t, "extractor input", []string{"myapex.hwasan.apks"}, extractedApex.Inputs.Strings()) 8336 8337 // Ditto for the apex. 8338 m = ctx.ModuleForTests("myapex", "android_common_myapex") 8339 copiedApex := m.Output("out/soong/.intermediates/myapex/android_common_myapex/foo_v2.apex") 8340 8341 android.AssertStringEquals(t, "myapex input", extractorOutput, copiedApex.Input.String()) 8342} 8343 8344func TestApexSetApksModuleAssignment(t *testing.T) { 8345 t.Parallel() 8346 ctx := testApex(t, ` 8347 apex_set { 8348 name: "myapex", 8349 set: ":myapex_apks_file", 8350 } 8351 8352 filegroup { 8353 name: "myapex_apks_file", 8354 srcs: ["myapex.apks"], 8355 } 8356 `) 8357 8358 m := ctx.ModuleForTests("myapex", "android_common_myapex") 8359 8360 // Check that the extractor produces the correct apks file from the input module 8361 extractorOutput := "out/soong/.intermediates/myapex/android_common_myapex/extracted/myapex.apks" 8362 extractedApex := m.Output(extractorOutput) 8363 8364 android.AssertArrayString(t, "extractor input", []string{"myapex.apks"}, extractedApex.Inputs.Strings()) 8365} 8366 8367func testDexpreoptWithApexes(t *testing.T, bp, errmsg string, preparer android.FixturePreparer, fragments ...java.ApexVariantReference) *android.TestContext { 8368 t.Helper() 8369 8370 fs := android.MockFS{ 8371 "a.java": nil, 8372 "a.jar": nil, 8373 "apex_manifest.json": nil, 8374 "AndroidManifest.xml": nil, 8375 "system/sepolicy/apex/myapex-file_contexts": nil, 8376 "system/sepolicy/apex/some-updatable-apex-file_contexts": nil, 8377 "system/sepolicy/apex/some-non-updatable-apex-file_contexts": nil, 8378 "system/sepolicy/apex/com.android.art.debug-file_contexts": nil, 8379 "framework/aidl/a.aidl": nil, 8380 } 8381 8382 errorHandler := android.FixtureExpectsNoErrors 8383 if errmsg != "" { 8384 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(errmsg) 8385 } 8386 8387 result := android.GroupFixturePreparers( 8388 cc.PrepareForTestWithCcDefaultModules, 8389 java.PrepareForTestWithHiddenApiBuildComponents, 8390 java.PrepareForTestWithDexpreopt, 8391 java.PrepareForTestWithJavaSdkLibraryFiles, 8392 PrepareForTestWithApexBuildComponents, 8393 preparer, 8394 fs.AddToFixture(), 8395 android.FixtureModifyMockFS(func(fs android.MockFS) { 8396 if _, ok := fs["frameworks/base/boot/Android.bp"]; !ok { 8397 insert := "" 8398 for _, fragment := range fragments { 8399 insert += fmt.Sprintf("{apex: %q, module: %q},\n", *fragment.Apex, *fragment.Module) 8400 } 8401 fs["frameworks/base/boot/Android.bp"] = []byte(fmt.Sprintf(` 8402 platform_bootclasspath { 8403 name: "platform-bootclasspath", 8404 fragments: [ 8405 {apex: "com.android.art", module: "art-bootclasspath-fragment"}, 8406 %s 8407 ], 8408 } 8409 `, insert)) 8410 } 8411 }), 8412 // Dexpreopt for boot jars requires the ART boot image profile. 8413 java.PrepareApexBootJarModule("com.android.art", "core-oj"), 8414 dexpreopt.FixtureSetArtBootJars("com.android.art:core-oj"), 8415 dexpreopt.FixtureSetBootImageProfiles("art/build/boot/boot-image-profile.txt"), 8416 ). 8417 ExtendWithErrorHandler(errorHandler). 8418 RunTestWithBp(t, bp) 8419 8420 return result.TestContext 8421} 8422 8423func TestUpdatable_should_set_min_sdk_version(t *testing.T) { 8424 t.Parallel() 8425 testApexError(t, `"myapex" .*: updatable: updatable APEXes should set min_sdk_version`, ` 8426 apex { 8427 name: "myapex", 8428 key: "myapex.key", 8429 updatable: true, 8430 } 8431 8432 apex_key { 8433 name: "myapex.key", 8434 public_key: "testkey.avbpubkey", 8435 private_key: "testkey.pem", 8436 } 8437 `) 8438} 8439 8440func TestUpdatableDefault_should_set_min_sdk_version(t *testing.T) { 8441 t.Parallel() 8442 testApexError(t, `"myapex" .*: updatable: updatable APEXes should set min_sdk_version`, ` 8443 apex { 8444 name: "myapex", 8445 key: "myapex.key", 8446 } 8447 8448 apex_key { 8449 name: "myapex.key", 8450 public_key: "testkey.avbpubkey", 8451 private_key: "testkey.pem", 8452 } 8453 `) 8454} 8455 8456func TestUpdatable_should_not_set_generate_classpaths_proto(t *testing.T) { 8457 t.Parallel() 8458 testApexError(t, `"mysystemserverclasspathfragment" .* it must not set generate_classpaths_proto to false`, ` 8459 apex { 8460 name: "myapex", 8461 key: "myapex.key", 8462 systemserverclasspath_fragments: [ 8463 "mysystemserverclasspathfragment", 8464 ], 8465 min_sdk_version: "29", 8466 updatable: true, 8467 } 8468 8469 apex_key { 8470 name: "myapex.key", 8471 public_key: "testkey.avbpubkey", 8472 private_key: "testkey.pem", 8473 } 8474 8475 java_library { 8476 name: "foo", 8477 srcs: ["b.java"], 8478 min_sdk_version: "29", 8479 installable: true, 8480 apex_available: [ 8481 "myapex", 8482 ], 8483 sdk_version: "current", 8484 } 8485 8486 systemserverclasspath_fragment { 8487 name: "mysystemserverclasspathfragment", 8488 generate_classpaths_proto: false, 8489 contents: [ 8490 "foo", 8491 ], 8492 apex_available: [ 8493 "myapex", 8494 ], 8495 } 8496 `, 8497 dexpreopt.FixtureSetApexSystemServerJars("myapex:foo"), 8498 ) 8499} 8500 8501func TestDexpreoptAccessDexFilesFromPrebuiltApex(t *testing.T) { 8502 t.Parallel() 8503 preparer := java.FixtureConfigureApexBootJars("myapex:libfoo") 8504 t.Run("prebuilt no source", func(t *testing.T) { 8505 t.Parallel() 8506 fragment := java.ApexVariantReference{ 8507 Apex: proptools.StringPtr("myapex"), 8508 Module: proptools.StringPtr("my-bootclasspath-fragment"), 8509 } 8510 8511 testDexpreoptWithApexes(t, ` 8512 prebuilt_apex { 8513 name: "myapex" , 8514 arch: { 8515 arm64: { 8516 src: "myapex-arm64.apex", 8517 }, 8518 arm: { 8519 src: "myapex-arm.apex", 8520 }, 8521 }, 8522 exported_bootclasspath_fragments: ["my-bootclasspath-fragment"], 8523 } 8524 8525 prebuilt_bootclasspath_fragment { 8526 name: "my-bootclasspath-fragment", 8527 contents: ["libfoo"], 8528 apex_available: ["myapex"], 8529 hidden_api: { 8530 annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", 8531 metadata: "my-bootclasspath-fragment/metadata.csv", 8532 index: "my-bootclasspath-fragment/index.csv", 8533 signature_patterns: "my-bootclasspath-fragment/signature-patterns.csv", 8534 filtered_stub_flags: "my-bootclasspath-fragment/filtered-stub-flags.csv", 8535 filtered_flags: "my-bootclasspath-fragment/filtered-flags.csv", 8536 }, 8537 } 8538 8539 java_sdk_library_import { 8540 name: "libfoo", 8541 prefer: true, 8542 public: { 8543 jars: ["libfoo.jar"], 8544 }, 8545 apex_available: ["myapex"], 8546 shared_library: false, 8547 permitted_packages: ["libfoo"], 8548 } 8549 `, "", preparer, fragment) 8550 }) 8551} 8552 8553func testBootJarPermittedPackagesRules(t *testing.T, errmsg, bp string, bootJars []string, rules []android.Rule) { 8554 t.Helper() 8555 bp += ` 8556 apex_key { 8557 name: "myapex.key", 8558 public_key: "testkey.avbpubkey", 8559 private_key: "testkey.pem", 8560 }` 8561 fs := android.MockFS{ 8562 "lib1/src/A.java": nil, 8563 "lib2/src/B.java": nil, 8564 "system/sepolicy/apex/myapex-file_contexts": nil, 8565 } 8566 8567 errorHandler := android.FixtureExpectsNoErrors 8568 if errmsg != "" { 8569 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(errmsg) 8570 } 8571 8572 android.GroupFixturePreparers( 8573 android.PrepareForTestWithAndroidBuildComponents, 8574 java.PrepareForTestWithJavaBuildComponents, 8575 PrepareForTestWithApexBuildComponents, 8576 android.PrepareForTestWithNeverallowRules(rules), 8577 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 8578 apexBootJars := make([]string, 0, len(bootJars)) 8579 for _, apexBootJar := range bootJars { 8580 apexBootJars = append(apexBootJars, "myapex:"+apexBootJar) 8581 } 8582 variables.ApexBootJars = android.CreateTestConfiguredJarList(apexBootJars) 8583 }), 8584 fs.AddToFixture(), 8585 ). 8586 ExtendWithErrorHandler(errorHandler). 8587 RunTestWithBp(t, bp) 8588} 8589 8590func TestApexPermittedPackagesRules(t *testing.T) { 8591 t.Parallel() 8592 testcases := []struct { 8593 name string 8594 expectedError string 8595 bp string 8596 bootJars []string 8597 bcpPermittedPackages map[string][]string 8598 }{ 8599 8600 { 8601 name: "Non-Bootclasspath apex jar not satisfying allowed module packages.", 8602 expectedError: "", 8603 bp: ` 8604 java_library { 8605 name: "bcp_lib1", 8606 srcs: ["lib1/src/*.java"], 8607 permitted_packages: ["foo.bar"], 8608 apex_available: ["myapex"], 8609 sdk_version: "none", 8610 system_modules: "none", 8611 compile_dex: true, 8612 } 8613 java_library { 8614 name: "nonbcp_lib2", 8615 srcs: ["lib2/src/*.java"], 8616 apex_available: ["myapex"], 8617 permitted_packages: ["a.b"], 8618 sdk_version: "none", 8619 system_modules: "none", 8620 compile_dex: true, 8621 } 8622 apex { 8623 name: "myapex", 8624 key: "myapex.key", 8625 java_libs: ["bcp_lib1", "nonbcp_lib2"], 8626 updatable: false, 8627 }`, 8628 bootJars: []string{"bcp_lib1"}, 8629 bcpPermittedPackages: map[string][]string{ 8630 "bcp_lib1": []string{ 8631 "foo.bar", 8632 }, 8633 }, 8634 }, 8635 { 8636 name: "Bootclasspath apex jar not satisfying allowed module packages.", 8637 expectedError: `(?s)module "bcp_lib2" .* which is restricted because bcp_lib2 bootjar may only use these package prefixes: foo.bar. Please consider the following alternatives:\n 1. If the offending code is from a statically linked library, consider removing that dependency and using an alternative already in the bootclasspath, or perhaps a shared library. 2. Move the offending code into an allowed package.\n 3. Jarjar the offending code. Please be mindful of the potential system health implications of bundling that code, particularly if the offending jar is part of the bootclasspath.`, 8638 bp: ` 8639 java_library { 8640 name: "bcp_lib1", 8641 srcs: ["lib1/src/*.java"], 8642 apex_available: ["myapex"], 8643 permitted_packages: ["foo.bar"], 8644 sdk_version: "none", 8645 system_modules: "none", 8646 compile_dex: true, 8647 } 8648 java_library { 8649 name: "bcp_lib2", 8650 srcs: ["lib2/src/*.java"], 8651 apex_available: ["myapex"], 8652 permitted_packages: ["foo.bar", "bar.baz"], 8653 sdk_version: "none", 8654 system_modules: "none", 8655 compile_dex: true, 8656 } 8657 apex { 8658 name: "myapex", 8659 key: "myapex.key", 8660 java_libs: ["bcp_lib1", "bcp_lib2"], 8661 updatable: false, 8662 } 8663 `, 8664 bootJars: []string{"bcp_lib1", "bcp_lib2"}, 8665 bcpPermittedPackages: map[string][]string{ 8666 "bcp_lib1": []string{ 8667 "foo.bar", 8668 }, 8669 "bcp_lib2": []string{ 8670 "foo.bar", 8671 }, 8672 }, 8673 }, 8674 { 8675 name: "Updateable Bootclasspath apex jar not satisfying allowed module packages.", 8676 expectedError: "", 8677 bp: ` 8678 java_library { 8679 name: "bcp_lib_restricted", 8680 srcs: ["lib1/src/*.java"], 8681 apex_available: ["myapex"], 8682 permitted_packages: ["foo.bar"], 8683 sdk_version: "none", 8684 min_sdk_version: "29", 8685 system_modules: "none", 8686 compile_dex: true, 8687 } 8688 java_library { 8689 name: "bcp_lib_unrestricted", 8690 srcs: ["lib2/src/*.java"], 8691 apex_available: ["myapex"], 8692 permitted_packages: ["foo.bar", "bar.baz"], 8693 sdk_version: "none", 8694 min_sdk_version: "29", 8695 system_modules: "none", 8696 compile_dex: true, 8697 } 8698 apex { 8699 name: "myapex", 8700 key: "myapex.key", 8701 java_libs: ["bcp_lib_restricted", "bcp_lib_unrestricted"], 8702 updatable: true, 8703 min_sdk_version: "29", 8704 } 8705 `, 8706 bootJars: []string{"bcp_lib1", "bcp_lib2"}, 8707 bcpPermittedPackages: map[string][]string{ 8708 "bcp_lib1_non_updateable": []string{ 8709 "foo.bar", 8710 }, 8711 // bcp_lib2_updateable has no entry here since updateable bcp can contain new packages - tracking via an allowlist is not necessary 8712 }, 8713 }, 8714 } 8715 for _, tc := range testcases { 8716 t.Run(tc.name, func(t *testing.T) { 8717 t.Parallel() 8718 rules := createBcpPermittedPackagesRules(tc.bcpPermittedPackages) 8719 testBootJarPermittedPackagesRules(t, tc.expectedError, tc.bp, tc.bootJars, rules) 8720 }) 8721 } 8722} 8723 8724// TODO(jungjw): Move this to proptools 8725func intPtr(i int) *int { 8726 return &i 8727} 8728 8729func TestApexSet(t *testing.T) { 8730 t.Parallel() 8731 ctx := testApex(t, ` 8732 apex_set { 8733 name: "myapex", 8734 set: "myapex.apks", 8735 filename: "foo_v2.apex", 8736 overrides: ["foo"], 8737 } 8738 `, 8739 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 8740 variables.Platform_sdk_version = intPtr(30) 8741 }), 8742 android.FixtureModifyConfig(func(config android.Config) { 8743 config.Targets[android.Android] = []android.Target{ 8744 {Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}}, 8745 {Os: android.Android, Arch: android.Arch{ArchType: android.Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}}, 8746 } 8747 }), 8748 ) 8749 8750 m := ctx.ModuleForTests("myapex", "android_common_myapex") 8751 8752 // Check extract_apks tool parameters. 8753 extractedApex := m.Output("extracted/myapex.apks") 8754 actual := extractedApex.Args["abis"] 8755 expected := "ARMEABI_V7A,ARM64_V8A" 8756 if actual != expected { 8757 t.Errorf("Unexpected abis parameter - expected %q vs actual %q", expected, actual) 8758 } 8759 actual = extractedApex.Args["sdk-version"] 8760 expected = "30" 8761 if actual != expected { 8762 t.Errorf("Unexpected abis parameter - expected %q vs actual %q", expected, actual) 8763 } 8764 8765 m = ctx.ModuleForTests("myapex", "android_common_myapex") 8766 a := m.Module().(*ApexSet) 8767 expectedOverrides := []string{"foo"} 8768 actualOverrides := android.AndroidMkEntriesForTest(t, ctx, a)[0].EntryMap["LOCAL_OVERRIDES_MODULES"] 8769 if !reflect.DeepEqual(actualOverrides, expectedOverrides) { 8770 t.Errorf("Incorrect LOCAL_OVERRIDES_MODULES - expected %q vs actual %q", expectedOverrides, actualOverrides) 8771 } 8772} 8773 8774func TestApexSet_NativeBridge(t *testing.T) { 8775 t.Parallel() 8776 ctx := testApex(t, ` 8777 apex_set { 8778 name: "myapex", 8779 set: "myapex.apks", 8780 filename: "foo_v2.apex", 8781 overrides: ["foo"], 8782 } 8783 `, 8784 android.FixtureModifyConfig(func(config android.Config) { 8785 config.Targets[android.Android] = []android.Target{ 8786 {Os: android.Android, Arch: android.Arch{ArchType: android.X86_64, ArchVariant: "", Abi: []string{"x86_64"}}}, 8787 {Os: android.Android, Arch: android.Arch{ArchType: android.Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridge: android.NativeBridgeEnabled}, 8788 } 8789 }), 8790 ) 8791 8792 m := ctx.ModuleForTests("myapex", "android_common_myapex") 8793 8794 // Check extract_apks tool parameters. No native bridge arch expected 8795 extractedApex := m.Output("extracted/myapex.apks") 8796 android.AssertStringEquals(t, "abis", "X86_64", extractedApex.Args["abis"]) 8797} 8798 8799func TestNoStaticLinkingToStubsLib(t *testing.T) { 8800 t.Parallel() 8801 testApexError(t, `.*required by "mylib" is a native library providing stub.*`, ` 8802 apex { 8803 name: "myapex", 8804 key: "myapex.key", 8805 native_shared_libs: ["mylib"], 8806 updatable: false, 8807 } 8808 8809 apex_key { 8810 name: "myapex.key", 8811 public_key: "testkey.avbpubkey", 8812 private_key: "testkey.pem", 8813 } 8814 8815 cc_library { 8816 name: "mylib", 8817 srcs: ["mylib.cpp"], 8818 static_libs: ["otherlib"], 8819 system_shared_libs: [], 8820 stl: "none", 8821 apex_available: [ "myapex" ], 8822 } 8823 8824 cc_library { 8825 name: "otherlib", 8826 srcs: ["mylib.cpp"], 8827 system_shared_libs: [], 8828 stl: "none", 8829 stubs: { 8830 versions: ["1", "2", "3"], 8831 }, 8832 apex_available: [ "myapex" ], 8833 } 8834 `) 8835} 8836 8837func TestApexKeysTxt(t *testing.T) { 8838 t.Parallel() 8839 ctx := testApex(t, ` 8840 apex { 8841 name: "myapex", 8842 key: "myapex.key", 8843 updatable: false, 8844 custom_sign_tool: "sign_myapex", 8845 } 8846 8847 apex_key { 8848 name: "myapex.key", 8849 public_key: "testkey.avbpubkey", 8850 private_key: "testkey.pem", 8851 } 8852 `) 8853 8854 myapex := ctx.ModuleForTests("myapex", "android_common_myapex") 8855 content := android.ContentFromFileRuleForTests(t, ctx, myapex.Output("apexkeys.txt")) 8856 ensureContains(t, content, `name="myapex.apex" public_key="vendor/foo/devkeys/testkey.avbpubkey" private_key="vendor/foo/devkeys/testkey.pem" container_certificate="vendor/foo/devkeys/test.x509.pem" container_private_key="vendor/foo/devkeys/test.pk8" partition="system" sign_tool="sign_myapex"`) 8857} 8858 8859func TestApexKeysTxtOverrides(t *testing.T) { 8860 t.Parallel() 8861 ctx := testApex(t, ` 8862 apex { 8863 name: "myapex", 8864 key: "myapex.key", 8865 updatable: false, 8866 custom_sign_tool: "sign_myapex", 8867 } 8868 8869 apex_key { 8870 name: "myapex.key", 8871 public_key: "testkey.avbpubkey", 8872 private_key: "testkey.pem", 8873 } 8874 8875 prebuilt_apex { 8876 name: "myapex", 8877 prefer: true, 8878 arch: { 8879 arm64: { 8880 src: "myapex-arm64.apex", 8881 }, 8882 arm: { 8883 src: "myapex-arm.apex", 8884 }, 8885 }, 8886 } 8887 8888 apex_set { 8889 name: "myapex_set", 8890 set: "myapex.apks", 8891 filename: "myapex_set.apex", 8892 overrides: ["myapex"], 8893 } 8894 `) 8895 8896 content := android.ContentFromFileRuleForTests(t, ctx, 8897 ctx.ModuleForTests("myapex", "android_common_myapex").Output("apexkeys.txt")) 8898 ensureContains(t, content, `name="myapex.apex" public_key="vendor/foo/devkeys/testkey.avbpubkey" private_key="vendor/foo/devkeys/testkey.pem" container_certificate="vendor/foo/devkeys/test.x509.pem" container_private_key="vendor/foo/devkeys/test.pk8" partition="system" sign_tool="sign_myapex"`) 8899 content = android.ContentFromFileRuleForTests(t, ctx, 8900 ctx.ModuleForTests("myapex_set", "android_common_myapex_set").Output("apexkeys.txt")) 8901 ensureContains(t, content, `name="myapex_set.apex" public_key="PRESIGNED" private_key="PRESIGNED" container_certificate="PRESIGNED" container_private_key="PRESIGNED" partition="system"`) 8902} 8903 8904func TestAllowedFiles(t *testing.T) { 8905 t.Parallel() 8906 ctx := testApex(t, ` 8907 apex { 8908 name: "myapex", 8909 key: "myapex.key", 8910 apps: ["app"], 8911 allowed_files: "allowed.txt", 8912 updatable: false, 8913 } 8914 8915 apex_key { 8916 name: "myapex.key", 8917 public_key: "testkey.avbpubkey", 8918 private_key: "testkey.pem", 8919 } 8920 8921 android_app { 8922 name: "app", 8923 srcs: ["foo/bar/MyClass.java"], 8924 package_name: "foo", 8925 sdk_version: "none", 8926 system_modules: "none", 8927 apex_available: [ "myapex" ], 8928 } 8929 `, withFiles(map[string][]byte{ 8930 "sub/Android.bp": []byte(` 8931 override_apex { 8932 name: "override_myapex", 8933 base: "myapex", 8934 apps: ["override_app"], 8935 allowed_files: ":allowed", 8936 } 8937 // Overridable "path" property should be referenced indirectly 8938 filegroup { 8939 name: "allowed", 8940 srcs: ["allowed.txt"], 8941 } 8942 override_android_app { 8943 name: "override_app", 8944 base: "app", 8945 package_name: "bar", 8946 } 8947 `), 8948 })) 8949 8950 rule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("diffApexContentRule") 8951 if expected, actual := "allowed.txt", rule.Args["allowed_files_file"]; expected != actual { 8952 t.Errorf("allowed_files_file: expected %q but got %q", expected, actual) 8953 } 8954 8955 rule2 := ctx.ModuleForTests("myapex", "android_common_override_myapex_override_myapex").Rule("diffApexContentRule") 8956 if expected, actual := "sub/allowed.txt", rule2.Args["allowed_files_file"]; expected != actual { 8957 t.Errorf("allowed_files_file: expected %q but got %q", expected, actual) 8958 } 8959} 8960 8961func TestNonPreferredPrebuiltDependency(t *testing.T) { 8962 t.Parallel() 8963 testApex(t, ` 8964 apex { 8965 name: "myapex", 8966 key: "myapex.key", 8967 native_shared_libs: ["mylib"], 8968 updatable: false, 8969 } 8970 8971 apex_key { 8972 name: "myapex.key", 8973 public_key: "testkey.avbpubkey", 8974 private_key: "testkey.pem", 8975 } 8976 8977 cc_library { 8978 name: "mylib", 8979 srcs: ["mylib.cpp"], 8980 stubs: { 8981 versions: ["current"], 8982 }, 8983 apex_available: ["myapex"], 8984 } 8985 8986 cc_prebuilt_library_shared { 8987 name: "mylib", 8988 prefer: false, 8989 srcs: ["prebuilt.so"], 8990 stubs: { 8991 versions: ["current"], 8992 }, 8993 apex_available: ["myapex"], 8994 } 8995 `) 8996} 8997 8998func TestCompressedApex(t *testing.T) { 8999 t.Parallel() 9000 ctx := testApex(t, ` 9001 apex { 9002 name: "myapex", 9003 key: "myapex.key", 9004 compressible: true, 9005 updatable: false, 9006 } 9007 apex_key { 9008 name: "myapex.key", 9009 public_key: "testkey.avbpubkey", 9010 private_key: "testkey.pem", 9011 } 9012 `, 9013 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 9014 variables.CompressedApex = proptools.BoolPtr(true) 9015 }), 9016 ) 9017 9018 compressRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("compressRule") 9019 ensureContains(t, compressRule.Output.String(), "myapex.capex.unsigned") 9020 9021 signApkRule := ctx.ModuleForTests("myapex", "android_common_myapex").Description("sign compressedApex") 9022 ensureEquals(t, signApkRule.Input.String(), compressRule.Output.String()) 9023 9024 // Make sure output of bundle is .capex 9025 ab := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle) 9026 ensureContains(t, ab.outputFile.String(), "myapex.capex") 9027 9028 // Verify android.mk rules 9029 data := android.AndroidMkDataForTest(t, ctx, ab) 9030 var builder strings.Builder 9031 data.Custom(&builder, ab.BaseModuleName(), "TARGET_", "", data) 9032 androidMk := builder.String() 9033 ensureContains(t, androidMk, "LOCAL_MODULE_STEM := myapex.capex\n") 9034} 9035 9036func TestCompressedApexIsDisabledWhenUsingErofs(t *testing.T) { 9037 t.Parallel() 9038 ctx := testApex(t, ` 9039 apex { 9040 name: "myapex", 9041 key: "myapex.key", 9042 compressible: true, 9043 updatable: false, 9044 payload_fs_type: "erofs", 9045 } 9046 apex_key { 9047 name: "myapex.key", 9048 public_key: "testkey.avbpubkey", 9049 private_key: "testkey.pem", 9050 } 9051 `, 9052 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 9053 variables.CompressedApex = proptools.BoolPtr(true) 9054 }), 9055 ) 9056 9057 compressRule := ctx.ModuleForTests("myapex", "android_common_myapex").MaybeRule("compressRule") 9058 if compressRule.Rule != nil { 9059 t.Error("erofs apex should not be compressed") 9060 } 9061} 9062 9063func TestApexSet_ShouldRespectCompressedApexFlag(t *testing.T) { 9064 t.Parallel() 9065 for _, compressionEnabled := range []bool{true, false} { 9066 t.Run(fmt.Sprintf("compressionEnabled=%v", compressionEnabled), func(t *testing.T) { 9067 t.Parallel() 9068 ctx := testApex(t, ` 9069 apex_set { 9070 name: "com.company.android.myapex", 9071 apex_name: "com.android.myapex", 9072 set: "company-myapex.apks", 9073 } 9074 `, android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 9075 variables.CompressedApex = proptools.BoolPtr(compressionEnabled) 9076 }), 9077 ) 9078 9079 build := ctx.ModuleForTests("com.company.android.myapex", "android_common_com.android.myapex").Output("com.company.android.myapex.apex") 9080 if compressionEnabled { 9081 ensureEquals(t, build.Rule.String(), "android/soong/android.Cp") 9082 } else { 9083 ensureEquals(t, build.Rule.String(), "android/apex.decompressApex") 9084 } 9085 }) 9086 } 9087} 9088 9089func TestPreferredPrebuiltSharedLibDep(t *testing.T) { 9090 t.Parallel() 9091 ctx := testApex(t, ` 9092 apex { 9093 name: "myapex", 9094 key: "myapex.key", 9095 native_shared_libs: ["mylib"], 9096 updatable: false, 9097 } 9098 9099 apex_key { 9100 name: "myapex.key", 9101 public_key: "testkey.avbpubkey", 9102 private_key: "testkey.pem", 9103 } 9104 9105 cc_library { 9106 name: "mylib", 9107 srcs: ["mylib.cpp"], 9108 apex_available: ["myapex"], 9109 shared_libs: ["otherlib"], 9110 system_shared_libs: [], 9111 } 9112 9113 cc_library { 9114 name: "otherlib", 9115 srcs: ["mylib.cpp"], 9116 stubs: { 9117 versions: ["current"], 9118 }, 9119 } 9120 9121 cc_prebuilt_library_shared { 9122 name: "otherlib", 9123 prefer: true, 9124 srcs: ["prebuilt.so"], 9125 stubs: { 9126 versions: ["current"], 9127 }, 9128 } 9129 `) 9130 9131 ab := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle) 9132 data := android.AndroidMkDataForTest(t, ctx, ab) 9133 var builder strings.Builder 9134 data.Custom(&builder, ab.BaseModuleName(), "TARGET_", "", data) 9135 androidMk := builder.String() 9136 9137 // The make level dependency needs to be on otherlib - prebuilt_otherlib isn't 9138 // a thing there. 9139 ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := libc++:64 mylib.myapex:64 otherlib\n") 9140} 9141 9142func TestExcludeDependency(t *testing.T) { 9143 t.Parallel() 9144 ctx := testApex(t, ` 9145 apex { 9146 name: "myapex", 9147 key: "myapex.key", 9148 native_shared_libs: ["mylib"], 9149 updatable: false, 9150 } 9151 9152 apex_key { 9153 name: "myapex.key", 9154 public_key: "testkey.avbpubkey", 9155 private_key: "testkey.pem", 9156 } 9157 9158 cc_library { 9159 name: "mylib", 9160 srcs: ["mylib.cpp"], 9161 system_shared_libs: [], 9162 stl: "none", 9163 apex_available: ["myapex"], 9164 shared_libs: ["mylib2"], 9165 target: { 9166 apex: { 9167 exclude_shared_libs: ["mylib2"], 9168 }, 9169 }, 9170 } 9171 9172 cc_library { 9173 name: "mylib2", 9174 srcs: ["mylib.cpp"], 9175 system_shared_libs: [], 9176 stl: "none", 9177 } 9178 `) 9179 9180 // Check if mylib is linked to mylib2 for the non-apex target 9181 ldFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared").Rule("ld").Args["libFlags"] 9182 ensureContains(t, ldFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so") 9183 9184 // Make sure that the link doesn't occur for the apex target 9185 ldFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"] 9186 ensureNotContains(t, ldFlags, "mylib2/android_arm64_armv8-a_shared_apex10000/mylib2.so") 9187 9188 // It shouldn't appear in the copy cmd as well. 9189 copyCmds := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule").Args["copy_commands"] 9190 ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so") 9191} 9192 9193func TestPrebuiltStubLibDep(t *testing.T) { 9194 t.Parallel() 9195 bpBase := ` 9196 apex { 9197 name: "myapex", 9198 key: "myapex.key", 9199 native_shared_libs: ["mylib"], 9200 updatable: false, 9201 } 9202 apex_key { 9203 name: "myapex.key", 9204 public_key: "testkey.avbpubkey", 9205 private_key: "testkey.pem", 9206 } 9207 cc_library { 9208 name: "mylib", 9209 srcs: ["mylib.cpp"], 9210 apex_available: ["myapex"], 9211 shared_libs: ["stublib"], 9212 system_shared_libs: [], 9213 } 9214 apex { 9215 name: "otherapex", 9216 enabled: %s, 9217 key: "myapex.key", 9218 native_shared_libs: ["stublib"], 9219 updatable: false, 9220 } 9221 ` 9222 9223 stublibSourceBp := ` 9224 cc_library { 9225 name: "stublib", 9226 srcs: ["mylib.cpp"], 9227 apex_available: ["otherapex"], 9228 system_shared_libs: [], 9229 stl: "none", 9230 stubs: { 9231 versions: ["1"], 9232 }, 9233 } 9234 ` 9235 9236 stublibPrebuiltBp := ` 9237 cc_prebuilt_library_shared { 9238 name: "stublib", 9239 srcs: ["prebuilt.so"], 9240 apex_available: ["otherapex"], 9241 stubs: { 9242 versions: ["1"], 9243 }, 9244 %s 9245 } 9246 ` 9247 9248 tests := []struct { 9249 name string 9250 stublibBp string 9251 usePrebuilt bool 9252 modNames []string // Modules to collect AndroidMkEntries for 9253 otherApexEnabled []string 9254 }{ 9255 { 9256 name: "only_source", 9257 stublibBp: stublibSourceBp, 9258 usePrebuilt: false, 9259 modNames: []string{"stublib"}, 9260 otherApexEnabled: []string{"true", "false"}, 9261 }, 9262 { 9263 name: "source_preferred", 9264 stublibBp: stublibSourceBp + fmt.Sprintf(stublibPrebuiltBp, ""), 9265 usePrebuilt: false, 9266 modNames: []string{"stublib", "prebuilt_stublib"}, 9267 otherApexEnabled: []string{"true", "false"}, 9268 }, 9269 { 9270 name: "prebuilt_preferred", 9271 stublibBp: stublibSourceBp + fmt.Sprintf(stublibPrebuiltBp, "prefer: true,"), 9272 usePrebuilt: true, 9273 modNames: []string{"stublib", "prebuilt_stublib"}, 9274 otherApexEnabled: []string{"false"}, // No "true" since APEX cannot depend on prebuilt. 9275 }, 9276 { 9277 name: "only_prebuilt", 9278 stublibBp: fmt.Sprintf(stublibPrebuiltBp, ""), 9279 usePrebuilt: true, 9280 modNames: []string{"stublib"}, 9281 otherApexEnabled: []string{"false"}, // No "true" since APEX cannot depend on prebuilt. 9282 }, 9283 } 9284 9285 for _, test := range tests { 9286 t.Run(test.name, func(t *testing.T) { 9287 t.Parallel() 9288 for _, otherApexEnabled := range test.otherApexEnabled { 9289 t.Run("otherapex_enabled_"+otherApexEnabled, func(t *testing.T) { 9290 t.Parallel() 9291 ctx := testApex(t, fmt.Sprintf(bpBase, otherApexEnabled)+test.stublibBp) 9292 9293 type modAndMkEntries struct { 9294 mod *cc.Module 9295 mkEntries android.AndroidMkInfo 9296 } 9297 entries := []*modAndMkEntries{} 9298 9299 // Gather shared lib modules that are installable 9300 for _, modName := range test.modNames { 9301 for _, variant := range ctx.ModuleVariantsForTests(modName) { 9302 if !strings.HasPrefix(variant, "android_arm64_armv8-a_shared") { 9303 continue 9304 } 9305 mod := ctx.ModuleForTests(modName, variant).Module().(*cc.Module) 9306 if !mod.Enabled(android.PanickingConfigAndErrorContext(ctx)) || mod.IsHideFromMake() { 9307 continue 9308 } 9309 info := android.AndroidMkInfoForTest(t, ctx, mod) 9310 ents := []android.AndroidMkInfo{info.PrimaryInfo} 9311 ents = append(ents, info.ExtraInfo...) 9312 for _, ent := range ents { 9313 if ent.Disabled { 9314 continue 9315 } 9316 entries = append(entries, &modAndMkEntries{ 9317 mod: mod, 9318 mkEntries: ent, 9319 }) 9320 } 9321 } 9322 } 9323 9324 var entry *modAndMkEntries = nil 9325 for _, ent := range entries { 9326 if strings.Join(ent.mkEntries.EntryMap["LOCAL_MODULE"], ",") == "stublib" { 9327 if entry != nil { 9328 t.Errorf("More than one AndroidMk entry for \"stublib\": %s and %s", entry.mod, ent.mod) 9329 } else { 9330 entry = ent 9331 } 9332 } 9333 } 9334 9335 if entry == nil { 9336 t.Errorf("AndroidMk entry for \"stublib\" missing") 9337 } else { 9338 isPrebuilt := entry.mod.Prebuilt() != nil 9339 if isPrebuilt != test.usePrebuilt { 9340 t.Errorf("Wrong module for \"stublib\" AndroidMk entry: got prebuilt %t, want prebuilt %t", isPrebuilt, test.usePrebuilt) 9341 } 9342 if !entry.mod.IsStubs() { 9343 t.Errorf("Module for \"stublib\" AndroidMk entry isn't a stub: %s", entry.mod) 9344 } 9345 if entry.mkEntries.EntryMap["LOCAL_NOT_AVAILABLE_FOR_PLATFORM"] != nil { 9346 t.Errorf("AndroidMk entry for \"stublib\" has LOCAL_NOT_AVAILABLE_FOR_PLATFORM set: %+v", entry.mkEntries) 9347 } 9348 cflags := entry.mkEntries.EntryMap["LOCAL_EXPORT_CFLAGS"] 9349 expected := "-D__STUBLIB_API__=10000" 9350 if !android.InList(expected, cflags) { 9351 t.Errorf("LOCAL_EXPORT_CFLAGS expected to have %q, but got %q", expected, cflags) 9352 } 9353 } 9354 }) 9355 } 9356 }) 9357 } 9358} 9359 9360func TestApexJavaCoverage(t *testing.T) { 9361 t.Parallel() 9362 bp := ` 9363 apex { 9364 name: "myapex", 9365 key: "myapex.key", 9366 java_libs: ["mylib"], 9367 bootclasspath_fragments: ["mybootclasspathfragment"], 9368 systemserverclasspath_fragments: ["mysystemserverclasspathfragment"], 9369 updatable: false, 9370 } 9371 9372 apex_key { 9373 name: "myapex.key", 9374 public_key: "testkey.avbpubkey", 9375 private_key: "testkey.pem", 9376 } 9377 9378 java_library { 9379 name: "mylib", 9380 srcs: ["mylib.java"], 9381 apex_available: ["myapex"], 9382 compile_dex: true, 9383 } 9384 9385 bootclasspath_fragment { 9386 name: "mybootclasspathfragment", 9387 contents: ["mybootclasspathlib"], 9388 apex_available: ["myapex"], 9389 hidden_api: { 9390 split_packages: ["*"], 9391 }, 9392 } 9393 9394 java_library { 9395 name: "mybootclasspathlib", 9396 srcs: ["mybootclasspathlib.java"], 9397 apex_available: ["myapex"], 9398 compile_dex: true, 9399 sdk_version: "current", 9400 } 9401 9402 systemserverclasspath_fragment { 9403 name: "mysystemserverclasspathfragment", 9404 contents: ["mysystemserverclasspathlib"], 9405 apex_available: ["myapex"], 9406 } 9407 9408 java_library { 9409 name: "mysystemserverclasspathlib", 9410 srcs: ["mysystemserverclasspathlib.java"], 9411 apex_available: ["myapex"], 9412 compile_dex: true, 9413 } 9414 ` 9415 9416 result := android.GroupFixturePreparers( 9417 PrepareForTestWithApexBuildComponents, 9418 prepareForTestWithMyapex, 9419 java.PrepareForTestWithJavaDefaultModules, 9420 android.PrepareForTestWithAndroidBuildComponents, 9421 android.FixtureWithRootAndroidBp(bp), 9422 dexpreopt.FixtureSetApexBootJars("myapex:mybootclasspathlib"), 9423 dexpreopt.FixtureSetApexSystemServerJars("myapex:mysystemserverclasspathlib"), 9424 java.PrepareForTestWithJacocoInstrumentation, 9425 ).RunTest(t) 9426 9427 // Make sure jacoco ran on both mylib and mybootclasspathlib 9428 if result.ModuleForTests("mylib", "android_common_apex10000").MaybeRule("jacoco").Rule == nil { 9429 t.Errorf("Failed to find jacoco rule for mylib") 9430 } 9431 if result.ModuleForTests("mybootclasspathlib", "android_common_apex10000").MaybeRule("jacoco").Rule == nil { 9432 t.Errorf("Failed to find jacoco rule for mybootclasspathlib") 9433 } 9434 if result.ModuleForTests("mysystemserverclasspathlib", "android_common_apex10000").MaybeRule("jacoco").Rule == nil { 9435 t.Errorf("Failed to find jacoco rule for mysystemserverclasspathlib") 9436 } 9437} 9438 9439func TestProhibitStaticExecutable(t *testing.T) { 9440 t.Parallel() 9441 testApexError(t, `executable mybin is static`, ` 9442 apex { 9443 name: "myapex", 9444 key: "myapex.key", 9445 binaries: ["mybin"], 9446 min_sdk_version: "29", 9447 } 9448 9449 apex_key { 9450 name: "myapex.key", 9451 public_key: "testkey.avbpubkey", 9452 private_key: "testkey.pem", 9453 } 9454 9455 cc_binary { 9456 name: "mybin", 9457 srcs: ["mylib.cpp"], 9458 relative_install_path: "foo/bar", 9459 static_executable: true, 9460 system_shared_libs: [], 9461 stl: "none", 9462 apex_available: [ "myapex" ], 9463 min_sdk_version: "29", 9464 } 9465 `) 9466 9467 testApexError(t, `executable mybin.rust is static`, ` 9468 apex { 9469 name: "myapex", 9470 key: "myapex.key", 9471 binaries: ["mybin.rust"], 9472 min_sdk_version: "29", 9473 } 9474 9475 apex_key { 9476 name: "myapex.key", 9477 public_key: "testkey.avbpubkey", 9478 private_key: "testkey.pem", 9479 } 9480 9481 rust_binary { 9482 name: "mybin.rust", 9483 srcs: ["foo.rs"], 9484 static_executable: true, 9485 apex_available: ["myapex"], 9486 min_sdk_version: "29", 9487 } 9488 `) 9489} 9490 9491func TestAndroidMk_DexpreoptBuiltInstalledForApex(t *testing.T) { 9492 t.Parallel() 9493 ctx := testApex(t, ` 9494 apex { 9495 name: "myapex", 9496 key: "myapex.key", 9497 updatable: false, 9498 java_libs: ["foo"], 9499 } 9500 9501 apex_key { 9502 name: "myapex.key", 9503 public_key: "testkey.avbpubkey", 9504 private_key: "testkey.pem", 9505 } 9506 9507 java_library { 9508 name: "foo", 9509 srcs: ["foo.java"], 9510 apex_available: ["myapex"], 9511 installable: true, 9512 } 9513 `, 9514 dexpreopt.FixtureSetApexSystemServerJars("myapex:foo"), 9515 ) 9516 9517 apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle) 9518 data := android.AndroidMkDataForTest(t, ctx, apexBundle) 9519 var builder strings.Builder 9520 data.Custom(&builder, apexBundle.BaseModuleName(), "TARGET_", "", data) 9521 androidMk := builder.String() 9522 ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := foo.myapex foo-dexpreopt-arm64-apex@myapex@[email protected]@classes.odex foo-dexpreopt-arm64-apex@myapex@[email protected]@classes.vdex\n") 9523} 9524 9525func TestAndroidMk_RequiredModules(t *testing.T) { 9526 t.Parallel() 9527 ctx := testApex(t, ` 9528 apex { 9529 name: "myapex", 9530 key: "myapex.key", 9531 updatable: false, 9532 java_libs: ["foo"], 9533 required: ["otherapex"], 9534 } 9535 9536 apex { 9537 name: "otherapex", 9538 key: "myapex.key", 9539 updatable: false, 9540 java_libs: ["foo"], 9541 } 9542 9543 apex_key { 9544 name: "myapex.key", 9545 public_key: "testkey.avbpubkey", 9546 private_key: "testkey.pem", 9547 } 9548 9549 java_library { 9550 name: "foo", 9551 srcs: ["foo.java"], 9552 apex_available: ["myapex", "otherapex"], 9553 installable: true, 9554 } 9555 `) 9556 9557 apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle) 9558 data := android.AndroidMkDataForTest(t, ctx, apexBundle) 9559 var builder strings.Builder 9560 data.Custom(&builder, apexBundle.BaseModuleName(), "TARGET_", "", data) 9561 androidMk := builder.String() 9562 ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := foo.myapex otherapex") 9563} 9564 9565func TestAndroidMk_RequiredDeps(t *testing.T) { 9566 t.Parallel() 9567 ctx := testApex(t, ` 9568 apex { 9569 name: "myapex", 9570 key: "myapex.key", 9571 updatable: false, 9572 } 9573 9574 apex_key { 9575 name: "myapex.key", 9576 public_key: "testkey.avbpubkey", 9577 private_key: "testkey.pem", 9578 } 9579 `) 9580 9581 bundle := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle) 9582 bundle.makeModulesToInstall = append(bundle.makeModulesToInstall, "foo") 9583 data := android.AndroidMkDataForTest(t, ctx, bundle) 9584 var builder strings.Builder 9585 data.Custom(&builder, bundle.BaseModuleName(), "TARGET_", "", data) 9586 androidMk := builder.String() 9587 ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := foo\n") 9588} 9589 9590func TestApexOutputFileProducer(t *testing.T) { 9591 t.Parallel() 9592 for _, tc := range []struct { 9593 name string 9594 ref string 9595 expected_data []string 9596 }{ 9597 { 9598 name: "test_using_output", 9599 ref: ":myapex", 9600 expected_data: []string{"out/soong/.intermediates/myapex/android_common_myapex/myapex.capex:myapex.capex"}, 9601 }, 9602 { 9603 name: "test_using_apex", 9604 ref: ":myapex{.apex}", 9605 expected_data: []string{"out/soong/.intermediates/myapex/android_common_myapex/myapex.apex:myapex.apex"}, 9606 }, 9607 } { 9608 t.Run(tc.name, func(t *testing.T) { 9609 t.Parallel() 9610 ctx := testApex(t, ` 9611 apex { 9612 name: "myapex", 9613 key: "myapex.key", 9614 compressible: true, 9615 updatable: false, 9616 } 9617 9618 apex_key { 9619 name: "myapex.key", 9620 public_key: "testkey.avbpubkey", 9621 private_key: "testkey.pem", 9622 } 9623 9624 java_test { 9625 name: "`+tc.name+`", 9626 srcs: ["a.java"], 9627 data: ["`+tc.ref+`"], 9628 } 9629 `, 9630 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 9631 variables.CompressedApex = proptools.BoolPtr(true) 9632 })) 9633 javaTest := ctx.ModuleForTests(tc.name, "android_common").Module().(*java.Test) 9634 data := android.AndroidMkEntriesForTest(t, ctx, javaTest)[0].EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"] 9635 android.AssertStringPathsRelativeToTopEquals(t, "data", ctx.Config(), tc.expected_data, data) 9636 }) 9637 } 9638} 9639 9640func TestSdkLibraryCanHaveHigherMinSdkVersion(t *testing.T) { 9641 t.Parallel() 9642 preparer := android.GroupFixturePreparers( 9643 PrepareForTestWithApexBuildComponents, 9644 prepareForTestWithMyapex, 9645 java.PrepareForTestWithJavaSdkLibraryFiles, 9646 java.PrepareForTestWithJavaDefaultModules, 9647 android.PrepareForTestWithAndroidBuildComponents, 9648 dexpreopt.FixtureSetApexBootJars("myapex:mybootclasspathlib"), 9649 dexpreopt.FixtureSetApexSystemServerJars("myapex:mysystemserverclasspathlib"), 9650 ) 9651 9652 // Test java_sdk_library in bootclasspath_fragment may define higher min_sdk_version than the apex 9653 t.Run("bootclasspath_fragment jar has higher min_sdk_version than apex", func(t *testing.T) { 9654 t.Parallel() 9655 preparer.RunTestWithBp(t, ` 9656 apex { 9657 name: "myapex", 9658 key: "myapex.key", 9659 bootclasspath_fragments: ["mybootclasspathfragment"], 9660 min_sdk_version: "30", 9661 updatable: false, 9662 } 9663 9664 apex_key { 9665 name: "myapex.key", 9666 public_key: "testkey.avbpubkey", 9667 private_key: "testkey.pem", 9668 } 9669 9670 bootclasspath_fragment { 9671 name: "mybootclasspathfragment", 9672 contents: ["mybootclasspathlib"], 9673 apex_available: ["myapex"], 9674 hidden_api: { 9675 split_packages: ["*"], 9676 }, 9677 } 9678 9679 java_sdk_library { 9680 name: "mybootclasspathlib", 9681 srcs: ["mybootclasspathlib.java"], 9682 apex_available: ["myapex"], 9683 compile_dex: true, 9684 unsafe_ignore_missing_latest_api: true, 9685 min_sdk_version: "31", 9686 static_libs: ["util"], 9687 sdk_version: "core_current", 9688 } 9689 9690 java_library { 9691 name: "util", 9692 srcs: ["a.java"], 9693 apex_available: ["myapex"], 9694 min_sdk_version: "31", 9695 static_libs: ["another_util"], 9696 sdk_version: "core_current", 9697 } 9698 9699 java_library { 9700 name: "another_util", 9701 srcs: ["a.java"], 9702 min_sdk_version: "31", 9703 apex_available: ["myapex"], 9704 sdk_version: "core_current", 9705 } 9706 `) 9707 }) 9708 9709 // Test java_sdk_library in systemserverclasspath_fragment may define higher min_sdk_version than the apex 9710 t.Run("systemserverclasspath_fragment jar has higher min_sdk_version than apex", func(t *testing.T) { 9711 t.Parallel() 9712 preparer.RunTestWithBp(t, ` 9713 apex { 9714 name: "myapex", 9715 key: "myapex.key", 9716 systemserverclasspath_fragments: ["mysystemserverclasspathfragment"], 9717 min_sdk_version: "30", 9718 updatable: false, 9719 } 9720 9721 apex_key { 9722 name: "myapex.key", 9723 public_key: "testkey.avbpubkey", 9724 private_key: "testkey.pem", 9725 } 9726 9727 systemserverclasspath_fragment { 9728 name: "mysystemserverclasspathfragment", 9729 contents: ["mysystemserverclasspathlib"], 9730 apex_available: ["myapex"], 9731 } 9732 9733 java_sdk_library { 9734 name: "mysystemserverclasspathlib", 9735 srcs: ["mysystemserverclasspathlib.java"], 9736 apex_available: ["myapex"], 9737 compile_dex: true, 9738 min_sdk_version: "32", 9739 unsafe_ignore_missing_latest_api: true, 9740 static_libs: ["util"], 9741 } 9742 9743 java_library { 9744 name: "util", 9745 srcs: ["a.java"], 9746 apex_available: ["myapex"], 9747 min_sdk_version: "31", 9748 static_libs: ["another_util"], 9749 } 9750 9751 java_library { 9752 name: "another_util", 9753 srcs: ["a.java"], 9754 min_sdk_version: "31", 9755 apex_available: ["myapex"], 9756 } 9757 `) 9758 }) 9759 9760 t.Run("bootclasspath_fragment jar must set min_sdk_version", func(t *testing.T) { 9761 t.Parallel() 9762 preparer. 9763 RunTestWithBp(t, ` 9764 apex { 9765 name: "myapex", 9766 key: "myapex.key", 9767 bootclasspath_fragments: ["mybootclasspathfragment"], 9768 min_sdk_version: "30", 9769 updatable: false, 9770 } 9771 9772 apex_key { 9773 name: "myapex.key", 9774 public_key: "testkey.avbpubkey", 9775 private_key: "testkey.pem", 9776 } 9777 9778 bootclasspath_fragment { 9779 name: "mybootclasspathfragment", 9780 contents: ["mybootclasspathlib"], 9781 apex_available: ["myapex"], 9782 hidden_api: { 9783 split_packages: ["*"], 9784 }, 9785 } 9786 9787 java_sdk_library { 9788 name: "mybootclasspathlib", 9789 srcs: ["mybootclasspathlib.java"], 9790 apex_available: ["myapex"], 9791 compile_dex: true, 9792 unsafe_ignore_missing_latest_api: true, 9793 sdk_version: "current", 9794 min_sdk_version: "30", 9795 } 9796 `) 9797 }) 9798 9799 t.Run("systemserverclasspath_fragment jar must set min_sdk_version", func(t *testing.T) { 9800 t.Parallel() 9801 preparer.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "mysystemserverclasspathlib".*must set min_sdk_version`)). 9802 RunTestWithBp(t, ` 9803 apex { 9804 name: "myapex", 9805 key: "myapex.key", 9806 systemserverclasspath_fragments: ["mysystemserverclasspathfragment"], 9807 min_sdk_version: "30", 9808 updatable: false, 9809 } 9810 9811 apex_key { 9812 name: "myapex.key", 9813 public_key: "testkey.avbpubkey", 9814 private_key: "testkey.pem", 9815 } 9816 9817 systemserverclasspath_fragment { 9818 name: "mysystemserverclasspathfragment", 9819 contents: ["mysystemserverclasspathlib"], 9820 apex_available: ["myapex"], 9821 } 9822 9823 java_sdk_library { 9824 name: "mysystemserverclasspathlib", 9825 srcs: ["mysystemserverclasspathlib.java"], 9826 apex_available: ["myapex"], 9827 compile_dex: true, 9828 unsafe_ignore_missing_latest_api: true, 9829 } 9830 `) 9831 }) 9832} 9833 9834// Verifies that the APEX depends on all the Make modules in the list. 9835func ensureContainsRequiredDeps(t *testing.T, ctx *android.TestContext, moduleName, variant string, deps []string) { 9836 a := ctx.ModuleForTests(moduleName, variant).Module().(*apexBundle) 9837 for _, dep := range deps { 9838 android.AssertStringListContains(t, "", a.makeModulesToInstall, dep) 9839 } 9840} 9841 9842// Verifies that the APEX does not depend on any of the Make modules in the list. 9843func ensureDoesNotContainRequiredDeps(t *testing.T, ctx *android.TestContext, moduleName, variant string, deps []string) { 9844 a := ctx.ModuleForTests(moduleName, variant).Module().(*apexBundle) 9845 for _, dep := range deps { 9846 android.AssertStringListDoesNotContain(t, "", a.makeModulesToInstall, dep) 9847 } 9848} 9849 9850func TestApexStrictUpdtabilityLint(t *testing.T) { 9851 t.Parallel() 9852 bpTemplate := ` 9853 apex { 9854 name: "myapex", 9855 key: "myapex.key", 9856 java_libs: ["myjavalib"], 9857 updatable: %v, 9858 min_sdk_version: "29", 9859 } 9860 apex_key { 9861 name: "myapex.key", 9862 } 9863 java_library { 9864 name: "myjavalib", 9865 srcs: ["MyClass.java"], 9866 apex_available: [ "myapex" ], 9867 lint: { 9868 strict_updatability_linting: %v, 9869 %s 9870 }, 9871 sdk_version: "current", 9872 min_sdk_version: "29", 9873 compile_dex: true, 9874 } 9875 ` 9876 fs := android.MockFS{ 9877 "lint-baseline.xml": nil, 9878 } 9879 9880 testCases := []struct { 9881 testCaseName string 9882 apexUpdatable bool 9883 javaStrictUpdtabilityLint bool 9884 lintFileExists bool 9885 disallowedFlagExpectedOnApex bool 9886 disallowedFlagExpectedOnJavalib bool 9887 }{ 9888 { 9889 testCaseName: "lint-baseline.xml does not exist, no disallowed flag necessary in lint cmd", 9890 apexUpdatable: true, 9891 javaStrictUpdtabilityLint: true, 9892 lintFileExists: false, 9893 disallowedFlagExpectedOnApex: false, 9894 disallowedFlagExpectedOnJavalib: false, 9895 }, 9896 { 9897 testCaseName: "non-updatable apex respects strict_updatability of javalib", 9898 apexUpdatable: false, 9899 javaStrictUpdtabilityLint: false, 9900 lintFileExists: true, 9901 disallowedFlagExpectedOnApex: false, 9902 disallowedFlagExpectedOnJavalib: false, 9903 }, 9904 { 9905 testCaseName: "non-updatable apex respects strict updatability of javalib", 9906 apexUpdatable: false, 9907 javaStrictUpdtabilityLint: true, 9908 lintFileExists: true, 9909 disallowedFlagExpectedOnApex: false, 9910 disallowedFlagExpectedOnJavalib: true, 9911 }, 9912 { 9913 testCaseName: "updatable apex checks strict updatability of javalib", 9914 apexUpdatable: true, 9915 javaStrictUpdtabilityLint: false, 9916 lintFileExists: true, 9917 disallowedFlagExpectedOnApex: true, 9918 disallowedFlagExpectedOnJavalib: false, 9919 }, 9920 } 9921 9922 for _, testCase := range testCases { 9923 t.Run(testCase.testCaseName, func(t *testing.T) { 9924 t.Parallel() 9925 fixtures := []android.FixturePreparer{} 9926 baselineProperty := "" 9927 if testCase.lintFileExists { 9928 fixtures = append(fixtures, fs.AddToFixture()) 9929 baselineProperty = "baseline_filename: \"lint-baseline.xml\"" 9930 } 9931 bp := fmt.Sprintf(bpTemplate, testCase.apexUpdatable, testCase.javaStrictUpdtabilityLint, baselineProperty) 9932 9933 result := testApex(t, bp, fixtures...) 9934 9935 checkModule := func(m android.TestingBuildParams, name string, expectStrictUpdatability bool) { 9936 if expectStrictUpdatability { 9937 if m.Rule == nil { 9938 t.Errorf("expected strict updatability check rule on %s", name) 9939 } else { 9940 android.AssertStringDoesContain(t, fmt.Sprintf("strict updatability check rule for %s", name), 9941 m.RuleParams.Command, "--disallowed_issues NewApi") 9942 android.AssertStringListContains(t, fmt.Sprintf("strict updatability check baselines for %s", name), 9943 m.Inputs.Strings(), "lint-baseline.xml") 9944 } 9945 } else { 9946 if m.Rule != nil { 9947 t.Errorf("expected no strict updatability check rule on %s", name) 9948 } 9949 } 9950 } 9951 9952 myjavalib := result.ModuleForTests("myjavalib", "android_common_apex29") 9953 apex := result.ModuleForTests("myapex", "android_common_myapex") 9954 apexStrictUpdatabilityCheck := apex.MaybeOutput("lint_strict_updatability_check.stamp") 9955 javalibStrictUpdatabilityCheck := myjavalib.MaybeOutput("lint_strict_updatability_check.stamp") 9956 9957 checkModule(apexStrictUpdatabilityCheck, "myapex", testCase.disallowedFlagExpectedOnApex) 9958 checkModule(javalibStrictUpdatabilityCheck, "myjavalib", testCase.disallowedFlagExpectedOnJavalib) 9959 }) 9960 } 9961} 9962 9963// checks transtive deps of an apex coming from bootclasspath_fragment 9964func TestApexStrictUpdtabilityLintBcpFragmentDeps(t *testing.T) { 9965 t.Parallel() 9966 bp := ` 9967 apex { 9968 name: "myapex", 9969 key: "myapex.key", 9970 bootclasspath_fragments: ["mybootclasspathfragment"], 9971 updatable: true, 9972 min_sdk_version: "29", 9973 } 9974 apex_key { 9975 name: "myapex.key", 9976 } 9977 bootclasspath_fragment { 9978 name: "mybootclasspathfragment", 9979 contents: ["myjavalib"], 9980 apex_available: ["myapex"], 9981 hidden_api: { 9982 split_packages: ["*"], 9983 }, 9984 } 9985 java_library { 9986 name: "myjavalib", 9987 srcs: ["MyClass.java"], 9988 apex_available: [ "myapex" ], 9989 sdk_version: "current", 9990 min_sdk_version: "29", 9991 compile_dex: true, 9992 lint: { 9993 baseline_filename: "lint-baseline.xml", 9994 } 9995 } 9996 ` 9997 fs := android.MockFS{ 9998 "lint-baseline.xml": nil, 9999 } 10000 10001 result := testApex(t, bp, dexpreopt.FixtureSetApexBootJars("myapex:myjavalib"), fs.AddToFixture()) 10002 apex := result.ModuleForTests("myapex", "android_common_myapex") 10003 apexStrictUpdatabilityCheck := apex.Output("lint_strict_updatability_check.stamp") 10004 android.AssertStringDoesContain(t, "strict updatability check rule for myapex", 10005 apexStrictUpdatabilityCheck.RuleParams.Command, "--disallowed_issues NewApi") 10006 android.AssertStringListContains(t, "strict updatability check baselines for myapex", 10007 apexStrictUpdatabilityCheck.Inputs.Strings(), "lint-baseline.xml") 10008} 10009 10010func TestApexLintBcpFragmentSdkLibDeps(t *testing.T) { 10011 t.Parallel() 10012 bp := ` 10013 apex { 10014 name: "myapex", 10015 key: "myapex.key", 10016 bootclasspath_fragments: ["mybootclasspathfragment"], 10017 min_sdk_version: "29", 10018 java_libs: [ 10019 "jacocoagent", 10020 ], 10021 } 10022 apex_key { 10023 name: "myapex.key", 10024 } 10025 bootclasspath_fragment { 10026 name: "mybootclasspathfragment", 10027 contents: ["foo"], 10028 apex_available: ["myapex"], 10029 hidden_api: { 10030 split_packages: ["*"], 10031 }, 10032 } 10033 java_sdk_library { 10034 name: "foo", 10035 srcs: ["MyClass.java"], 10036 apex_available: [ "myapex" ], 10037 sdk_version: "current", 10038 min_sdk_version: "29", 10039 compile_dex: true, 10040 } 10041 ` 10042 fs := android.MockFS{ 10043 "lint-baseline.xml": nil, 10044 } 10045 10046 result := android.GroupFixturePreparers( 10047 prepareForApexTest, 10048 java.PrepareForTestWithJavaSdkLibraryFiles, 10049 java.PrepareForTestWithJacocoInstrumentation, 10050 java.FixtureWithLastReleaseApis("foo"), 10051 android.FixtureMergeMockFs(fs), 10052 ).RunTestWithBp(t, bp) 10053 10054 myapex := result.ModuleForTests("myapex", "android_common_myapex") 10055 lintReportInputs := strings.Join(myapex.Output("lint-report-xml.zip").Inputs.Strings(), " ") 10056 android.AssertStringDoesContain(t, 10057 "myapex lint report expected to contain that of the sdk library impl lib as an input", 10058 lintReportInputs, "foo.impl") 10059} 10060 10061// updatable apexes should propagate updatable=true to its apps 10062func TestUpdatableApexEnforcesAppUpdatability(t *testing.T) { 10063 t.Parallel() 10064 bp := ` 10065 apex { 10066 name: "myapex", 10067 key: "myapex.key", 10068 updatable: true, 10069 apps: [ 10070 "myapp", 10071 ], 10072 min_sdk_version: "30", 10073 } 10074 apex_key { 10075 name: "myapex.key", 10076 } 10077 android_app { 10078 name: "myapp", 10079 apex_available: [ 10080 "myapex", 10081 ], 10082 sdk_version: "current", 10083 min_sdk_version: "30", 10084 } 10085 ` 10086 _ = android.GroupFixturePreparers( 10087 prepareForApexTest, 10088 ).ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("app dependency myapp must have updatable: true")). 10089 RunTestWithBp(t, bp) 10090} 10091 10092func TestCannedFsConfig(t *testing.T) { 10093 t.Parallel() 10094 ctx := testApex(t, ` 10095 apex { 10096 name: "myapex", 10097 key: "myapex.key", 10098 updatable: false, 10099 } 10100 10101 apex_key { 10102 name: "myapex.key", 10103 public_key: "testkey.avbpubkey", 10104 private_key: "testkey.pem", 10105 }`) 10106 mod := ctx.ModuleForTests("myapex", "android_common_myapex") 10107 generateFsRule := mod.Rule("generateFsConfig") 10108 cmd := generateFsRule.RuleParams.Command 10109 10110 ensureContains(t, cmd, `( echo '/ 1000 1000 0755'; echo '/apex_manifest.json 1000 1000 0644'; echo '/apex_manifest.pb 1000 1000 0644'; ) >`) 10111} 10112 10113func TestCannedFsConfig_HasCustomConfig(t *testing.T) { 10114 t.Parallel() 10115 ctx := testApex(t, ` 10116 apex { 10117 name: "myapex", 10118 key: "myapex.key", 10119 canned_fs_config: "my_config", 10120 updatable: false, 10121 } 10122 10123 apex_key { 10124 name: "myapex.key", 10125 public_key: "testkey.avbpubkey", 10126 private_key: "testkey.pem", 10127 }`) 10128 mod := ctx.ModuleForTests("myapex", "android_common_myapex") 10129 generateFsRule := mod.Rule("generateFsConfig") 10130 cmd := generateFsRule.RuleParams.Command 10131 10132 // Ensure that canned_fs_config has "cat my_config" at the end 10133 ensureContains(t, cmd, `( echo '/ 1000 1000 0755'; echo '/apex_manifest.json 1000 1000 0644'; echo '/apex_manifest.pb 1000 1000 0644'; cat my_config ) >`) 10134} 10135 10136func TestStubLibrariesMultipleApexViolation(t *testing.T) { 10137 t.Parallel() 10138 testCases := []struct { 10139 desc string 10140 hasStubs bool 10141 apexAvailable string 10142 expectedError string 10143 }{ 10144 { 10145 desc: "non-stub library can have multiple apex_available", 10146 hasStubs: false, 10147 apexAvailable: `["myapex", "otherapex"]`, 10148 }, 10149 { 10150 desc: "stub library should not be available to anyapex", 10151 hasStubs: true, 10152 apexAvailable: `["//apex_available:anyapex"]`, 10153 expectedError: "Stub libraries should have a single apex_available.*anyapex", 10154 }, 10155 { 10156 desc: "stub library should not be available to multiple apexes", 10157 hasStubs: true, 10158 apexAvailable: `["myapex", "otherapex"]`, 10159 expectedError: "Stub libraries should have a single apex_available.*myapex.*otherapex", 10160 }, 10161 { 10162 desc: "stub library can be available to a core apex and a test apex", 10163 hasStubs: true, 10164 apexAvailable: `["myapex", "test_myapex"]`, 10165 }, 10166 } 10167 bpTemplate := ` 10168 cc_library { 10169 name: "libfoo", 10170 %v 10171 apex_available: %v, 10172 } 10173 apex { 10174 name: "myapex", 10175 key: "apex.key", 10176 updatable: false, 10177 native_shared_libs: ["libfoo"], 10178 } 10179 apex { 10180 name: "otherapex", 10181 key: "apex.key", 10182 updatable: false, 10183 } 10184 apex_test { 10185 name: "test_myapex", 10186 key: "apex.key", 10187 updatable: false, 10188 native_shared_libs: ["libfoo"], 10189 } 10190 apex_key { 10191 name: "apex.key", 10192 } 10193 ` 10194 for _, tc := range testCases { 10195 stubs := "" 10196 if tc.hasStubs { 10197 stubs = `stubs: {symbol_file: "libfoo.map.txt"},` 10198 } 10199 bp := fmt.Sprintf(bpTemplate, stubs, tc.apexAvailable) 10200 mockFsFixturePreparer := android.FixtureModifyMockFS(func(fs android.MockFS) { 10201 fs["system/sepolicy/apex/test_myapex-file_contexts"] = nil 10202 }) 10203 if tc.expectedError == "" { 10204 testApex(t, bp, mockFsFixturePreparer) 10205 } else { 10206 testApexError(t, tc.expectedError, bp, mockFsFixturePreparer) 10207 } 10208 } 10209} 10210 10211func TestFileSystemShouldSkipApexLibraries(t *testing.T) { 10212 t.Parallel() 10213 context := android.GroupFixturePreparers( 10214 android.PrepareForIntegrationTestWithAndroid, 10215 cc.PrepareForIntegrationTestWithCc, 10216 PrepareForTestWithApexBuildComponents, 10217 prepareForTestWithMyapex, 10218 filesystem.PrepareForTestWithFilesystemBuildComponents, 10219 ) 10220 result := context.RunTestWithBp(t, ` 10221 android_system_image { 10222 name: "myfilesystem", 10223 deps: [ 10224 "libfoo", 10225 ], 10226 linker_config: { 10227 gen_linker_config: true, 10228 linker_config_srcs: ["linker.config.json"], 10229 }, 10230 } 10231 10232 cc_library { 10233 name: "libfoo", 10234 shared_libs: [ 10235 "libbar", 10236 ], 10237 stl: "none", 10238 } 10239 10240 cc_library { 10241 name: "libbar", 10242 stl: "none", 10243 apex_available: ["myapex"], 10244 } 10245 10246 apex { 10247 name: "myapex", 10248 native_shared_libs: ["libbar"], 10249 key: "myapex.key", 10250 updatable: false, 10251 } 10252 10253 apex_key { 10254 name: "myapex.key", 10255 public_key: "testkey.avbpubkey", 10256 private_key: "testkey.pem", 10257 } 10258 `) 10259 10260 inputs := result.ModuleForTests("myfilesystem", "android_common").Output("myfilesystem.img").Implicits 10261 android.AssertStringListDoesNotContain(t, "filesystem should not have libbar", 10262 inputs.Strings(), 10263 "out/soong/.intermediates/libbar/android_arm64_armv8-a_shared/libbar.so") 10264} 10265 10266var apex_default_bp = ` 10267 apex_key { 10268 name: "myapex.key", 10269 public_key: "testkey.avbpubkey", 10270 private_key: "testkey.pem", 10271 } 10272 10273 filegroup { 10274 name: "myapex.manifest", 10275 srcs: ["apex_manifest.json"], 10276 } 10277 10278 filegroup { 10279 name: "myapex.androidmanifest", 10280 srcs: ["AndroidManifest.xml"], 10281 } 10282` 10283 10284func TestAconfigFilesJavaDeps(t *testing.T) { 10285 t.Parallel() 10286 ctx := testApex(t, apex_default_bp+` 10287 apex { 10288 name: "myapex", 10289 manifest: ":myapex.manifest", 10290 androidManifest: ":myapex.androidmanifest", 10291 key: "myapex.key", 10292 java_libs: [ 10293 "my_java_library_foo", 10294 "my_java_library_bar", 10295 ], 10296 updatable: false, 10297 } 10298 10299 java_library { 10300 name: "my_java_library_foo", 10301 srcs: ["foo/bar/MyClass.java"], 10302 sdk_version: "none", 10303 system_modules: "none", 10304 static_libs: ["my_java_aconfig_library_foo"], 10305 apex_available: [ 10306 "myapex", 10307 ], 10308 compile_dex: true, 10309 } 10310 10311 java_library { 10312 name: "my_java_library_bar", 10313 srcs: ["foo/bar/MyClass.java"], 10314 sdk_version: "none", 10315 system_modules: "none", 10316 static_libs: ["my_java_aconfig_library_bar"], 10317 apex_available: [ 10318 "myapex", 10319 ], 10320 compile_dex: true, 10321 } 10322 10323 aconfig_declarations { 10324 name: "my_aconfig_declarations_foo", 10325 package: "com.example.package", 10326 container: "myapex", 10327 srcs: ["foo.aconfig"], 10328 } 10329 10330 java_aconfig_library { 10331 name: "my_java_aconfig_library_foo", 10332 aconfig_declarations: "my_aconfig_declarations_foo", 10333 apex_available: [ 10334 "myapex", 10335 ], 10336 } 10337 10338 aconfig_declarations { 10339 name: "my_aconfig_declarations_bar", 10340 package: "com.example.package", 10341 container: "myapex", 10342 srcs: ["bar.aconfig"], 10343 } 10344 10345 java_aconfig_library { 10346 name: "my_java_aconfig_library_bar", 10347 aconfig_declarations: "my_aconfig_declarations_bar", 10348 apex_available: [ 10349 "myapex", 10350 ], 10351 } 10352 `) 10353 10354 mod := ctx.ModuleForTests("myapex", "android_common_myapex") 10355 s := mod.Rule("apexRule").Args["copy_commands"] 10356 copyCmds := regexp.MustCompile(" *&& *").Split(s, -1) 10357 if len(copyCmds) != 14 { 10358 t.Fatalf("Expected 14 commands, got %d in:\n%s", len(copyCmds), s) 10359 } 10360 10361 ensureListContainsMatch(t, copyCmds, "^cp -f .*/aconfig_flags.pb .*/image.apex/etc/aconfig_flags.pb") 10362 ensureListContainsMatch(t, copyCmds, "^cp -f .*/package.map .*/image.apex/etc/package.map") 10363 ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.map .*/image.apex/etc/flag.map") 10364 ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.val .*/image.apex/etc/flag.val") 10365 ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.info.*/image.apex/etc/flag.info") 10366 10367 inputs := []string{ 10368 "my_aconfig_declarations_foo/intermediate.pb", 10369 "my_aconfig_declarations_bar/intermediate.pb", 10370 } 10371 VerifyAconfigRule(t, &mod, "combine_aconfig_declarations", inputs, "android_common_myapex/aconfig_flags.pb", "", "") 10372 VerifyAconfigRule(t, &mod, "create_aconfig_package_map_file", inputs, "android_common_myapex/package.map", "myapex", "package_map") 10373 VerifyAconfigRule(t, &mod, "create_aconfig_flag_map_file", inputs, "android_common_myapex/flag.map", "myapex", "flag_map") 10374 VerifyAconfigRule(t, &mod, "create_aconfig_flag_val_file", inputs, "android_common_myapex/flag.val", "myapex", "flag_val") 10375 VerifyAconfigRule(t, &mod, "create_aconfig_flag_info_file", inputs, "android_common_myapex/flag.info", "myapex", "flag_info") 10376} 10377 10378func TestAconfigFilesJavaAndCcDeps(t *testing.T) { 10379 t.Parallel() 10380 ctx := testApex(t, apex_default_bp+` 10381 apex { 10382 name: "myapex", 10383 manifest: ":myapex.manifest", 10384 androidManifest: ":myapex.androidmanifest", 10385 key: "myapex.key", 10386 java_libs: [ 10387 "my_java_library_foo", 10388 ], 10389 native_shared_libs: [ 10390 "my_cc_library_bar", 10391 ], 10392 binaries: [ 10393 "my_cc_binary_baz", 10394 ], 10395 updatable: false, 10396 } 10397 10398 java_library { 10399 name: "my_java_library_foo", 10400 srcs: ["foo/bar/MyClass.java"], 10401 sdk_version: "none", 10402 system_modules: "none", 10403 static_libs: ["my_java_aconfig_library_foo"], 10404 apex_available: [ 10405 "myapex", 10406 ], 10407 compile_dex: true, 10408 } 10409 10410 cc_library { 10411 name: "my_cc_library_bar", 10412 srcs: ["foo/bar/MyClass.cc"], 10413 static_libs: [ 10414 "my_cc_aconfig_library_bar", 10415 "my_cc_aconfig_library_baz", 10416 ], 10417 apex_available: [ 10418 "myapex", 10419 ], 10420 } 10421 10422 cc_binary { 10423 name: "my_cc_binary_baz", 10424 srcs: ["foo/bar/MyClass.cc"], 10425 static_libs: ["my_cc_aconfig_library_baz"], 10426 apex_available: [ 10427 "myapex", 10428 ], 10429 } 10430 10431 aconfig_declarations { 10432 name: "my_aconfig_declarations_foo", 10433 package: "com.example.package", 10434 container: "myapex", 10435 srcs: ["foo.aconfig"], 10436 } 10437 10438 java_aconfig_library { 10439 name: "my_java_aconfig_library_foo", 10440 aconfig_declarations: "my_aconfig_declarations_foo", 10441 apex_available: [ 10442 "myapex", 10443 ], 10444 } 10445 10446 aconfig_declarations { 10447 name: "my_aconfig_declarations_bar", 10448 package: "com.example.package", 10449 container: "myapex", 10450 srcs: ["bar.aconfig"], 10451 } 10452 10453 cc_aconfig_library { 10454 name: "my_cc_aconfig_library_bar", 10455 aconfig_declarations: "my_aconfig_declarations_bar", 10456 apex_available: [ 10457 "myapex", 10458 ], 10459 } 10460 10461 aconfig_declarations { 10462 name: "my_aconfig_declarations_baz", 10463 package: "com.example.package", 10464 container: "myapex", 10465 srcs: ["baz.aconfig"], 10466 } 10467 10468 cc_aconfig_library { 10469 name: "my_cc_aconfig_library_baz", 10470 aconfig_declarations: "my_aconfig_declarations_baz", 10471 apex_available: [ 10472 "myapex", 10473 ], 10474 } 10475 10476 cc_library { 10477 name: "server_configurable_flags", 10478 srcs: ["server_configurable_flags.cc"], 10479 } 10480 cc_library { 10481 name: "libbase", 10482 srcs: ["libbase.cc"], 10483 apex_available: [ 10484 "myapex", 10485 ], 10486 } 10487 cc_library { 10488 name: "libaconfig_storage_read_api_cc", 10489 srcs: ["libaconfig_storage_read_api_cc.cc"], 10490 } 10491 `) 10492 10493 mod := ctx.ModuleForTests("myapex", "android_common_myapex") 10494 s := mod.Rule("apexRule").Args["copy_commands"] 10495 copyCmds := regexp.MustCompile(" *&& *").Split(s, -1) 10496 if len(copyCmds) != 18 { 10497 t.Fatalf("Expected 18 commands, got %d in:\n%s", len(copyCmds), s) 10498 } 10499 10500 ensureListContainsMatch(t, copyCmds, "^cp -f .*/aconfig_flags.pb .*/image.apex/etc/aconfig_flags.pb") 10501 ensureListContainsMatch(t, copyCmds, "^cp -f .*/package.map .*/image.apex/etc/package.map") 10502 ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.map .*/image.apex/etc/flag.map") 10503 ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.val .*/image.apex/etc/flag.val") 10504 ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.info .*/image.apex/etc/flag.info") 10505 10506 inputs := []string{ 10507 "my_aconfig_declarations_foo/intermediate.pb", 10508 "my_cc_library_bar/android_arm64_armv8-a_shared_apex10000/myapex/aconfig_merged.pb", 10509 "my_aconfig_declarations_baz/intermediate.pb", 10510 } 10511 VerifyAconfigRule(t, &mod, "combine_aconfig_declarations", inputs, "android_common_myapex/aconfig_flags.pb", "", "") 10512 VerifyAconfigRule(t, &mod, "create_aconfig_package_map_file", inputs, "android_common_myapex/package.map", "myapex", "package_map") 10513 VerifyAconfigRule(t, &mod, "create_aconfig_flag_map_file", inputs, "android_common_myapex/flag.map", "myapex", "flag_map") 10514 VerifyAconfigRule(t, &mod, "create_aconfig_flag_val_file", inputs, "android_common_myapex/flag.val", "myapex", "flag_val") 10515 VerifyAconfigRule(t, &mod, "create_aconfig_flag_info_file", inputs, "android_common_myapex/flag.info", "myapex", "flag_info") 10516} 10517 10518func TestAconfigFilesRustDeps(t *testing.T) { 10519 t.Parallel() 10520 ctx := testApex(t, apex_default_bp+` 10521 apex { 10522 name: "myapex", 10523 manifest: ":myapex.manifest", 10524 androidManifest: ":myapex.androidmanifest", 10525 key: "myapex.key", 10526 native_shared_libs: [ 10527 "libmy_rust_library", 10528 ], 10529 binaries: [ 10530 "my_rust_binary", 10531 ], 10532 rust_dyn_libs: [ 10533 "libmy_rust_dylib", 10534 ], 10535 updatable: false, 10536 } 10537 10538 rust_library { 10539 name: "libflags_rust", // test mock 10540 crate_name: "flags_rust", 10541 srcs: ["lib.rs"], 10542 apex_available: [ 10543 "myapex", 10544 ], 10545 } 10546 10547 rust_library { 10548 name: "liblazy_static", // test mock 10549 crate_name: "lazy_static", 10550 srcs: ["src/lib.rs"], 10551 apex_available: [ 10552 "myapex", 10553 ], 10554 } 10555 10556 rust_library { 10557 name: "libaconfig_storage_read_api", // test mock 10558 crate_name: "aconfig_storage_read_api", 10559 srcs: ["src/lib.rs"], 10560 apex_available: [ 10561 "myapex", 10562 ], 10563 } 10564 10565 rust_library { 10566 name: "liblogger", // test mock 10567 crate_name: "logger", 10568 srcs: ["src/lib.rs"], 10569 apex_available: [ 10570 "myapex", 10571 ], 10572 } 10573 10574 rust_library { 10575 name: "liblog_rust", // test mock 10576 crate_name: "log_rust", 10577 srcs: ["src/lib.rs"], 10578 apex_available: [ 10579 "myapex", 10580 ], 10581 } 10582 10583 rust_ffi_shared { 10584 name: "libmy_rust_library", 10585 srcs: ["src/lib.rs"], 10586 rustlibs: ["libmy_rust_aconfig_library_foo"], 10587 crate_name: "my_rust_library", 10588 apex_available: [ 10589 "myapex", 10590 ], 10591 } 10592 10593 rust_library_dylib { 10594 name: "libmy_rust_dylib", 10595 srcs: ["foo/bar/MyClass.rs"], 10596 rustlibs: ["libmy_rust_aconfig_library_bar"], 10597 crate_name: "my_rust_dylib", 10598 apex_available: [ 10599 "myapex", 10600 ], 10601 } 10602 10603 rust_binary { 10604 name: "my_rust_binary", 10605 srcs: ["foo/bar/MyClass.rs"], 10606 rustlibs: [ 10607 "libmy_rust_aconfig_library_baz", 10608 "libmy_rust_dylib", 10609 ], 10610 apex_available: [ 10611 "myapex", 10612 ], 10613 } 10614 10615 aconfig_declarations { 10616 name: "my_aconfig_declarations_foo", 10617 package: "com.example.package", 10618 container: "myapex", 10619 srcs: ["foo.aconfig"], 10620 } 10621 10622 aconfig_declarations { 10623 name: "my_aconfig_declarations_bar", 10624 package: "com.example.package", 10625 container: "myapex", 10626 srcs: ["bar.aconfig"], 10627 } 10628 10629 aconfig_declarations { 10630 name: "my_aconfig_declarations_baz", 10631 package: "com.example.package", 10632 container: "myapex", 10633 srcs: ["baz.aconfig"], 10634 } 10635 10636 rust_aconfig_library { 10637 name: "libmy_rust_aconfig_library_foo", 10638 aconfig_declarations: "my_aconfig_declarations_foo", 10639 crate_name: "my_rust_aconfig_library_foo", 10640 apex_available: [ 10641 "myapex", 10642 ], 10643 } 10644 10645 rust_aconfig_library { 10646 name: "libmy_rust_aconfig_library_bar", 10647 aconfig_declarations: "my_aconfig_declarations_bar", 10648 crate_name: "my_rust_aconfig_library_bar", 10649 apex_available: [ 10650 "myapex", 10651 ], 10652 } 10653 10654 rust_aconfig_library { 10655 name: "libmy_rust_aconfig_library_baz", 10656 aconfig_declarations: "my_aconfig_declarations_baz", 10657 crate_name: "my_rust_aconfig_library_baz", 10658 apex_available: [ 10659 "myapex", 10660 ], 10661 } 10662 `) 10663 10664 mod := ctx.ModuleForTests("myapex", "android_common_myapex") 10665 s := mod.Rule("apexRule").Args["copy_commands"] 10666 copyCmds := regexp.MustCompile(" *&& *").Split(s, -1) 10667 if len(copyCmds) != 38 { 10668 t.Fatalf("Expected 38 commands, got %d in:\n%s", len(copyCmds), s) 10669 } 10670 10671 ensureListContainsMatch(t, copyCmds, "^cp -f .*/aconfig_flags.pb .*/image.apex/etc/aconfig_flags.pb") 10672 ensureListContainsMatch(t, copyCmds, "^cp -f .*/package.map .*/image.apex/etc/package.map") 10673 ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.map .*/image.apex/etc/flag.map") 10674 ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.val .*/image.apex/etc/flag.val") 10675 ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.info .*/image.apex/etc/flag.info") 10676 10677 inputs := []string{ 10678 "my_aconfig_declarations_foo/intermediate.pb", 10679 "my_aconfig_declarations_bar/intermediate.pb", 10680 "my_aconfig_declarations_baz/intermediate.pb", 10681 "my_rust_binary/android_arm64_armv8-a_apex10000/myapex/aconfig_merged.pb", 10682 } 10683 VerifyAconfigRule(t, &mod, "combine_aconfig_declarations", inputs, "android_common_myapex/aconfig_flags.pb", "", "") 10684 VerifyAconfigRule(t, &mod, "create_aconfig_package_map_file", inputs, "android_common_myapex/package.map", "myapex", "package_map") 10685 VerifyAconfigRule(t, &mod, "create_aconfig_flag_map_file", inputs, "android_common_myapex/flag.map", "myapex", "flag_map") 10686 VerifyAconfigRule(t, &mod, "create_aconfig_flag_val_file", inputs, "android_common_myapex/flag.val", "myapex", "flag_val") 10687 VerifyAconfigRule(t, &mod, "create_aconfig_flag_info_file", inputs, "android_common_myapex/flag.info", "myapex", "flag_info") 10688} 10689 10690func VerifyAconfigRule(t *testing.T, mod *android.TestingModule, desc string, inputs []string, output string, container string, file_type string) { 10691 aconfigRule := mod.Description(desc) 10692 s := " " + aconfigRule.Args["cache_files"] 10693 aconfigArgs := regexp.MustCompile(" --cache ").Split(s, -1)[1:] 10694 if len(aconfigArgs) != len(inputs) { 10695 t.Fatalf("Expected %d commands, got %d in:\n%s", len(inputs), len(aconfigArgs), s) 10696 } 10697 10698 ensureEquals(t, container, aconfigRule.Args["container"]) 10699 ensureEquals(t, file_type, aconfigRule.Args["file_type"]) 10700 10701 buildParams := aconfigRule.BuildParams 10702 for _, input := range inputs { 10703 android.EnsureListContainsSuffix(t, aconfigArgs, input) 10704 android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), input) 10705 } 10706 10707 ensureContains(t, buildParams.Output.String(), output) 10708} 10709 10710func TestAconfigFilesOnlyMatchCurrentApex(t *testing.T) { 10711 t.Parallel() 10712 ctx := testApex(t, apex_default_bp+` 10713 apex { 10714 name: "myapex", 10715 manifest: ":myapex.manifest", 10716 androidManifest: ":myapex.androidmanifest", 10717 key: "myapex.key", 10718 java_libs: [ 10719 "my_java_library_foo", 10720 "other_java_library_bar", 10721 ], 10722 updatable: false, 10723 } 10724 10725 java_library { 10726 name: "my_java_library_foo", 10727 srcs: ["foo/bar/MyClass.java"], 10728 sdk_version: "none", 10729 system_modules: "none", 10730 static_libs: ["my_java_aconfig_library_foo"], 10731 apex_available: [ 10732 "myapex", 10733 ], 10734 compile_dex: true, 10735 } 10736 10737 java_library { 10738 name: "other_java_library_bar", 10739 srcs: ["foo/bar/MyClass.java"], 10740 sdk_version: "none", 10741 system_modules: "none", 10742 static_libs: ["other_java_aconfig_library_bar"], 10743 apex_available: [ 10744 "myapex", 10745 ], 10746 compile_dex: true, 10747 } 10748 10749 aconfig_declarations { 10750 name: "my_aconfig_declarations_foo", 10751 package: "com.example.package", 10752 container: "myapex", 10753 srcs: ["foo.aconfig"], 10754 } 10755 10756 java_aconfig_library { 10757 name: "my_java_aconfig_library_foo", 10758 aconfig_declarations: "my_aconfig_declarations_foo", 10759 apex_available: [ 10760 "myapex", 10761 ], 10762 } 10763 10764 aconfig_declarations { 10765 name: "other_aconfig_declarations_bar", 10766 package: "com.example.package", 10767 container: "otherapex", 10768 srcs: ["bar.aconfig"], 10769 } 10770 10771 java_aconfig_library { 10772 name: "other_java_aconfig_library_bar", 10773 aconfig_declarations: "other_aconfig_declarations_bar", 10774 apex_available: [ 10775 "myapex", 10776 ], 10777 } 10778 `) 10779 10780 mod := ctx.ModuleForTests("myapex", "android_common_myapex") 10781 combineAconfigRule := mod.Rule("All_aconfig_declarations_dump") 10782 s := " " + combineAconfigRule.Args["cache_files"] 10783 aconfigArgs := regexp.MustCompile(" --cache ").Split(s, -1)[1:] 10784 if len(aconfigArgs) != 1 { 10785 t.Fatalf("Expected 1 commands, got %d in:\n%s", len(aconfigArgs), s) 10786 } 10787 android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_foo/intermediate.pb") 10788 10789 buildParams := combineAconfigRule.BuildParams 10790 if len(buildParams.Inputs) != 1 { 10791 t.Fatalf("Expected 1 input, got %d", len(buildParams.Inputs)) 10792 } 10793 android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_foo/intermediate.pb") 10794 ensureContains(t, buildParams.Output.String(), "android_common_myapex/aconfig_flags.pb") 10795} 10796 10797func TestAconfigFilesRemoveDuplicates(t *testing.T) { 10798 t.Parallel() 10799 ctx := testApex(t, apex_default_bp+` 10800 apex { 10801 name: "myapex", 10802 manifest: ":myapex.manifest", 10803 androidManifest: ":myapex.androidmanifest", 10804 key: "myapex.key", 10805 java_libs: [ 10806 "my_java_library_foo", 10807 "my_java_library_bar", 10808 ], 10809 updatable: false, 10810 } 10811 10812 java_library { 10813 name: "my_java_library_foo", 10814 srcs: ["foo/bar/MyClass.java"], 10815 sdk_version: "none", 10816 system_modules: "none", 10817 static_libs: ["my_java_aconfig_library_foo"], 10818 apex_available: [ 10819 "myapex", 10820 ], 10821 compile_dex: true, 10822 } 10823 10824 java_library { 10825 name: "my_java_library_bar", 10826 srcs: ["foo/bar/MyClass.java"], 10827 sdk_version: "none", 10828 system_modules: "none", 10829 static_libs: ["my_java_aconfig_library_bar"], 10830 apex_available: [ 10831 "myapex", 10832 ], 10833 compile_dex: true, 10834 } 10835 10836 aconfig_declarations { 10837 name: "my_aconfig_declarations_foo", 10838 package: "com.example.package", 10839 container: "myapex", 10840 srcs: ["foo.aconfig"], 10841 } 10842 10843 java_aconfig_library { 10844 name: "my_java_aconfig_library_foo", 10845 aconfig_declarations: "my_aconfig_declarations_foo", 10846 apex_available: [ 10847 "myapex", 10848 ], 10849 } 10850 10851 java_aconfig_library { 10852 name: "my_java_aconfig_library_bar", 10853 aconfig_declarations: "my_aconfig_declarations_foo", 10854 apex_available: [ 10855 "myapex", 10856 ], 10857 } 10858 `) 10859 10860 mod := ctx.ModuleForTests("myapex", "android_common_myapex") 10861 combineAconfigRule := mod.Rule("All_aconfig_declarations_dump") 10862 s := " " + combineAconfigRule.Args["cache_files"] 10863 aconfigArgs := regexp.MustCompile(" --cache ").Split(s, -1)[1:] 10864 if len(aconfigArgs) != 1 { 10865 t.Fatalf("Expected 1 commands, got %d in:\n%s", len(aconfigArgs), s) 10866 } 10867 android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_foo/intermediate.pb") 10868 10869 buildParams := combineAconfigRule.BuildParams 10870 if len(buildParams.Inputs) != 1 { 10871 t.Fatalf("Expected 1 input, got %d", len(buildParams.Inputs)) 10872 } 10873 android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_foo/intermediate.pb") 10874 ensureContains(t, buildParams.Output.String(), "android_common_myapex/aconfig_flags.pb") 10875} 10876 10877// Test that the boot jars come from the _selected_ apex prebuilt 10878// RELEASE_APEX_CONTIRBUTIONS_* build flags will be used to select the correct prebuilt for a specific release config 10879func TestBootDexJarsMultipleApexPrebuilts(t *testing.T) { 10880 t.Parallel() 10881 checkBootDexJarPath := func(t *testing.T, ctx *android.TestContext, stem string, bootDexJarPath string) { 10882 t.Helper() 10883 s := ctx.ModuleForTests("dex_bootjars", "android_common") 10884 foundLibfooJar := false 10885 base := stem + ".jar" 10886 for _, output := range s.AllOutputs() { 10887 if filepath.Base(output) == base { 10888 foundLibfooJar = true 10889 buildRule := s.Output(output) 10890 android.AssertStringEquals(t, "boot dex jar path", bootDexJarPath, buildRule.Input.String()) 10891 } 10892 } 10893 if !foundLibfooJar { 10894 t.Errorf("Rule for libfoo.jar missing in dex_bootjars singleton outputs %q", android.StringPathsRelativeToTop(ctx.Config().SoongOutDir(), s.AllOutputs())) 10895 } 10896 } 10897 10898 // Check that the boot jars of the selected apex are run through boot_jars_package_check 10899 // This validates that the jars on the bootclasspath do not contain packages outside an allowlist 10900 checkBootJarsPackageCheck := func(t *testing.T, ctx *android.TestContext, expectedBootJar string) { 10901 platformBcp := ctx.ModuleForTests("platform-bootclasspath", "android_common") 10902 bootJarsCheckRule := platformBcp.Rule("boot_jars_package_check") 10903 android.AssertStringMatches(t, "Could not find the correct boot dex jar in package check rule", bootJarsCheckRule.RuleParams.Command, "build/soong/scripts/check_boot_jars/package_allowed_list.txt.*"+expectedBootJar) 10904 } 10905 10906 // Check that the boot jars used to generate the monolithic hiddenapi flags come from the selected apex 10907 checkBootJarsForMonolithicHiddenapi := func(t *testing.T, ctx *android.TestContext, expectedBootJar string) { 10908 monolithicHiddenapiFlagsCmd := ctx.ModuleForTests("platform-bootclasspath", "android_common").Output("out/soong/hiddenapi/hiddenapi-stub-flags.txt").RuleParams.Command 10909 android.AssertStringMatches(t, "Could not find the correct boot dex jar in monolithic hiddenapi flags generation command", monolithicHiddenapiFlagsCmd, "--boot-dex="+expectedBootJar) 10910 } 10911 10912 bp := ` 10913 // Source APEX. 10914 10915 java_library { 10916 name: "framework-foo", 10917 srcs: ["foo.java"], 10918 installable: true, 10919 apex_available: [ 10920 "com.android.foo", 10921 ], 10922 } 10923 10924 bootclasspath_fragment { 10925 name: "foo-bootclasspath-fragment", 10926 contents: ["framework-foo"], 10927 apex_available: [ 10928 "com.android.foo", 10929 ], 10930 hidden_api: { 10931 split_packages: ["*"], 10932 }, 10933 } 10934 10935 apex_key { 10936 name: "com.android.foo.key", 10937 public_key: "com.android.foo.avbpubkey", 10938 private_key: "com.android.foo.pem", 10939 } 10940 10941 apex { 10942 name: "com.android.foo", 10943 key: "com.android.foo.key", 10944 bootclasspath_fragments: ["foo-bootclasspath-fragment"], 10945 updatable: false, 10946 } 10947 10948 // Prebuilt APEX. 10949 10950 java_sdk_library_import { 10951 name: "framework-foo", 10952 public: { 10953 jars: ["foo.jar"], 10954 }, 10955 apex_available: ["com.android.foo"], 10956 shared_library: false, 10957 } 10958 10959 prebuilt_bootclasspath_fragment { 10960 name: "foo-bootclasspath-fragment", 10961 contents: ["framework-foo"], 10962 hidden_api: { 10963 annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", 10964 metadata: "my-bootclasspath-fragment/metadata.csv", 10965 index: "my-bootclasspath-fragment/index.csv", 10966 stub_flags: "my-bootclasspath-fragment/stub-flags.csv", 10967 all_flags: "my-bootclasspath-fragment/all-flags.csv", 10968 }, 10969 apex_available: [ 10970 "com.android.foo", 10971 ], 10972 } 10973 10974 prebuilt_apex { 10975 name: "com.android.foo", 10976 apex_name: "com.android.foo", 10977 src: "com.android.foo-arm.apex", 10978 exported_bootclasspath_fragments: ["foo-bootclasspath-fragment"], 10979 } 10980 10981 // Another Prebuilt ART APEX 10982 prebuilt_apex { 10983 name: "com.android.foo.v2", 10984 apex_name: "com.android.foo", // Used to determine the API domain 10985 src: "com.android.foo-arm.apex", 10986 exported_bootclasspath_fragments: ["foo-bootclasspath-fragment"], 10987 } 10988 10989 // APEX contribution modules 10990 10991 apex_contributions { 10992 name: "foo.source.contributions", 10993 api_domain: "com.android.foo", 10994 contents: ["com.android.foo"], 10995 } 10996 10997 apex_contributions { 10998 name: "foo.prebuilt.contributions", 10999 api_domain: "com.android.foo", 11000 contents: ["prebuilt_com.android.foo"], 11001 } 11002 11003 apex_contributions { 11004 name: "foo.prebuilt.v2.contributions", 11005 api_domain: "com.android.foo", 11006 contents: ["com.android.foo.v2"], // prebuilt_ prefix is missing because of prebuilt_rename mutator 11007 } 11008 ` 11009 11010 testCases := []struct { 11011 desc string 11012 selectedApexContributions string 11013 expectedBootJar string 11014 }{ 11015 { 11016 desc: "Source apex com.android.foo is selected, bootjar should come from source java library", 11017 selectedApexContributions: "foo.source.contributions", 11018 expectedBootJar: "out/soong/.intermediates/foo-bootclasspath-fragment/android_common_apex10000/hiddenapi-modular/encoded/framework-foo.jar", 11019 }, 11020 { 11021 desc: "Prebuilt apex prebuilt_com.android.foo is selected, profile should come from .prof deapexed from the prebuilt", 11022 selectedApexContributions: "foo.prebuilt.contributions", 11023 expectedBootJar: "out/soong/.intermediates/prebuilt_com.android.foo/android_common_com.android.foo/deapexer/javalib/framework-foo.jar", 11024 }, 11025 { 11026 desc: "Prebuilt apex prebuilt_com.android.foo.v2 is selected, profile should come from .prof deapexed from the prebuilt", 11027 selectedApexContributions: "foo.prebuilt.v2.contributions", 11028 expectedBootJar: "out/soong/.intermediates/com.android.foo.v2/android_common_com.android.foo/deapexer/javalib/framework-foo.jar", 11029 }, 11030 } 11031 11032 fragment := java.ApexVariantReference{ 11033 Apex: proptools.StringPtr("com.android.foo"), 11034 Module: proptools.StringPtr("foo-bootclasspath-fragment"), 11035 } 11036 11037 for _, tc := range testCases { 11038 preparer := android.GroupFixturePreparers( 11039 java.FixtureConfigureApexBootJars("com.android.foo:framework-foo"), 11040 android.FixtureMergeMockFs(map[string][]byte{ 11041 "system/sepolicy/apex/com.android.foo-file_contexts": nil, 11042 }), 11043 // Make sure that we have atleast one platform library so that we can check the monolithic hiddenapi 11044 // file creation. 11045 java.FixtureConfigureBootJars("platform:foo"), 11046 android.FixtureModifyMockFS(func(fs android.MockFS) { 11047 fs["platform/Android.bp"] = []byte(` 11048 java_library { 11049 name: "foo", 11050 srcs: ["Test.java"], 11051 compile_dex: true, 11052 } 11053 `) 11054 fs["platform/Test.java"] = nil 11055 }), 11056 11057 android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ADSERVICES", tc.selectedApexContributions), 11058 ) 11059 ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment) 11060 checkBootDexJarPath(t, ctx, "framework-foo", tc.expectedBootJar) 11061 checkBootJarsPackageCheck(t, ctx, tc.expectedBootJar) 11062 checkBootJarsForMonolithicHiddenapi(t, ctx, tc.expectedBootJar) 11063 } 11064} 11065 11066// Test that product packaging installs the selected mainline module (either source or a specific prebuilt) 11067// RELEASE_APEX_CONTIRBUTIONS_* build flags will be used to select the correct prebuilt for a specific release config 11068func TestInstallationRulesForMultipleApexPrebuilts(t *testing.T) { 11069 t.Parallel() 11070 // for a mainline module family, check that only the flagged soong module is visible to make 11071 checkHideFromMake := func(t *testing.T, ctx *android.TestContext, visibleModuleName string, hiddenModuleNames []string) { 11072 variation := func(moduleName string) string { 11073 ret := "android_common_com.android.foo" 11074 if moduleName == "com.google.android.foo" { 11075 ret = "android_common_com.google.android.foo_com.google.android.foo" 11076 } 11077 return ret 11078 } 11079 11080 visibleModule := ctx.ModuleForTests(visibleModuleName, variation(visibleModuleName)).Module() 11081 android.AssertBoolEquals(t, "Apex "+visibleModuleName+" selected using apex_contributions should be visible to make", false, visibleModule.IsHideFromMake()) 11082 11083 for _, hiddenModuleName := range hiddenModuleNames { 11084 hiddenModule := ctx.ModuleForTests(hiddenModuleName, variation(hiddenModuleName)).Module() 11085 android.AssertBoolEquals(t, "Apex "+hiddenModuleName+" not selected using apex_contributions should be hidden from make", true, hiddenModule.IsHideFromMake()) 11086 11087 } 11088 } 11089 11090 bp := ` 11091 apex_key { 11092 name: "com.android.foo.key", 11093 public_key: "com.android.foo.avbpubkey", 11094 private_key: "com.android.foo.pem", 11095 } 11096 11097 // AOSP source apex 11098 apex { 11099 name: "com.android.foo", 11100 key: "com.android.foo.key", 11101 updatable: false, 11102 } 11103 11104 // Google source apex 11105 override_apex { 11106 name: "com.google.android.foo", 11107 base: "com.android.foo", 11108 key: "com.android.foo.key", 11109 } 11110 11111 // Prebuilt Google APEX. 11112 11113 prebuilt_apex { 11114 name: "com.google.android.foo", 11115 apex_name: "com.android.foo", 11116 src: "com.android.foo-arm.apex", 11117 prefer: true, // prefer is set to true on both the prebuilts to induce an error if flagging is not present 11118 } 11119 11120 // Another Prebuilt Google APEX 11121 prebuilt_apex { 11122 name: "com.google.android.foo.v2", 11123 apex_name: "com.android.foo", 11124 source_apex_name: "com.google.android.foo", 11125 src: "com.android.foo-arm.apex", 11126 prefer: true, // prefer is set to true on both the prebuilts to induce an error if flagging is not present 11127 } 11128 11129 // APEX contribution modules 11130 11131 apex_contributions { 11132 name: "foo.source.contributions", 11133 api_domain: "com.android.foo", 11134 contents: ["com.google.android.foo"], 11135 } 11136 11137 apex_contributions { 11138 name: "foo.prebuilt.contributions", 11139 api_domain: "com.android.foo", 11140 contents: ["prebuilt_com.google.android.foo"], 11141 } 11142 11143 apex_contributions { 11144 name: "foo.prebuilt.v2.contributions", 11145 api_domain: "com.android.foo", 11146 contents: ["prebuilt_com.google.android.foo.v2"], 11147 } 11148 11149 // This is an incompatible module because it selects multiple versions of the same mainline module 11150 apex_contributions { 11151 name: "foo.prebuilt.duplicate.contributions", 11152 api_domain: "com.android.foo", 11153 contents: [ 11154 "prebuilt_com.google.android.foo", 11155 "prebuilt_com.google.android.foo.v2", 11156 ], 11157 } 11158 ` 11159 11160 testCases := []struct { 11161 desc string 11162 selectedApexContributions string 11163 expectedVisibleModuleName string 11164 expectedHiddenModuleNames []string 11165 expectedError string 11166 }{ 11167 { 11168 desc: "Source apex is selected, prebuilts should be hidden from make", 11169 selectedApexContributions: "foo.source.contributions", 11170 expectedVisibleModuleName: "com.google.android.foo", 11171 expectedHiddenModuleNames: []string{"prebuilt_com.google.android.foo", "prebuilt_com.google.android.foo.v2"}, 11172 }, 11173 { 11174 desc: "Prebuilt apex prebuilt_com.android.foo is selected, source and the other prebuilt should be hidden from make", 11175 selectedApexContributions: "foo.prebuilt.contributions", 11176 expectedVisibleModuleName: "prebuilt_com.google.android.foo", 11177 expectedHiddenModuleNames: []string{"com.google.android.foo", "prebuilt_com.google.android.foo.v2"}, 11178 }, 11179 { 11180 desc: "Prebuilt apex prebuilt_com.android.fooi.v2 is selected, source and the other prebuilt should be hidden from make", 11181 selectedApexContributions: "foo.prebuilt.v2.contributions", 11182 expectedVisibleModuleName: "prebuilt_com.google.android.foo.v2", 11183 expectedHiddenModuleNames: []string{"com.google.android.foo", "prebuilt_com.google.android.foo"}, 11184 }, 11185 { 11186 desc: "Multiple versions of a prebuilt apex is selected in the same release config", 11187 selectedApexContributions: "foo.prebuilt.duplicate.contributions", 11188 expectedError: "Found duplicate variations of the same module in apex_contributions: prebuilt_com.google.android.foo and prebuilt_com.google.android.foo.v2", 11189 }, 11190 } 11191 11192 for _, tc := range testCases { 11193 preparer := android.GroupFixturePreparers( 11194 android.FixtureMergeMockFs(map[string][]byte{ 11195 "system/sepolicy/apex/com.android.foo-file_contexts": nil, 11196 }), 11197 android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ADSERVICES", tc.selectedApexContributions), 11198 ) 11199 if tc.expectedError != "" { 11200 preparer = preparer.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(tc.expectedError)) 11201 testApex(t, bp, preparer) 11202 return 11203 } 11204 ctx := testApex(t, bp, preparer) 11205 11206 // Check that 11207 // 1. The contents of the selected apex_contributions are visible to make 11208 // 2. The rest of the apexes in the mainline module family (source or other prebuilt) is hidden from make 11209 checkHideFromMake(t, ctx, tc.expectedVisibleModuleName, tc.expectedHiddenModuleNames) 11210 } 11211} 11212 11213// Test that product packaging installs the selected mainline module in workspaces withtout source mainline module 11214func TestInstallationRulesForMultipleApexPrebuiltsWithoutSource(t *testing.T) { 11215 t.Parallel() 11216 // for a mainline module family, check that only the flagged soong module is visible to make 11217 checkHideFromMake := func(t *testing.T, ctx *android.TestContext, visibleModuleNames []string, hiddenModuleNames []string) { 11218 variation := func(moduleName string) string { 11219 ret := "android_common_com.android.adservices" 11220 if moduleName == "com.google.android.foo" { 11221 ret = "android_common_com.google.android.foo_com.google.android.foo" 11222 } 11223 return ret 11224 } 11225 11226 for _, visibleModuleName := range visibleModuleNames { 11227 visibleModule := ctx.ModuleForTests(visibleModuleName, variation(visibleModuleName)).Module() 11228 android.AssertBoolEquals(t, "Apex "+visibleModuleName+" selected using apex_contributions should be visible to make", false, visibleModule.IsHideFromMake()) 11229 } 11230 11231 for _, hiddenModuleName := range hiddenModuleNames { 11232 hiddenModule := ctx.ModuleForTests(hiddenModuleName, variation(hiddenModuleName)).Module() 11233 android.AssertBoolEquals(t, "Apex "+hiddenModuleName+" not selected using apex_contributions should be hidden from make", true, hiddenModule.IsHideFromMake()) 11234 11235 } 11236 } 11237 11238 bp := ` 11239 apex_key { 11240 name: "com.android.adservices.key", 11241 public_key: "com.android.adservices.avbpubkey", 11242 private_key: "com.android.adservices.pem", 11243 } 11244 11245 // AOSP source apex 11246 apex { 11247 name: "com.android.adservices", 11248 key: "com.android.adservices.key", 11249 updatable: false, 11250 } 11251 11252 // Prebuilt Google APEX. 11253 11254 prebuilt_apex { 11255 name: "com.google.android.adservices", 11256 apex_name: "com.android.adservices", 11257 src: "com.android.foo-arm.apex", 11258 } 11259 11260 // Another Prebuilt Google APEX 11261 prebuilt_apex { 11262 name: "com.google.android.adservices.v2", 11263 apex_name: "com.android.adservices", 11264 src: "com.android.foo-arm.apex", 11265 } 11266 11267 // APEX contribution modules 11268 11269 11270 apex_contributions { 11271 name: "adservices.prebuilt.contributions", 11272 api_domain: "com.android.adservices", 11273 contents: ["prebuilt_com.google.android.adservices"], 11274 } 11275 11276 apex_contributions { 11277 name: "adservices.prebuilt.v2.contributions", 11278 api_domain: "com.android.adservices", 11279 contents: ["prebuilt_com.google.android.adservices.v2"], 11280 } 11281 ` 11282 11283 testCases := []struct { 11284 desc string 11285 selectedApexContributions string 11286 expectedVisibleModuleNames []string 11287 expectedHiddenModuleNames []string 11288 }{ 11289 { 11290 desc: "No apex contributions selected, source aosp apex should be visible, and mainline prebuilts should be hidden", 11291 selectedApexContributions: "", 11292 expectedVisibleModuleNames: []string{"com.android.adservices"}, 11293 expectedHiddenModuleNames: []string{"com.google.android.adservices", "com.google.android.adservices.v2"}, 11294 }, 11295 { 11296 desc: "Prebuilt apex prebuilt_com.android.foo is selected", 11297 selectedApexContributions: "adservices.prebuilt.contributions", 11298 expectedVisibleModuleNames: []string{"com.android.adservices", "com.google.android.adservices"}, 11299 expectedHiddenModuleNames: []string{"com.google.android.adservices.v2"}, 11300 }, 11301 { 11302 desc: "Prebuilt apex prebuilt_com.android.foo.v2 is selected", 11303 selectedApexContributions: "adservices.prebuilt.v2.contributions", 11304 expectedVisibleModuleNames: []string{"com.android.adservices", "com.google.android.adservices.v2"}, 11305 expectedHiddenModuleNames: []string{"com.google.android.adservices"}, 11306 }, 11307 } 11308 11309 for _, tc := range testCases { 11310 preparer := android.GroupFixturePreparers( 11311 android.FixtureMergeMockFs(map[string][]byte{ 11312 "system/sepolicy/apex/com.android.adservices-file_contexts": nil, 11313 }), 11314 android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ADSERVICES", tc.selectedApexContributions), 11315 ) 11316 ctx := testApex(t, bp, preparer) 11317 11318 checkHideFromMake(t, ctx, tc.expectedVisibleModuleNames, tc.expectedHiddenModuleNames) 11319 } 11320} 11321 11322func TestAconfifDeclarationsValidation(t *testing.T) { 11323 t.Parallel() 11324 aconfigDeclarationLibraryString := func(moduleNames []string) (ret string) { 11325 for _, moduleName := range moduleNames { 11326 ret += fmt.Sprintf(` 11327 aconfig_declarations { 11328 name: "%[1]s", 11329 package: "com.example.package", 11330 container: "system", 11331 srcs: [ 11332 "%[1]s.aconfig", 11333 ], 11334 } 11335 java_aconfig_library { 11336 name: "%[1]s-lib", 11337 aconfig_declarations: "%[1]s", 11338 } 11339 `, moduleName) 11340 } 11341 return ret 11342 } 11343 11344 result := android.GroupFixturePreparers( 11345 prepareForApexTest, 11346 java.PrepareForTestWithJavaSdkLibraryFiles, 11347 java.FixtureWithLastReleaseApis("foo"), 11348 ).RunTestWithBp(t, ` 11349 java_library { 11350 name: "baz-java-lib", 11351 static_libs: [ 11352 "baz-lib", 11353 ], 11354 } 11355 filegroup { 11356 name: "qux-filegroup", 11357 device_common_srcs: [ 11358 ":qux-lib{.generated_srcjars}", 11359 ], 11360 } 11361 filegroup { 11362 name: "qux-another-filegroup", 11363 srcs: [ 11364 ":qux-filegroup", 11365 ], 11366 } 11367 java_library { 11368 name: "quux-java-lib", 11369 srcs: [ 11370 "a.java", 11371 ], 11372 libs: [ 11373 "quux-lib", 11374 ], 11375 } 11376 java_sdk_library { 11377 name: "foo", 11378 srcs: [ 11379 ":qux-another-filegroup", 11380 ], 11381 api_packages: ["foo"], 11382 system: { 11383 enabled: true, 11384 }, 11385 module_lib: { 11386 enabled: true, 11387 }, 11388 test: { 11389 enabled: true, 11390 }, 11391 static_libs: [ 11392 "bar-lib", 11393 ], 11394 libs: [ 11395 "baz-java-lib", 11396 "quux-java-lib", 11397 ], 11398 aconfig_declarations: [ 11399 "bar", 11400 ], 11401 } 11402 `+aconfigDeclarationLibraryString([]string{"bar", "baz", "qux", "quux"})) 11403 11404 m := result.ModuleForTests("foo.stubs.source", "android_common") 11405 outDir := "out/soong/.intermediates" 11406 11407 // Arguments passed to aconfig to retrieve the state of the flags defined in the 11408 // textproto files 11409 aconfigFlagArgs := m.Output("released-flagged-apis-exportable.txt").Args["flags_path"] 11410 11411 // "bar-lib" is a static_lib of "foo" and is passed to metalava as classpath. Thus the 11412 // cache file provided by the associated aconfig_declarations module "bar" should be passed 11413 // to aconfig. 11414 android.AssertStringDoesContain(t, "cache file of a java_aconfig_library static_lib "+ 11415 "passed as an input", 11416 aconfigFlagArgs, fmt.Sprintf("%s/%s/intermediate.pb", outDir, "bar")) 11417 11418 // "baz-java-lib", which statically depends on "baz-lib", is a lib of "foo" and is passed 11419 // to metalava as classpath. Thus the cache file provided by the associated 11420 // aconfig_declarations module "baz" should be passed to aconfig. 11421 android.AssertStringDoesContain(t, "cache file of a lib that statically depends on "+ 11422 "java_aconfig_library passed as an input", 11423 aconfigFlagArgs, fmt.Sprintf("%s/%s/intermediate.pb", outDir, "baz")) 11424 11425 // "qux-lib" is passed to metalava as src via the filegroup, thus the cache file provided by 11426 // the associated aconfig_declarations module "qux" should be passed to aconfig. 11427 android.AssertStringDoesContain(t, "cache file of srcs java_aconfig_library passed as an "+ 11428 "input", 11429 aconfigFlagArgs, fmt.Sprintf("%s/%s/intermediate.pb", outDir, "qux")) 11430 11431 // "quux-java-lib" is a lib of "foo" and is passed to metalava as classpath, but does not 11432 // statically depend on "quux-lib". Therefore, the cache file provided by the associated 11433 // aconfig_declarations module "quux" should not be passed to aconfig. 11434 android.AssertStringDoesNotContain(t, "cache file of a lib that does not statically "+ 11435 "depend on java_aconfig_library not passed as an input", 11436 aconfigFlagArgs, fmt.Sprintf("%s/%s/intermediate.pb", outDir, "quux")) 11437} 11438 11439func TestMultiplePrebuiltsWithSameBase(t *testing.T) { 11440 t.Parallel() 11441 ctx := testApex(t, ` 11442 apex { 11443 name: "myapex", 11444 key: "myapex.key", 11445 prebuilts: ["myetc", "myetc2"], 11446 min_sdk_version: "29", 11447 } 11448 apex_key { 11449 name: "myapex.key", 11450 public_key: "testkey.avbpubkey", 11451 private_key: "testkey.pem", 11452 } 11453 11454 prebuilt_etc { 11455 name: "myetc", 11456 src: "myprebuilt", 11457 filename: "myfilename", 11458 } 11459 prebuilt_etc { 11460 name: "myetc2", 11461 sub_dir: "mysubdir", 11462 src: "myprebuilt", 11463 filename: "myfilename", 11464 } 11465 `, withFiles(android.MockFS{ 11466 "packages/modules/common/build/allowed_deps.txt": nil, 11467 })) 11468 11469 ab := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle) 11470 data := android.AndroidMkDataForTest(t, ctx, ab) 11471 var builder strings.Builder 11472 data.Custom(&builder, ab.BaseModuleName(), "TARGET_", "", data) 11473 androidMk := builder.String() 11474 11475 android.AssertStringDoesContain(t, "not found", androidMk, "LOCAL_MODULE := etc_myfilename.myapex") 11476 android.AssertStringDoesContain(t, "not found", androidMk, "LOCAL_MODULE := etc_mysubdir_myfilename.myapex") 11477} 11478 11479func TestApexMinSdkVersionOverride(t *testing.T) { 11480 t.Parallel() 11481 checkMinSdkVersion := func(t *testing.T, module android.TestingModule, expectedMinSdkVersion string) { 11482 args := module.Rule("apexRule").Args 11483 optFlags := args["opt_flags"] 11484 if !strings.Contains(optFlags, "--min_sdk_version "+expectedMinSdkVersion) { 11485 t.Errorf("%s: Expected min_sdk_version=%s, got: %s", module.Module(), expectedMinSdkVersion, optFlags) 11486 } 11487 } 11488 11489 checkHasDep := func(t *testing.T, ctx *android.TestContext, m android.Module, wantDep android.Module) { 11490 t.Helper() 11491 found := false 11492 ctx.VisitDirectDeps(m, func(dep blueprint.Module) { 11493 if dep == wantDep { 11494 found = true 11495 } 11496 }) 11497 if !found { 11498 t.Errorf("Could not find a dependency from %v to %v\n", m, wantDep) 11499 } 11500 } 11501 11502 ctx := testApex(t, ` 11503 apex { 11504 name: "com.android.apex30", 11505 min_sdk_version: "30", 11506 key: "apex30.key", 11507 java_libs: ["javalib"], 11508 } 11509 11510 java_library { 11511 name: "javalib", 11512 srcs: ["A.java"], 11513 apex_available: ["com.android.apex30"], 11514 min_sdk_version: "30", 11515 sdk_version: "current", 11516 compile_dex: true, 11517 } 11518 11519 override_apex { 11520 name: "com.mycompany.android.apex30", 11521 base: "com.android.apex30", 11522 } 11523 11524 override_apex { 11525 name: "com.mycompany.android.apex31", 11526 base: "com.android.apex30", 11527 min_sdk_version: "31", 11528 } 11529 11530 apex_key { 11531 name: "apex30.key", 11532 public_key: "testkey.avbpubkey", 11533 private_key: "testkey.pem", 11534 } 11535 11536 `, android.FixtureMergeMockFs(android.MockFS{ 11537 "system/sepolicy/apex/com.android.apex30-file_contexts": nil, 11538 }), 11539 ) 11540 11541 baseModule := ctx.ModuleForTests("com.android.apex30", "android_common_com.android.apex30") 11542 checkMinSdkVersion(t, baseModule, "30") 11543 11544 // Override module, but uses same min_sdk_version 11545 overridingModuleSameMinSdkVersion := ctx.ModuleForTests("com.android.apex30", "android_common_com.mycompany.android.apex30_com.mycompany.android.apex30") 11546 javalibApex30Variant := ctx.ModuleForTests("javalib", "android_common_apex30") 11547 checkMinSdkVersion(t, overridingModuleSameMinSdkVersion, "30") 11548 checkHasDep(t, ctx, overridingModuleSameMinSdkVersion.Module(), javalibApex30Variant.Module()) 11549 11550 // Override module, uses different min_sdk_version 11551 overridingModuleDifferentMinSdkVersion := ctx.ModuleForTests("com.android.apex30", "android_common_com.mycompany.android.apex31_com.mycompany.android.apex31") 11552 javalibApex31Variant := ctx.ModuleForTests("javalib", "android_common_apex31") 11553 checkMinSdkVersion(t, overridingModuleDifferentMinSdkVersion, "31") 11554 checkHasDep(t, ctx, overridingModuleDifferentMinSdkVersion.Module(), javalibApex31Variant.Module()) 11555} 11556 11557func TestOverrideApexWithPrebuiltApexPreferred(t *testing.T) { 11558 t.Parallel() 11559 context := android.GroupFixturePreparers( 11560 android.PrepareForIntegrationTestWithAndroid, 11561 PrepareForTestWithApexBuildComponents, 11562 android.FixtureMergeMockFs(android.MockFS{ 11563 "system/sepolicy/apex/foo-file_contexts": nil, 11564 }), 11565 ) 11566 res := context.RunTestWithBp(t, ` 11567 apex { 11568 name: "foo", 11569 key: "myapex.key", 11570 apex_available_name: "com.android.foo", 11571 variant_version: "0", 11572 updatable: false, 11573 } 11574 apex_key { 11575 name: "myapex.key", 11576 public_key: "testkey.avbpubkey", 11577 private_key: "testkey.pem", 11578 } 11579 prebuilt_apex { 11580 name: "foo", 11581 src: "foo.apex", 11582 prefer: true, 11583 } 11584 override_apex { 11585 name: "myoverrideapex", 11586 base: "foo", 11587 } 11588 `) 11589 11590 java.CheckModuleHasDependency(t, res.TestContext, "myoverrideapex", "android_common_myoverrideapex_myoverrideapex", "foo") 11591} 11592 11593func TestUpdatableApexMinSdkVersionCurrent(t *testing.T) { 11594 t.Parallel() 11595 testApexError(t, `"myapex" .*: updatable: updatable APEXes should not set min_sdk_version to current. Please use a finalized API level or a recognized in-development codename`, ` 11596 apex { 11597 name: "myapex", 11598 key: "myapex.key", 11599 updatable: true, 11600 min_sdk_version: "current", 11601 } 11602 11603 apex_key { 11604 name: "myapex.key", 11605 public_key: "testkey.avbpubkey", 11606 private_key: "testkey.pem", 11607 } 11608 `) 11609} 11610 11611func TestPrebuiltStubNoinstall(t *testing.T) { 11612 t.Parallel() 11613 testFunc := func(t *testing.T, expectLibfooOnSystemLib bool, fs android.MockFS) { 11614 result := android.GroupFixturePreparers( 11615 prepareForApexTest, 11616 android.PrepareForTestWithAndroidMk, 11617 android.PrepareForTestWithMakevars, 11618 android.FixtureMergeMockFs(fs), 11619 ).RunTest(t) 11620 11621 ldRule := result.ModuleForTests("installedlib", "android_arm64_armv8-a_shared").Rule("ld") 11622 android.AssertStringDoesContain(t, "", ldRule.Args["libFlags"], "android_arm64_armv8-a_shared_current/libfoo.so") 11623 11624 installRules := result.InstallMakeRulesForTesting(t) 11625 11626 var installedlibRule *android.InstallMakeRule 11627 for i, rule := range installRules { 11628 if rule.Target == "out/target/product/test_device/system/lib/installedlib.so" { 11629 if installedlibRule != nil { 11630 t.Errorf("Duplicate install rules for %s", rule.Target) 11631 } 11632 installedlibRule = &installRules[i] 11633 } 11634 } 11635 if installedlibRule == nil { 11636 t.Errorf("No install rule found for installedlib") 11637 return 11638 } 11639 11640 if expectLibfooOnSystemLib { 11641 android.AssertStringListContains(t, 11642 "installedlib doesn't have install dependency on libfoo impl", 11643 installedlibRule.OrderOnlyDeps, 11644 "out/target/product/test_device/system/lib/libfoo.so") 11645 } else { 11646 android.AssertStringListDoesNotContain(t, 11647 "installedlib has install dependency on libfoo stub", 11648 installedlibRule.Deps, 11649 "out/target/product/test_device/system/lib/libfoo.so") 11650 android.AssertStringListDoesNotContain(t, 11651 "installedlib has order-only install dependency on libfoo stub", 11652 installedlibRule.OrderOnlyDeps, 11653 "out/target/product/test_device/system/lib/libfoo.so") 11654 } 11655 } 11656 11657 prebuiltLibfooBp := []byte(` 11658 cc_prebuilt_library { 11659 name: "libfoo", 11660 prefer: true, 11661 srcs: ["libfoo.so"], 11662 stubs: { 11663 versions: ["1"], 11664 }, 11665 apex_available: ["apexfoo"], 11666 } 11667 `) 11668 11669 apexfooBp := []byte(` 11670 apex { 11671 name: "apexfoo", 11672 key: "apexfoo.key", 11673 native_shared_libs: ["libfoo"], 11674 updatable: false, 11675 compile_multilib: "both", 11676 } 11677 apex_key { 11678 name: "apexfoo.key", 11679 public_key: "testkey.avbpubkey", 11680 private_key: "testkey.pem", 11681 } 11682 `) 11683 11684 installedlibBp := []byte(` 11685 cc_library { 11686 name: "installedlib", 11687 shared_libs: ["libfoo"], 11688 } 11689 `) 11690 11691 t.Run("prebuilt stub (without source): no install", func(t *testing.T) { 11692 t.Parallel() 11693 testFunc( 11694 t, 11695 /*expectLibfooOnSystemLib=*/ false, 11696 android.MockFS{ 11697 "prebuilts/module_sdk/art/current/Android.bp": prebuiltLibfooBp, 11698 "apexfoo/Android.bp": apexfooBp, 11699 "system/sepolicy/apex/apexfoo-file_contexts": nil, 11700 "Android.bp": installedlibBp, 11701 }, 11702 ) 11703 }) 11704 11705 disabledSourceLibfooBp := []byte(` 11706 cc_library { 11707 name: "libfoo", 11708 enabled: false, 11709 stubs: { 11710 versions: ["1"], 11711 }, 11712 apex_available: ["apexfoo"], 11713 } 11714 `) 11715 11716 t.Run("prebuilt stub (with disabled source): no install", func(t *testing.T) { 11717 t.Parallel() 11718 testFunc( 11719 t, 11720 /*expectLibfooOnSystemLib=*/ false, 11721 android.MockFS{ 11722 "prebuilts/module_sdk/art/current/Android.bp": prebuiltLibfooBp, 11723 "impl/Android.bp": disabledSourceLibfooBp, 11724 "apexfoo/Android.bp": apexfooBp, 11725 "system/sepolicy/apex/apexfoo-file_contexts": nil, 11726 "Android.bp": installedlibBp, 11727 }, 11728 ) 11729 }) 11730} 11731 11732func TestSdkLibraryTransitiveClassLoaderContext(t *testing.T) { 11733 t.Parallel() 11734 // This test case tests that listing the impl lib instead of the top level java_sdk_library 11735 // in libs of android_app and java_library does not lead to class loader context device/host 11736 // path mismatch errors. 11737 android.GroupFixturePreparers( 11738 prepareForApexTest, 11739 android.PrepareForIntegrationTestWithAndroid, 11740 PrepareForTestWithApexBuildComponents, 11741 android.FixtureModifyEnv(func(env map[string]string) { 11742 env["DISABLE_CONTAINER_CHECK"] = "true" 11743 }), 11744 withFiles(filesForSdkLibrary), 11745 android.FixtureMergeMockFs(android.MockFS{ 11746 "system/sepolicy/apex/com.android.foo30-file_contexts": nil, 11747 }), 11748 ).RunTestWithBp(t, ` 11749 apex { 11750 name: "com.android.foo30", 11751 key: "myapex.key", 11752 updatable: true, 11753 bootclasspath_fragments: [ 11754 "foo-bootclasspath-fragment", 11755 ], 11756 java_libs: [ 11757 "bar", 11758 ], 11759 apps: [ 11760 "bar-app", 11761 ], 11762 min_sdk_version: "30", 11763 } 11764 apex_key { 11765 name: "myapex.key", 11766 public_key: "testkey.avbpubkey", 11767 private_key: "testkey.pem", 11768 } 11769 bootclasspath_fragment { 11770 name: "foo-bootclasspath-fragment", 11771 contents: [ 11772 "framework-foo", 11773 ], 11774 apex_available: [ 11775 "com.android.foo30", 11776 ], 11777 hidden_api: { 11778 split_packages: ["*"] 11779 }, 11780 } 11781 11782 java_sdk_library { 11783 name: "framework-foo", 11784 srcs: [ 11785 "A.java" 11786 ], 11787 unsafe_ignore_missing_latest_api: true, 11788 apex_available: [ 11789 "com.android.foo30", 11790 ], 11791 compile_dex: true, 11792 sdk_version: "core_current", 11793 shared_library: false, 11794 } 11795 11796 java_library { 11797 name: "bar", 11798 srcs: [ 11799 "A.java" 11800 ], 11801 libs: [ 11802 "framework-foo.impl", 11803 ], 11804 apex_available: [ 11805 "com.android.foo30", 11806 ], 11807 sdk_version: "core_current", 11808 compile_dex: true, 11809 } 11810 11811 java_library { 11812 name: "baz", 11813 srcs: [ 11814 "A.java" 11815 ], 11816 libs: [ 11817 "bar", 11818 ], 11819 sdk_version: "core_current", 11820 } 11821 11822 android_app { 11823 name: "bar-app", 11824 srcs: [ 11825 "A.java" 11826 ], 11827 libs: [ 11828 "baz", 11829 "framework-foo.impl", 11830 ], 11831 apex_available: [ 11832 "com.android.foo30", 11833 ], 11834 sdk_version: "core_current", 11835 min_sdk_version: "30", 11836 manifest: "AndroidManifest.xml", 11837 updatable: true, 11838 } 11839 `) 11840} 11841 11842// If an apex sets system_ext_specific: true, its systemserverclasspath libraries must set this property as well. 11843func TestApexSSCPJarMustBeInSamePartitionAsApex(t *testing.T) { 11844 t.Parallel() 11845 testApexError(t, `foo is an apex systemserver jar, but its partition does not match the partition of its containing apex`, ` 11846 apex { 11847 name: "myapex", 11848 key: "myapex.key", 11849 systemserverclasspath_fragments: [ 11850 "mysystemserverclasspathfragment", 11851 ], 11852 min_sdk_version: "29", 11853 updatable: true, 11854 system_ext_specific: true, 11855 } 11856 11857 apex_key { 11858 name: "myapex.key", 11859 public_key: "testkey.avbpubkey", 11860 private_key: "testkey.pem", 11861 } 11862 11863 java_library { 11864 name: "foo", 11865 srcs: ["b.java"], 11866 min_sdk_version: "29", 11867 installable: true, 11868 apex_available: [ 11869 "myapex", 11870 ], 11871 sdk_version: "current", 11872 } 11873 11874 systemserverclasspath_fragment { 11875 name: "mysystemserverclasspathfragment", 11876 contents: [ 11877 "foo", 11878 ], 11879 apex_available: [ 11880 "myapex", 11881 ], 11882 } 11883 `, 11884 dexpreopt.FixtureSetApexSystemServerJars("myapex:foo"), 11885 ) 11886} 11887 11888// partitions should not package the artifacts that are included inside the apex. 11889func TestFilesystemWithApexDeps(t *testing.T) { 11890 t.Parallel() 11891 result := testApex(t, ` 11892 android_filesystem { 11893 name: "myfilesystem", 11894 deps: ["myapex"], 11895 } 11896 apex { 11897 name: "myapex", 11898 key: "myapex.key", 11899 binaries: ["binfoo"], 11900 native_shared_libs: ["libfoo"], 11901 apps: ["appfoo"], 11902 updatable: false, 11903 } 11904 apex_key { 11905 name: "myapex.key", 11906 } 11907 cc_binary { 11908 name: "binfoo", 11909 apex_available: ["myapex"], 11910 } 11911 cc_library { 11912 name: "libfoo", 11913 apex_available: ["myapex"], 11914 } 11915 android_app { 11916 name: "appfoo", 11917 sdk_version: "current", 11918 apex_available: ["myapex"], 11919 } 11920 `, filesystem.PrepareForTestWithFilesystemBuildComponents) 11921 11922 partition := result.ModuleForTests("myfilesystem", "android_common") 11923 fileList := android.ContentFromFileRuleForTests(t, result, partition.Output("fileList")) 11924 android.AssertDeepEquals(t, "filesystem with apex", "apex/myapex.apex\n", fileList) 11925} 11926 11927func TestApexVerifyNativeImplementationLibs(t *testing.T) { 11928 t.Parallel() 11929 11930 extractDepenencyPathFromErrors := func(errs []error) []string { 11931 i := slices.IndexFunc(errs, func(err error) bool { 11932 return strings.Contains(err.Error(), "dependency path:") 11933 }) 11934 if i < 0 { 11935 return nil 11936 } 11937 var dependencyPath []string 11938 for _, err := range errs[i+1:] { 11939 s := err.Error() 11940 lastSpace := strings.LastIndexByte(s, ' ') 11941 if lastSpace >= 0 { 11942 dependencyPath = append(dependencyPath, s[lastSpace+1:]) 11943 } 11944 } 11945 return dependencyPath 11946 } 11947 11948 checkErrors := func(wantDependencyPath []string) func(t *testing.T, result *android.TestResult) { 11949 return func(t *testing.T, result *android.TestResult) { 11950 t.Helper() 11951 if len(result.Errs) == 0 { 11952 t.Fatalf("expected errors") 11953 } 11954 t.Log("found errors:") 11955 for _, err := range result.Errs { 11956 t.Log(err) 11957 } 11958 if g, w := result.Errs[0].Error(), "library in apex transitively linked against implementation library"; !strings.Contains(g, w) { 11959 t.Fatalf("expected error %q, got %q", w, g) 11960 } 11961 dependencyPath := extractDepenencyPathFromErrors(result.Errs) 11962 if g, w := dependencyPath, wantDependencyPath; !slices.Equal(g, w) { 11963 t.Errorf("expected dependency path %q, got %q", w, g) 11964 } 11965 } 11966 } 11967 11968 addToSharedLibs := func(module, lib string) func(bp *bpmodify.Blueprint) { 11969 return func(bp *bpmodify.Blueprint) { 11970 m := bp.ModulesByName(module) 11971 props, err := m.GetOrCreateProperty(bpmodify.List, "shared_libs") 11972 if err != nil { 11973 panic(err) 11974 } 11975 props.AddStringToList(lib) 11976 } 11977 } 11978 11979 bpTemplate := ` 11980 apex { 11981 name: "myapex", 11982 key: "myapex.key", 11983 native_shared_libs: ["mylib"], 11984 rust_dyn_libs: ["libmyrust"], 11985 binaries: ["mybin", "myrustbin"], 11986 jni_libs: ["libjni"], 11987 apps: ["myapp"], 11988 updatable: false, 11989 } 11990 11991 apex { 11992 name: "otherapex", 11993 key: "myapex.key", 11994 native_shared_libs: ["libotherapex"], 11995 updatable: false, 11996 } 11997 11998 apex_key { 11999 name: "myapex.key", 12000 public_key: "testkey.avbpubkey", 12001 private_key: "testkey.pem", 12002 } 12003 12004 cc_library { 12005 name: "mylib", 12006 srcs: ["foo.cpp"], 12007 apex_available: ["myapex"], 12008 } 12009 12010 cc_binary { 12011 name: "mybin", 12012 srcs: ["foo.cpp"], 12013 apex_available: ["myapex"], 12014 } 12015 12016 rust_library { 12017 name: "libmyrust", 12018 crate_name: "myrust", 12019 srcs: ["src/lib.rs"], 12020 rustlibs: ["libmyrust_transitive_dylib"], 12021 rlibs: ["libmyrust_transitive_rlib"], 12022 apex_available: ["myapex"], 12023 } 12024 12025 rust_library{ 12026 name: "libmyrust_transitive_dylib", 12027 crate_name: "myrust_transitive_dylib", 12028 srcs: ["src/lib.rs"], 12029 apex_available: ["myapex"], 12030 } 12031 12032 rust_library { 12033 name: "libmyrust_transitive_rlib", 12034 crate_name: "myrust_transitive_rlib", 12035 srcs: ["src/lib.rs"], 12036 apex_available: ["myapex"], 12037 } 12038 12039 rust_binary { 12040 name: "myrustbin", 12041 srcs: ["src/main.rs"], 12042 apex_available: ["myapex"], 12043 } 12044 12045 cc_library { 12046 name: "libbar", 12047 sdk_version: "current", 12048 srcs: ["bar.cpp"], 12049 apex_available: ["myapex"], 12050 stl: "none", 12051 } 12052 12053 android_app { 12054 name: "myapp", 12055 jni_libs: ["libembeddedjni"], 12056 use_embedded_native_libs: true, 12057 sdk_version: "current", 12058 apex_available: ["myapex"], 12059 } 12060 12061 cc_library { 12062 name: "libembeddedjni", 12063 sdk_version: "current", 12064 srcs: ["bar.cpp"], 12065 apex_available: ["myapex"], 12066 stl: "none", 12067 } 12068 12069 cc_library { 12070 name: "libjni", 12071 sdk_version: "current", 12072 srcs: ["bar.cpp"], 12073 apex_available: ["myapex"], 12074 stl: "none", 12075 } 12076 12077 cc_library { 12078 name: "libotherapex", 12079 sdk_version: "current", 12080 srcs: ["otherapex.cpp"], 12081 apex_available: ["otherapex"], 12082 stubs: { 12083 symbol_file: "libotherapex.map.txt", 12084 versions: ["1", "2", "3"], 12085 }, 12086 stl: "none", 12087 } 12088 12089 cc_library { 12090 name: "libplatform", 12091 sdk_version: "current", 12092 srcs: ["libplatform.cpp"], 12093 stubs: { 12094 symbol_file: "libplatform.map.txt", 12095 versions: ["1", "2", "3"], 12096 }, 12097 stl: "none", 12098 system_shared_libs: [], 12099 } 12100 ` 12101 12102 testCases := []struct { 12103 name string 12104 bpModifier func(bp *bpmodify.Blueprint) 12105 dependencyPath []string 12106 }{ 12107 { 12108 name: "library dependency in other apex", 12109 bpModifier: addToSharedLibs("mylib", "libotherapex#impl"), 12110 dependencyPath: []string{"myapex", "mylib", "libotherapex"}, 12111 }, 12112 { 12113 name: "transitive library dependency in other apex", 12114 bpModifier: func(bp *bpmodify.Blueprint) { 12115 addToSharedLibs("mylib", "libbar")(bp) 12116 addToSharedLibs("libbar", "libotherapex#impl")(bp) 12117 }, 12118 dependencyPath: []string{"myapex", "mylib", "libbar", "libotherapex"}, 12119 }, 12120 { 12121 name: "library dependency in platform", 12122 bpModifier: addToSharedLibs("mylib", "libplatform#impl"), 12123 dependencyPath: []string{"myapex", "mylib", "libplatform"}, 12124 }, 12125 { 12126 name: "jni library dependency in other apex", 12127 bpModifier: addToSharedLibs("libjni", "libotherapex#impl"), 12128 dependencyPath: []string{"myapex", "libjni", "libotherapex"}, 12129 }, 12130 { 12131 name: "transitive jni library dependency in other apex", 12132 bpModifier: func(bp *bpmodify.Blueprint) { 12133 addToSharedLibs("libjni", "libbar")(bp) 12134 addToSharedLibs("libbar", "libotherapex#impl")(bp) 12135 }, 12136 dependencyPath: []string{"myapex", "libjni", "libbar", "libotherapex"}, 12137 }, 12138 { 12139 name: "jni library dependency in platform", 12140 bpModifier: addToSharedLibs("libjni", "libplatform#impl"), 12141 dependencyPath: []string{"myapex", "libjni", "libplatform"}, 12142 }, 12143 { 12144 name: "transitive jni library dependency in platform", 12145 bpModifier: func(bp *bpmodify.Blueprint) { 12146 addToSharedLibs("libjni", "libbar")(bp) 12147 addToSharedLibs("libbar", "libplatform#impl")(bp) 12148 }, 12149 dependencyPath: []string{"myapex", "libjni", "libbar", "libplatform"}, 12150 }, 12151 { 12152 name: "app jni library dependency in other apex", 12153 bpModifier: addToSharedLibs("libembeddedjni", "libotherapex#impl"), 12154 dependencyPath: []string{"myapex", "myapp", "libembeddedjni", "libotherapex"}, 12155 }, 12156 { 12157 name: "transitive app jni library dependency in other apex", 12158 bpModifier: func(bp *bpmodify.Blueprint) { 12159 addToSharedLibs("libembeddedjni", "libbar")(bp) 12160 addToSharedLibs("libbar", "libotherapex#impl")(bp) 12161 }, 12162 dependencyPath: []string{"myapex", "myapp", "libembeddedjni", "libbar", "libotherapex"}, 12163 }, 12164 { 12165 name: "app jni library dependency in platform", 12166 bpModifier: addToSharedLibs("libembeddedjni", "libplatform#impl"), 12167 dependencyPath: []string{"myapex", "myapp", "libembeddedjni", "libplatform"}, 12168 }, 12169 { 12170 name: "transitive app jni library dependency in platform", 12171 bpModifier: func(bp *bpmodify.Blueprint) { 12172 addToSharedLibs("libembeddedjni", "libbar")(bp) 12173 addToSharedLibs("libbar", "libplatform#impl")(bp) 12174 }, 12175 dependencyPath: []string{"myapex", "myapp", "libembeddedjni", "libbar", "libplatform"}, 12176 }, 12177 { 12178 name: "binary dependency in other apex", 12179 bpModifier: addToSharedLibs("mybin", "libotherapex#impl"), 12180 dependencyPath: []string{"myapex", "mybin", "libotherapex"}, 12181 }, 12182 { 12183 name: "transitive binary dependency in other apex", 12184 bpModifier: func(bp *bpmodify.Blueprint) { 12185 addToSharedLibs("mybin", "libbar")(bp) 12186 addToSharedLibs("libbar", "libotherapex#impl")(bp) 12187 }, 12188 dependencyPath: []string{"myapex", "mybin", "libbar", "libotherapex"}, 12189 }, 12190 { 12191 name: "binary dependency in platform", 12192 bpModifier: addToSharedLibs("mybin", "libplatform#impl"), 12193 dependencyPath: []string{"myapex", "mybin", "libplatform"}, 12194 }, 12195 { 12196 name: "transitive binary dependency in platform", 12197 bpModifier: func(bp *bpmodify.Blueprint) { 12198 addToSharedLibs("mybin", "libbar")(bp) 12199 addToSharedLibs("libbar", "libplatform#impl")(bp) 12200 }, 12201 dependencyPath: []string{"myapex", "mybin", "libbar", "libplatform"}, 12202 }, 12203 12204 { 12205 name: "rust library dependency in other apex", 12206 bpModifier: addToSharedLibs("libmyrust", "libotherapex#impl"), 12207 dependencyPath: []string{"myapex", "libmyrust", "libotherapex"}, 12208 }, 12209 { 12210 name: "transitive rust library dependency in other apex", 12211 bpModifier: func(bp *bpmodify.Blueprint) { 12212 addToSharedLibs("libmyrust", "libbar")(bp) 12213 addToSharedLibs("libbar", "libotherapex#impl")(bp) 12214 }, 12215 dependencyPath: []string{"myapex", "libmyrust", "libbar", "libotherapex"}, 12216 }, 12217 { 12218 name: "rust library dependency in platform", 12219 bpModifier: addToSharedLibs("libmyrust", "libplatform#impl"), 12220 dependencyPath: []string{"myapex", "libmyrust", "libplatform"}, 12221 }, 12222 { 12223 name: "transitive rust library dependency in platform", 12224 bpModifier: func(bp *bpmodify.Blueprint) { 12225 addToSharedLibs("libmyrust", "libbar")(bp) 12226 addToSharedLibs("libbar", "libplatform#impl")(bp) 12227 }, 12228 dependencyPath: []string{"myapex", "libmyrust", "libbar", "libplatform"}, 12229 }, 12230 { 12231 name: "transitive rust library dylib dependency in other apex", 12232 bpModifier: func(bp *bpmodify.Blueprint) { 12233 addToSharedLibs("libmyrust_transitive_dylib", "libotherapex#impl")(bp) 12234 }, 12235 dependencyPath: []string{"myapex", "libmyrust", "libmyrust_transitive_dylib", "libotherapex"}, 12236 }, 12237 { 12238 name: "transitive rust library dylib dependency in platform", 12239 bpModifier: func(bp *bpmodify.Blueprint) { 12240 addToSharedLibs("libmyrust_transitive_dylib", "libplatform#impl")(bp) 12241 }, 12242 dependencyPath: []string{"myapex", "libmyrust", "libmyrust_transitive_dylib", "libplatform"}, 12243 }, 12244 { 12245 name: "transitive rust library rlib dependency in other apex", 12246 bpModifier: func(bp *bpmodify.Blueprint) { 12247 addToSharedLibs("libmyrust_transitive_rlib", "libotherapex#impl")(bp) 12248 }, 12249 dependencyPath: []string{"myapex", "libmyrust", "libmyrust_transitive_rlib", "libotherapex"}, 12250 }, 12251 { 12252 name: "transitive rust library rlib dependency in platform", 12253 bpModifier: func(bp *bpmodify.Blueprint) { 12254 addToSharedLibs("libmyrust_transitive_rlib", "libplatform#impl")(bp) 12255 }, 12256 dependencyPath: []string{"myapex", "libmyrust", "libmyrust_transitive_rlib", "libplatform"}, 12257 }, 12258 { 12259 name: "rust binary dependency in other apex", 12260 bpModifier: addToSharedLibs("myrustbin", "libotherapex#impl"), 12261 dependencyPath: []string{"myapex", "myrustbin", "libotherapex"}, 12262 }, 12263 { 12264 name: "transitive rust binary dependency in other apex", 12265 bpModifier: func(bp *bpmodify.Blueprint) { 12266 addToSharedLibs("myrustbin", "libbar")(bp) 12267 addToSharedLibs("libbar", "libotherapex#impl")(bp) 12268 }, 12269 dependencyPath: []string{"myapex", "myrustbin", "libbar", "libotherapex"}, 12270 }, 12271 { 12272 name: "rust binary dependency in platform", 12273 bpModifier: addToSharedLibs("myrustbin", "libplatform#impl"), 12274 dependencyPath: []string{"myapex", "myrustbin", "libplatform"}, 12275 }, 12276 { 12277 name: "transitive rust binary dependency in platform", 12278 bpModifier: func(bp *bpmodify.Blueprint) { 12279 addToSharedLibs("myrustbin", "libbar")(bp) 12280 addToSharedLibs("libbar", "libplatform#impl")(bp) 12281 }, 12282 dependencyPath: []string{"myapex", "myrustbin", "libbar", "libplatform"}, 12283 }, 12284 } 12285 12286 for _, testCase := range testCases { 12287 t.Run(testCase.name, func(t *testing.T) { 12288 t.Parallel() 12289 bp, err := bpmodify.NewBlueprint("", []byte(bpTemplate)) 12290 if err != nil { 12291 t.Fatal(err) 12292 } 12293 if testCase.bpModifier != nil { 12294 func() { 12295 defer func() { 12296 if r := recover(); r != nil { 12297 t.Fatalf("panic in bpModifier: %v", r) 12298 } 12299 }() 12300 testCase.bpModifier(bp) 12301 }() 12302 } 12303 android.GroupFixturePreparers( 12304 android.PrepareForTestWithAndroidBuildComponents, 12305 cc.PrepareForTestWithCcBuildComponents, 12306 java.PrepareForTestWithDexpreopt, 12307 rust.PrepareForTestWithRustDefaultModules, 12308 PrepareForTestWithApexBuildComponents, 12309 prepareForTestWithMyapex, 12310 prepareForTestWithOtherapex, 12311 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 12312 variables.BuildId = proptools.StringPtr("TEST.BUILD_ID") 12313 }), 12314 ).ExtendWithErrorHandler(android.FixtureCustomErrorHandler(checkErrors(testCase.dependencyPath))). 12315 RunTestWithBp(t, bp.String()) 12316 }) 12317 } 12318} 12319