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