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