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