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 "os" 20 "path" 21 "path/filepath" 22 "reflect" 23 "regexp" 24 "sort" 25 "strconv" 26 "strings" 27 "testing" 28 29 "github.com/google/blueprint/proptools" 30 31 "android/soong/android" 32 "android/soong/bpf" 33 "android/soong/cc" 34 "android/soong/dexpreopt" 35 prebuilt_etc "android/soong/etc" 36 "android/soong/java" 37 "android/soong/rust" 38 "android/soong/sh" 39) 40 41// names returns name list from white space separated string 42func names(s string) (ns []string) { 43 for _, n := range strings.Split(s, " ") { 44 if len(n) > 0 { 45 ns = append(ns, n) 46 } 47 } 48 return 49} 50 51func testApexError(t *testing.T, pattern, bp string, preparers ...android.FixturePreparer) { 52 t.Helper() 53 android.GroupFixturePreparers( 54 prepareForApexTest, 55 android.GroupFixturePreparers(preparers...), 56 ). 57 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)). 58 RunTestWithBp(t, bp) 59} 60 61func testApex(t *testing.T, bp string, preparers ...android.FixturePreparer) *android.TestContext { 62 t.Helper() 63 64 optionalBpPreparer := android.NullFixturePreparer 65 if bp != "" { 66 optionalBpPreparer = android.FixtureWithRootAndroidBp(bp) 67 } 68 69 result := android.GroupFixturePreparers( 70 prepareForApexTest, 71 android.GroupFixturePreparers(preparers...), 72 optionalBpPreparer, 73 ).RunTest(t) 74 75 return result.TestContext 76} 77 78func withFiles(files android.MockFS) android.FixturePreparer { 79 return files.AddToFixture() 80} 81 82func withTargets(targets map[android.OsType][]android.Target) android.FixturePreparer { 83 return android.FixtureModifyConfig(func(config android.Config) { 84 for k, v := range targets { 85 config.Targets[k] = v 86 } 87 }) 88} 89 90// withNativeBridgeTargets sets configuration with targets including: 91// - X86_64 (primary) 92// - X86 (secondary) 93// - Arm64 on X86_64 (native bridge) 94// - Arm on X86 (native bridge) 95var withNativeBridgeEnabled = android.FixtureModifyConfig( 96 func(config android.Config) { 97 config.Targets[android.Android] = []android.Target{ 98 {Os: android.Android, Arch: android.Arch{ArchType: android.X86_64, ArchVariant: "silvermont", Abi: []string{"arm64-v8a"}}, 99 NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""}, 100 {Os: android.Android, Arch: android.Arch{ArchType: android.X86, ArchVariant: "silvermont", Abi: []string{"armeabi-v7a"}}, 101 NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""}, 102 {Os: android.Android, Arch: android.Arch{ArchType: android.Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, 103 NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "x86_64", NativeBridgeRelativePath: "arm64"}, 104 {Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, 105 NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "x86", NativeBridgeRelativePath: "arm"}, 106 } 107 }, 108) 109 110func withManifestPackageNameOverrides(specs []string) android.FixturePreparer { 111 return android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 112 variables.ManifestPackageNameOverrides = specs 113 }) 114} 115 116var withBinder32bit = android.FixtureModifyProductVariables( 117 func(variables android.FixtureProductVariables) { 118 variables.Binder32bit = proptools.BoolPtr(true) 119 }, 120) 121 122var withUnbundledBuild = android.FixtureModifyProductVariables( 123 func(variables android.FixtureProductVariables) { 124 variables.Unbundled_build = proptools.BoolPtr(true) 125 }, 126) 127 128// Legacy preparer used for running tests within the apex package. 129// 130// This includes everything that was needed to run any test in the apex package prior to the 131// introduction of the test fixtures. Tests that are being converted to use fixtures directly 132// rather than through the testApex...() methods should avoid using this and instead use the 133// various preparers directly, using android.GroupFixturePreparers(...) to group them when 134// necessary. 135// 136// deprecated 137var prepareForApexTest = android.GroupFixturePreparers( 138 // General preparers in alphabetical order as test infrastructure will enforce correct 139 // registration order. 140 android.PrepareForTestWithAndroidBuildComponents, 141 bpf.PrepareForTestWithBpf, 142 cc.PrepareForTestWithCcBuildComponents, 143 java.PrepareForTestWithJavaDefaultModules, 144 prebuilt_etc.PrepareForTestWithPrebuiltEtc, 145 rust.PrepareForTestWithRustDefaultModules, 146 sh.PrepareForTestWithShBuildComponents, 147 148 PrepareForTestWithApexBuildComponents, 149 150 // Additional apex test specific preparers. 151 android.FixtureAddTextFile("system/sepolicy/Android.bp", ` 152 filegroup { 153 name: "myapex-file_contexts", 154 srcs: [ 155 "apex/myapex-file_contexts", 156 ], 157 } 158 `), 159 prepareForTestWithMyapex, 160 android.FixtureMergeMockFs(android.MockFS{ 161 "a.java": nil, 162 "PrebuiltAppFoo.apk": nil, 163 "PrebuiltAppFooPriv.apk": nil, 164 "apex_manifest.json": nil, 165 "AndroidManifest.xml": nil, 166 "system/sepolicy/apex/myapex.updatable-file_contexts": nil, 167 "system/sepolicy/apex/myapex2-file_contexts": nil, 168 "system/sepolicy/apex/otherapex-file_contexts": nil, 169 "system/sepolicy/apex/com.android.vndk-file_contexts": nil, 170 "system/sepolicy/apex/com.android.vndk.current-file_contexts": nil, 171 "mylib.cpp": nil, 172 "mytest.cpp": nil, 173 "mytest1.cpp": nil, 174 "mytest2.cpp": nil, 175 "mytest3.cpp": nil, 176 "myprebuilt": nil, 177 "my_include": nil, 178 "foo/bar/MyClass.java": nil, 179 "prebuilt.jar": nil, 180 "prebuilt.so": nil, 181 "vendor/foo/devkeys/test.x509.pem": nil, 182 "vendor/foo/devkeys/test.pk8": nil, 183 "testkey.x509.pem": nil, 184 "testkey.pk8": nil, 185 "testkey.override.x509.pem": nil, 186 "testkey.override.pk8": nil, 187 "vendor/foo/devkeys/testkey.avbpubkey": nil, 188 "vendor/foo/devkeys/testkey.pem": nil, 189 "NOTICE": nil, 190 "custom_notice": nil, 191 "custom_notice_for_static_lib": nil, 192 "testkey2.avbpubkey": nil, 193 "testkey2.pem": nil, 194 "myapex-arm64.apex": nil, 195 "myapex-arm.apex": nil, 196 "myapex.apks": nil, 197 "frameworks/base/api/current.txt": nil, 198 "framework/aidl/a.aidl": nil, 199 "build/make/core/proguard.flags": nil, 200 "build/make/core/proguard_basic_keeps.flags": nil, 201 "dummy.txt": nil, 202 "baz": nil, 203 "bar/baz": nil, 204 "testdata/baz": nil, 205 "AppSet.apks": nil, 206 "foo.rs": nil, 207 "libfoo.jar": nil, 208 "libbar.jar": nil, 209 }, 210 ), 211 212 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 213 variables.DeviceVndkVersion = proptools.StringPtr("current") 214 variables.DefaultAppCertificate = proptools.StringPtr("vendor/foo/devkeys/test") 215 variables.CertificateOverrides = []string{"myapex_keytest:myapex.certificate.override"} 216 variables.Platform_sdk_codename = proptools.StringPtr("Q") 217 variables.Platform_sdk_final = proptools.BoolPtr(false) 218 variables.Platform_version_active_codenames = []string{"Q"} 219 variables.Platform_vndk_version = proptools.StringPtr("29") 220 }), 221) 222 223var prepareForTestWithMyapex = android.FixtureMergeMockFs(android.MockFS{ 224 "system/sepolicy/apex/myapex-file_contexts": nil, 225}) 226 227// ensure that 'result' equals 'expected' 228func ensureEquals(t *testing.T, result string, expected string) { 229 t.Helper() 230 if result != expected { 231 t.Errorf("%q != %q", expected, result) 232 } 233} 234 235// ensure that 'result' contains 'expected' 236func ensureContains(t *testing.T, result string, expected string) { 237 t.Helper() 238 if !strings.Contains(result, expected) { 239 t.Errorf("%q is not found in %q", expected, result) 240 } 241} 242 243// ensure that 'result' contains 'expected' exactly one time 244func ensureContainsOnce(t *testing.T, result string, expected string) { 245 t.Helper() 246 count := strings.Count(result, expected) 247 if count != 1 { 248 t.Errorf("%q is found %d times (expected 1 time) in %q", expected, count, result) 249 } 250} 251 252// ensures that 'result' does not contain 'notExpected' 253func ensureNotContains(t *testing.T, result string, notExpected string) { 254 t.Helper() 255 if strings.Contains(result, notExpected) { 256 t.Errorf("%q is found in %q", notExpected, result) 257 } 258} 259 260func ensureMatches(t *testing.T, result string, expectedRex string) { 261 ok, err := regexp.MatchString(expectedRex, result) 262 if err != nil { 263 t.Fatalf("regexp failure trying to match %s against `%s` expression: %s", result, expectedRex, err) 264 return 265 } 266 if !ok { 267 t.Errorf("%s does not match regular expession %s", result, expectedRex) 268 } 269} 270 271func ensureListContains(t *testing.T, result []string, expected string) { 272 t.Helper() 273 if !android.InList(expected, result) { 274 t.Errorf("%q is not found in %v", expected, result) 275 } 276} 277 278func ensureListNotContains(t *testing.T, result []string, notExpected string) { 279 t.Helper() 280 if android.InList(notExpected, result) { 281 t.Errorf("%q is found in %v", notExpected, result) 282 } 283} 284 285func ensureListEmpty(t *testing.T, result []string) { 286 t.Helper() 287 if len(result) > 0 { 288 t.Errorf("%q is expected to be empty", result) 289 } 290} 291 292func ensureListNotEmpty(t *testing.T, result []string) { 293 t.Helper() 294 if len(result) == 0 { 295 t.Errorf("%q is expected to be not empty", result) 296 } 297} 298 299// Minimal test 300func TestBasicApex(t *testing.T) { 301 ctx := testApex(t, ` 302 apex_defaults { 303 name: "myapex-defaults", 304 manifest: ":myapex.manifest", 305 androidManifest: ":myapex.androidmanifest", 306 key: "myapex.key", 307 binaries: ["foo.rust"], 308 native_shared_libs: [ 309 "mylib", 310 "libfoo.ffi", 311 ], 312 rust_dyn_libs: ["libfoo.dylib.rust"], 313 multilib: { 314 both: { 315 binaries: ["foo"], 316 } 317 }, 318 java_libs: [ 319 "myjar", 320 "myjar_dex", 321 ], 322 updatable: false, 323 } 324 325 apex { 326 name: "myapex", 327 defaults: ["myapex-defaults"], 328 } 329 330 apex_key { 331 name: "myapex.key", 332 public_key: "testkey.avbpubkey", 333 private_key: "testkey.pem", 334 } 335 336 filegroup { 337 name: "myapex.manifest", 338 srcs: ["apex_manifest.json"], 339 } 340 341 filegroup { 342 name: "myapex.androidmanifest", 343 srcs: ["AndroidManifest.xml"], 344 } 345 346 cc_library { 347 name: "mylib", 348 srcs: ["mylib.cpp"], 349 shared_libs: [ 350 "mylib2", 351 "libbar.ffi", 352 ], 353 system_shared_libs: [], 354 stl: "none", 355 // TODO: remove //apex_available:platform 356 apex_available: [ 357 "//apex_available:platform", 358 "myapex", 359 ], 360 } 361 362 cc_binary { 363 name: "foo", 364 srcs: ["mylib.cpp"], 365 compile_multilib: "both", 366 multilib: { 367 lib32: { 368 suffix: "32", 369 }, 370 lib64: { 371 suffix: "64", 372 }, 373 }, 374 symlinks: ["foo_link_"], 375 symlink_preferred_arch: true, 376 system_shared_libs: [], 377 static_executable: true, 378 stl: "none", 379 apex_available: [ "myapex", "com.android.gki.*" ], 380 } 381 382 rust_binary { 383 name: "foo.rust", 384 srcs: ["foo.rs"], 385 rlibs: ["libfoo.rlib.rust"], 386 dylibs: ["libfoo.dylib.rust"], 387 apex_available: ["myapex"], 388 } 389 390 rust_library_rlib { 391 name: "libfoo.rlib.rust", 392 srcs: ["foo.rs"], 393 crate_name: "foo", 394 apex_available: ["myapex"], 395 shared_libs: ["libfoo.shared_from_rust"], 396 } 397 398 cc_library_shared { 399 name: "libfoo.shared_from_rust", 400 srcs: ["mylib.cpp"], 401 system_shared_libs: [], 402 stl: "none", 403 apex_available: ["myapex"], 404 } 405 406 rust_library_dylib { 407 name: "libfoo.dylib.rust", 408 srcs: ["foo.rs"], 409 crate_name: "foo", 410 apex_available: ["myapex"], 411 } 412 413 rust_ffi_shared { 414 name: "libfoo.ffi", 415 srcs: ["foo.rs"], 416 crate_name: "foo", 417 apex_available: ["myapex"], 418 } 419 420 rust_ffi_shared { 421 name: "libbar.ffi", 422 srcs: ["foo.rs"], 423 crate_name: "bar", 424 apex_available: ["myapex"], 425 } 426 427 apex { 428 name: "com.android.gki.fake", 429 binaries: ["foo"], 430 key: "myapex.key", 431 file_contexts: ":myapex-file_contexts", 432 updatable: false, 433 } 434 435 cc_library_shared { 436 name: "mylib2", 437 srcs: ["mylib.cpp"], 438 system_shared_libs: [], 439 stl: "none", 440 notice: "custom_notice", 441 static_libs: ["libstatic"], 442 // TODO: remove //apex_available:platform 443 apex_available: [ 444 "//apex_available:platform", 445 "myapex", 446 ], 447 } 448 449 cc_prebuilt_library_shared { 450 name: "mylib2", 451 srcs: ["prebuilt.so"], 452 // TODO: remove //apex_available:platform 453 apex_available: [ 454 "//apex_available:platform", 455 "myapex", 456 ], 457 } 458 459 cc_library_static { 460 name: "libstatic", 461 srcs: ["mylib.cpp"], 462 system_shared_libs: [], 463 stl: "none", 464 notice: "custom_notice_for_static_lib", 465 // TODO: remove //apex_available:platform 466 apex_available: [ 467 "//apex_available:platform", 468 "myapex", 469 ], 470 } 471 472 java_library { 473 name: "myjar", 474 srcs: ["foo/bar/MyClass.java"], 475 stem: "myjar_stem", 476 sdk_version: "none", 477 system_modules: "none", 478 static_libs: ["myotherjar"], 479 libs: ["mysharedjar"], 480 // TODO: remove //apex_available:platform 481 apex_available: [ 482 "//apex_available:platform", 483 "myapex", 484 ], 485 } 486 487 dex_import { 488 name: "myjar_dex", 489 jars: ["prebuilt.jar"], 490 apex_available: [ 491 "//apex_available:platform", 492 "myapex", 493 ], 494 } 495 496 java_library { 497 name: "myotherjar", 498 srcs: ["foo/bar/MyClass.java"], 499 sdk_version: "none", 500 system_modules: "none", 501 // TODO: remove //apex_available:platform 502 apex_available: [ 503 "//apex_available:platform", 504 "myapex", 505 ], 506 } 507 508 java_library { 509 name: "mysharedjar", 510 srcs: ["foo/bar/MyClass.java"], 511 sdk_version: "none", 512 system_modules: "none", 513 } 514 `) 515 516 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule") 517 518 // Make sure that Android.mk is created 519 ab := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle) 520 data := android.AndroidMkDataForTest(t, ctx, ab) 521 var builder strings.Builder 522 data.Custom(&builder, ab.BaseModuleName(), "TARGET_", "", data) 523 524 androidMk := builder.String() 525 ensureContains(t, androidMk, "LOCAL_MODULE := mylib.myapex\n") 526 ensureNotContains(t, androidMk, "LOCAL_MODULE := mylib.com.android.myapex\n") 527 528 optFlags := apexRule.Args["opt_flags"] 529 ensureContains(t, optFlags, "--pubkey vendor/foo/devkeys/testkey.avbpubkey") 530 // Ensure that the NOTICE output is being packaged as an asset. 531 ensureContains(t, optFlags, "--assets_dir out/soong/.intermediates/myapex/android_common_myapex_image/NOTICE") 532 533 copyCmds := apexRule.Args["copy_commands"] 534 535 // Ensure that main rule creates an output 536 ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned") 537 538 // Ensure that apex variant is created for the direct dep 539 ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_apex10000") 540 ensureListContains(t, ctx.ModuleVariantsForTests("myjar"), "android_common_apex10000") 541 ensureListContains(t, ctx.ModuleVariantsForTests("myjar_dex"), "android_common_apex10000") 542 ensureListContains(t, ctx.ModuleVariantsForTests("foo.rust"), "android_arm64_armv8-a_apex10000") 543 ensureListContains(t, ctx.ModuleVariantsForTests("libfoo.ffi"), "android_arm64_armv8-a_shared_apex10000") 544 545 // Ensure that apex variant is created for the indirect dep 546 ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_apex10000") 547 ensureListContains(t, ctx.ModuleVariantsForTests("myotherjar"), "android_common_apex10000") 548 ensureListContains(t, ctx.ModuleVariantsForTests("libfoo.rlib.rust"), "android_arm64_armv8-a_rlib_dylib-std_apex10000") 549 ensureListContains(t, ctx.ModuleVariantsForTests("libfoo.dylib.rust"), "android_arm64_armv8-a_dylib_apex10000") 550 ensureListContains(t, ctx.ModuleVariantsForTests("libbar.ffi"), "android_arm64_armv8-a_shared_apex10000") 551 ensureListContains(t, ctx.ModuleVariantsForTests("libfoo.shared_from_rust"), "android_arm64_armv8-a_shared_apex10000") 552 553 // Ensure that both direct and indirect deps are copied into apex 554 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") 555 ensureContains(t, copyCmds, "image.apex/lib64/mylib2.so") 556 ensureContains(t, copyCmds, "image.apex/javalib/myjar_stem.jar") 557 ensureContains(t, copyCmds, "image.apex/javalib/myjar_dex.jar") 558 ensureContains(t, copyCmds, "image.apex/lib64/libfoo.dylib.rust.dylib.so") 559 ensureContains(t, copyCmds, "image.apex/lib64/libfoo.ffi.so") 560 ensureContains(t, copyCmds, "image.apex/lib64/libbar.ffi.so") 561 ensureContains(t, copyCmds, "image.apex/lib64/libfoo.shared_from_rust.so") 562 // .. but not for java libs 563 ensureNotContains(t, copyCmds, "image.apex/javalib/myotherjar.jar") 564 ensureNotContains(t, copyCmds, "image.apex/javalib/msharedjar.jar") 565 566 // Ensure that the platform variant ends with _shared or _common 567 ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared") 568 ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared") 569 ensureListContains(t, ctx.ModuleVariantsForTests("myjar"), "android_common") 570 ensureListContains(t, ctx.ModuleVariantsForTests("myotherjar"), "android_common") 571 ensureListContains(t, ctx.ModuleVariantsForTests("mysharedjar"), "android_common") 572 573 // Ensure that dynamic dependency to java libs are not included 574 ensureListNotContains(t, ctx.ModuleVariantsForTests("mysharedjar"), "android_common_myapex") 575 576 // Ensure that all symlinks are present. 577 found_foo_link_64 := false 578 found_foo := false 579 for _, cmd := range strings.Split(copyCmds, " && ") { 580 if strings.HasPrefix(cmd, "ln -sfn foo64") { 581 if strings.HasSuffix(cmd, "bin/foo") { 582 found_foo = true 583 } else if strings.HasSuffix(cmd, "bin/foo_link_64") { 584 found_foo_link_64 = true 585 } 586 } 587 } 588 good := found_foo && found_foo_link_64 589 if !good { 590 t.Errorf("Could not find all expected symlinks! foo: %t, foo_link_64: %t. Command was %s", found_foo, found_foo_link_64, copyCmds) 591 } 592 593 mergeNoticesRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("mergeNoticesRule") 594 noticeInputs := mergeNoticesRule.Inputs.Strings() 595 if len(noticeInputs) != 3 { 596 t.Errorf("number of input notice files: expected = 3, actual = %q", len(noticeInputs)) 597 } 598 ensureListContains(t, noticeInputs, "NOTICE") 599 ensureListContains(t, noticeInputs, "custom_notice") 600 ensureListContains(t, noticeInputs, "custom_notice_for_static_lib") 601 602 fullDepsInfo := strings.Split(ctx.ModuleForTests("myapex", "android_common_myapex_image").Output("depsinfo/fulllist.txt").Args["content"], "\\n") 603 ensureListContains(t, fullDepsInfo, " myjar(minSdkVersion:(no version)) <- myapex") 604 ensureListContains(t, fullDepsInfo, " mylib2(minSdkVersion:(no version)) <- mylib") 605 ensureListContains(t, fullDepsInfo, " myotherjar(minSdkVersion:(no version)) <- myjar") 606 ensureListContains(t, fullDepsInfo, " mysharedjar(minSdkVersion:(no version)) (external) <- myjar") 607 608 flatDepsInfo := strings.Split(ctx.ModuleForTests("myapex", "android_common_myapex_image").Output("depsinfo/flatlist.txt").Args["content"], "\\n") 609 ensureListContains(t, flatDepsInfo, "myjar(minSdkVersion:(no version))") 610 ensureListContains(t, flatDepsInfo, "mylib2(minSdkVersion:(no version))") 611 ensureListContains(t, flatDepsInfo, "myotherjar(minSdkVersion:(no version))") 612 ensureListContains(t, flatDepsInfo, "mysharedjar(minSdkVersion:(no version)) (external)") 613} 614 615func TestDefaults(t *testing.T) { 616 ctx := testApex(t, ` 617 apex_defaults { 618 name: "myapex-defaults", 619 key: "myapex.key", 620 prebuilts: ["myetc"], 621 native_shared_libs: ["mylib"], 622 java_libs: ["myjar"], 623 apps: ["AppFoo"], 624 rros: ["rro"], 625 bpfs: ["bpf"], 626 updatable: false, 627 } 628 629 prebuilt_etc { 630 name: "myetc", 631 src: "myprebuilt", 632 } 633 634 apex { 635 name: "myapex", 636 defaults: ["myapex-defaults"], 637 } 638 639 apex_key { 640 name: "myapex.key", 641 public_key: "testkey.avbpubkey", 642 private_key: "testkey.pem", 643 } 644 645 cc_library { 646 name: "mylib", 647 system_shared_libs: [], 648 stl: "none", 649 apex_available: [ "myapex" ], 650 } 651 652 java_library { 653 name: "myjar", 654 srcs: ["foo/bar/MyClass.java"], 655 sdk_version: "none", 656 system_modules: "none", 657 apex_available: [ "myapex" ], 658 } 659 660 android_app { 661 name: "AppFoo", 662 srcs: ["foo/bar/MyClass.java"], 663 sdk_version: "none", 664 system_modules: "none", 665 apex_available: [ "myapex" ], 666 } 667 668 runtime_resource_overlay { 669 name: "rro", 670 theme: "blue", 671 } 672 673 bpf { 674 name: "bpf", 675 srcs: ["bpf.c", "bpf2.c"], 676 } 677 678 `) 679 ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{ 680 "etc/myetc", 681 "javalib/myjar.jar", 682 "lib64/mylib.so", 683 "app/AppFoo/AppFoo.apk", 684 "overlay/blue/rro.apk", 685 "etc/bpf/bpf.o", 686 "etc/bpf/bpf2.o", 687 }) 688} 689 690func TestApexManifest(t *testing.T) { 691 ctx := testApex(t, ` 692 apex { 693 name: "myapex", 694 key: "myapex.key", 695 updatable: false, 696 } 697 698 apex_key { 699 name: "myapex.key", 700 public_key: "testkey.avbpubkey", 701 private_key: "testkey.pem", 702 } 703 `) 704 705 module := ctx.ModuleForTests("myapex", "android_common_myapex_image") 706 args := module.Rule("apexRule").Args 707 if manifest := args["manifest"]; manifest != module.Output("apex_manifest.pb").Output.String() { 708 t.Error("manifest should be apex_manifest.pb, but " + manifest) 709 } 710} 711 712func TestBasicZipApex(t *testing.T) { 713 ctx := testApex(t, ` 714 apex { 715 name: "myapex", 716 key: "myapex.key", 717 payload_type: "zip", 718 native_shared_libs: ["mylib"], 719 updatable: false, 720 } 721 722 apex_key { 723 name: "myapex.key", 724 public_key: "testkey.avbpubkey", 725 private_key: "testkey.pem", 726 } 727 728 cc_library { 729 name: "mylib", 730 srcs: ["mylib.cpp"], 731 shared_libs: ["mylib2"], 732 system_shared_libs: [], 733 stl: "none", 734 apex_available: [ "myapex" ], 735 } 736 737 cc_library { 738 name: "mylib2", 739 srcs: ["mylib.cpp"], 740 system_shared_libs: [], 741 stl: "none", 742 apex_available: [ "myapex" ], 743 } 744 `) 745 746 zipApexRule := ctx.ModuleForTests("myapex", "android_common_myapex_zip").Rule("zipApexRule") 747 copyCmds := zipApexRule.Args["copy_commands"] 748 749 // Ensure that main rule creates an output 750 ensureContains(t, zipApexRule.Output.String(), "myapex.zipapex.unsigned") 751 752 // Ensure that APEX variant is created for the direct dep 753 ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_apex10000") 754 755 // Ensure that APEX variant is created for the indirect dep 756 ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_apex10000") 757 758 // Ensure that both direct and indirect deps are copied into apex 759 ensureContains(t, copyCmds, "image.zipapex/lib64/mylib.so") 760 ensureContains(t, copyCmds, "image.zipapex/lib64/mylib2.so") 761} 762 763func TestApexWithStubs(t *testing.T) { 764 ctx := testApex(t, ` 765 apex { 766 name: "myapex", 767 key: "myapex.key", 768 native_shared_libs: ["mylib", "mylib3"], 769 updatable: false, 770 } 771 772 apex_key { 773 name: "myapex.key", 774 public_key: "testkey.avbpubkey", 775 private_key: "testkey.pem", 776 } 777 778 cc_library { 779 name: "mylib", 780 srcs: ["mylib.cpp"], 781 shared_libs: ["mylib2", "mylib3"], 782 system_shared_libs: [], 783 stl: "none", 784 apex_available: [ "myapex" ], 785 } 786 787 cc_library { 788 name: "mylib2", 789 srcs: ["mylib.cpp"], 790 cflags: ["-include mylib.h"], 791 system_shared_libs: [], 792 stl: "none", 793 stubs: { 794 versions: ["1", "2", "3"], 795 }, 796 } 797 798 cc_library { 799 name: "mylib3", 800 srcs: ["mylib.cpp"], 801 shared_libs: ["mylib4"], 802 system_shared_libs: [], 803 stl: "none", 804 stubs: { 805 versions: ["10", "11", "12"], 806 }, 807 apex_available: [ "myapex" ], 808 } 809 810 cc_library { 811 name: "mylib4", 812 srcs: ["mylib.cpp"], 813 system_shared_libs: [], 814 stl: "none", 815 apex_available: [ "myapex" ], 816 } 817 `) 818 819 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule") 820 copyCmds := apexRule.Args["copy_commands"] 821 822 // Ensure that direct non-stubs dep is always included 823 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") 824 825 // Ensure that indirect stubs dep is not included 826 ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so") 827 828 // Ensure that direct stubs dep is included 829 ensureContains(t, copyCmds, "image.apex/lib64/mylib3.so") 830 831 mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"] 832 833 // Ensure that mylib is linking with the latest version of stubs for mylib2 834 ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_current/mylib2.so") 835 // ... and not linking to the non-stub (impl) variant of mylib2 836 ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so") 837 838 // Ensure that mylib is linking with the non-stub (impl) of mylib3 (because mylib3 is in the same apex) 839 ensureContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_apex10000/mylib3.so") 840 // .. and not linking to the stubs variant of mylib3 841 ensureNotContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_12/mylib3.so") 842 843 // Ensure that stubs libs are built without -include flags 844 mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"] 845 ensureNotContains(t, mylib2Cflags, "-include ") 846 847 // Ensure that genstub is invoked with --apex 848 ensureContains(t, "--apex", ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"]) 849 850 ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{ 851 "lib64/mylib.so", 852 "lib64/mylib3.so", 853 "lib64/mylib4.so", 854 }) 855} 856 857func TestApexWithStubsWithMinSdkVersion(t *testing.T) { 858 t.Parallel() 859 ctx := testApex(t, ` 860 apex { 861 name: "myapex", 862 key: "myapex.key", 863 native_shared_libs: ["mylib", "mylib3"], 864 min_sdk_version: "29", 865 } 866 867 apex_key { 868 name: "myapex.key", 869 public_key: "testkey.avbpubkey", 870 private_key: "testkey.pem", 871 } 872 873 cc_library { 874 name: "mylib", 875 srcs: ["mylib.cpp"], 876 shared_libs: ["mylib2", "mylib3"], 877 system_shared_libs: [], 878 stl: "none", 879 apex_available: [ "myapex" ], 880 min_sdk_version: "28", 881 } 882 883 cc_library { 884 name: "mylib2", 885 srcs: ["mylib.cpp"], 886 cflags: ["-include mylib.h"], 887 system_shared_libs: [], 888 stl: "none", 889 stubs: { 890 versions: ["28", "29", "30", "current"], 891 }, 892 min_sdk_version: "28", 893 } 894 895 cc_library { 896 name: "mylib3", 897 srcs: ["mylib.cpp"], 898 shared_libs: ["mylib4"], 899 system_shared_libs: [], 900 stl: "none", 901 stubs: { 902 versions: ["28", "29", "30", "current"], 903 }, 904 apex_available: [ "myapex" ], 905 min_sdk_version: "28", 906 } 907 908 cc_library { 909 name: "mylib4", 910 srcs: ["mylib.cpp"], 911 system_shared_libs: [], 912 stl: "none", 913 apex_available: [ "myapex" ], 914 min_sdk_version: "28", 915 } 916 `) 917 918 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule") 919 copyCmds := apexRule.Args["copy_commands"] 920 921 // Ensure that direct non-stubs dep is always included 922 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") 923 924 // Ensure that indirect stubs dep is not included 925 ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so") 926 927 // Ensure that direct stubs dep is included 928 ensureContains(t, copyCmds, "image.apex/lib64/mylib3.so") 929 930 mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex29").Rule("ld").Args["libFlags"] 931 932 // Ensure that mylib is linking with the latest version of stub for mylib2 933 ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_current/mylib2.so") 934 // ... and not linking to the non-stub (impl) variant of mylib2 935 ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so") 936 937 // Ensure that mylib is linking with the non-stub (impl) of mylib3 (because mylib3 is in the same apex) 938 ensureContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_apex29/mylib3.so") 939 // .. and not linking to the stubs variant of mylib3 940 ensureNotContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_29/mylib3.so") 941 942 // Ensure that stubs libs are built without -include flags 943 mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_29").Rule("cc").Args["cFlags"] 944 ensureNotContains(t, mylib2Cflags, "-include ") 945 946 // Ensure that genstub is invoked with --apex 947 ensureContains(t, "--apex", ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_29").Rule("genStubSrc").Args["flags"]) 948 949 ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{ 950 "lib64/mylib.so", 951 "lib64/mylib3.so", 952 "lib64/mylib4.so", 953 }) 954} 955 956func TestApex_PlatformUsesLatestStubFromApex(t *testing.T) { 957 t.Parallel() 958 // myapex (Z) 959 // mylib -----------------. 960 // | 961 // otherapex (29) | 962 // libstub's versions: 29 Z current 963 // | 964 // <platform> | 965 // libplatform ----------------' 966 ctx := testApex(t, ` 967 apex { 968 name: "myapex", 969 key: "myapex.key", 970 native_shared_libs: ["mylib"], 971 min_sdk_version: "Z", // non-final 972 } 973 974 cc_library { 975 name: "mylib", 976 srcs: ["mylib.cpp"], 977 shared_libs: ["libstub"], 978 apex_available: ["myapex"], 979 min_sdk_version: "Z", 980 } 981 982 apex_key { 983 name: "myapex.key", 984 public_key: "testkey.avbpubkey", 985 private_key: "testkey.pem", 986 } 987 988 apex { 989 name: "otherapex", 990 key: "myapex.key", 991 native_shared_libs: ["libstub"], 992 min_sdk_version: "29", 993 } 994 995 cc_library { 996 name: "libstub", 997 srcs: ["mylib.cpp"], 998 stubs: { 999 versions: ["29", "Z", "current"], 1000 }, 1001 apex_available: ["otherapex"], 1002 min_sdk_version: "29", 1003 } 1004 1005 // platform module depending on libstub from otherapex should use the latest stub("current") 1006 cc_library { 1007 name: "libplatform", 1008 srcs: ["mylib.cpp"], 1009 shared_libs: ["libstub"], 1010 } 1011 `, 1012 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1013 variables.Platform_sdk_codename = proptools.StringPtr("Z") 1014 variables.Platform_sdk_final = proptools.BoolPtr(false) 1015 variables.Platform_version_active_codenames = []string{"Z"} 1016 }), 1017 ) 1018 1019 // Ensure that mylib from myapex is built against the latest stub (current) 1020 mylibCflags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex10000").Rule("cc").Args["cFlags"] 1021 ensureContains(t, mylibCflags, "-D__LIBSTUB_API__=10000 ") 1022 mylibLdflags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"] 1023 ensureContains(t, mylibLdflags, "libstub/android_arm64_armv8-a_shared_current/libstub.so ") 1024 1025 // Ensure that libplatform is built against latest stub ("current") of mylib3 from the apex 1026 libplatformCflags := ctx.ModuleForTests("libplatform", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"] 1027 ensureContains(t, libplatformCflags, "-D__LIBSTUB_API__=10000 ") // "current" maps to 10000 1028 libplatformLdflags := ctx.ModuleForTests("libplatform", "android_arm64_armv8-a_shared").Rule("ld").Args["libFlags"] 1029 ensureContains(t, libplatformLdflags, "libstub/android_arm64_armv8-a_shared_current/libstub.so ") 1030} 1031 1032func TestApexWithExplicitStubsDependency(t *testing.T) { 1033 ctx := testApex(t, ` 1034 apex { 1035 name: "myapex2", 1036 key: "myapex2.key", 1037 native_shared_libs: ["mylib"], 1038 updatable: false, 1039 } 1040 1041 apex_key { 1042 name: "myapex2.key", 1043 public_key: "testkey.avbpubkey", 1044 private_key: "testkey.pem", 1045 } 1046 1047 cc_library { 1048 name: "mylib", 1049 srcs: ["mylib.cpp"], 1050 shared_libs: ["libfoo#10"], 1051 static_libs: ["libbaz"], 1052 system_shared_libs: [], 1053 stl: "none", 1054 apex_available: [ "myapex2" ], 1055 } 1056 1057 cc_library { 1058 name: "libfoo", 1059 srcs: ["mylib.cpp"], 1060 shared_libs: ["libbar"], 1061 system_shared_libs: [], 1062 stl: "none", 1063 stubs: { 1064 versions: ["10", "20", "30"], 1065 }, 1066 } 1067 1068 cc_library { 1069 name: "libbar", 1070 srcs: ["mylib.cpp"], 1071 system_shared_libs: [], 1072 stl: "none", 1073 } 1074 1075 cc_library_static { 1076 name: "libbaz", 1077 srcs: ["mylib.cpp"], 1078 system_shared_libs: [], 1079 stl: "none", 1080 apex_available: [ "myapex2" ], 1081 } 1082 1083 `) 1084 1085 apexRule := ctx.ModuleForTests("myapex2", "android_common_myapex2_image").Rule("apexRule") 1086 copyCmds := apexRule.Args["copy_commands"] 1087 1088 // Ensure that direct non-stubs dep is always included 1089 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") 1090 1091 // Ensure that indirect stubs dep is not included 1092 ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.so") 1093 1094 // Ensure that dependency of stubs is not included 1095 ensureNotContains(t, copyCmds, "image.apex/lib64/libbar.so") 1096 1097 mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"] 1098 1099 // Ensure that mylib is linking with version 10 of libfoo 1100 ensureContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_shared_10/libfoo.so") 1101 // ... and not linking to the non-stub (impl) variant of libfoo 1102 ensureNotContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_shared/libfoo.so") 1103 1104 libFooStubsLdFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared_10").Rule("ld").Args["libFlags"] 1105 1106 // Ensure that libfoo stubs is not linking to libbar (since it is a stubs) 1107 ensureNotContains(t, libFooStubsLdFlags, "libbar.so") 1108 1109 fullDepsInfo := strings.Split(ctx.ModuleForTests("myapex2", "android_common_myapex2_image").Output("depsinfo/fulllist.txt").Args["content"], "\\n") 1110 ensureListContains(t, fullDepsInfo, " libfoo(minSdkVersion:(no version)) (external) <- mylib") 1111 1112 flatDepsInfo := strings.Split(ctx.ModuleForTests("myapex2", "android_common_myapex2_image").Output("depsinfo/flatlist.txt").Args["content"], "\\n") 1113 ensureListContains(t, flatDepsInfo, "libfoo(minSdkVersion:(no version)) (external)") 1114} 1115 1116func TestApexWithRuntimeLibsDependency(t *testing.T) { 1117 /* 1118 myapex 1119 | 1120 v (runtime_libs) 1121 mylib ------+------> libfoo [provides stub] 1122 | 1123 `------> libbar 1124 */ 1125 ctx := testApex(t, ` 1126 apex { 1127 name: "myapex", 1128 key: "myapex.key", 1129 native_shared_libs: ["mylib"], 1130 updatable: false, 1131 } 1132 1133 apex_key { 1134 name: "myapex.key", 1135 public_key: "testkey.avbpubkey", 1136 private_key: "testkey.pem", 1137 } 1138 1139 cc_library { 1140 name: "mylib", 1141 srcs: ["mylib.cpp"], 1142 runtime_libs: ["libfoo", "libbar"], 1143 system_shared_libs: [], 1144 stl: "none", 1145 apex_available: [ "myapex" ], 1146 } 1147 1148 cc_library { 1149 name: "libfoo", 1150 srcs: ["mylib.cpp"], 1151 system_shared_libs: [], 1152 stl: "none", 1153 stubs: { 1154 versions: ["10", "20", "30"], 1155 }, 1156 } 1157 1158 cc_library { 1159 name: "libbar", 1160 srcs: ["mylib.cpp"], 1161 system_shared_libs: [], 1162 stl: "none", 1163 apex_available: [ "myapex" ], 1164 } 1165 1166 `) 1167 1168 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule") 1169 copyCmds := apexRule.Args["copy_commands"] 1170 1171 // Ensure that direct non-stubs dep is always included 1172 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") 1173 1174 // Ensure that indirect stubs dep is not included 1175 ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.so") 1176 1177 // Ensure that runtime_libs dep in included 1178 ensureContains(t, copyCmds, "image.apex/lib64/libbar.so") 1179 1180 apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule") 1181 ensureListEmpty(t, names(apexManifestRule.Args["provideNativeLibs"])) 1182 ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libfoo.so") 1183 1184} 1185 1186var prepareForTestOfRuntimeApexWithHwasan = android.GroupFixturePreparers( 1187 cc.PrepareForTestWithCcBuildComponents, 1188 PrepareForTestWithApexBuildComponents, 1189 android.FixtureAddTextFile("bionic/apex/Android.bp", ` 1190 apex { 1191 name: "com.android.runtime", 1192 key: "com.android.runtime.key", 1193 native_shared_libs: ["libc"], 1194 updatable: false, 1195 } 1196 1197 apex_key { 1198 name: "com.android.runtime.key", 1199 public_key: "testkey.avbpubkey", 1200 private_key: "testkey.pem", 1201 } 1202 `), 1203 android.FixtureAddFile("system/sepolicy/apex/com.android.runtime-file_contexts", nil), 1204) 1205 1206func TestRuntimeApexShouldInstallHwasanIfLibcDependsOnIt(t *testing.T) { 1207 result := android.GroupFixturePreparers(prepareForTestOfRuntimeApexWithHwasan).RunTestWithBp(t, ` 1208 cc_library { 1209 name: "libc", 1210 no_libcrt: true, 1211 nocrt: true, 1212 stl: "none", 1213 system_shared_libs: [], 1214 stubs: { versions: ["1"] }, 1215 apex_available: ["com.android.runtime"], 1216 1217 sanitize: { 1218 hwaddress: true, 1219 } 1220 } 1221 1222 cc_prebuilt_library_shared { 1223 name: "libclang_rt.hwasan-aarch64-android", 1224 no_libcrt: true, 1225 nocrt: true, 1226 stl: "none", 1227 system_shared_libs: [], 1228 srcs: [""], 1229 stubs: { versions: ["1"] }, 1230 1231 sanitize: { 1232 never: true, 1233 }, 1234 } `) 1235 ctx := result.TestContext 1236 1237 ensureExactContents(t, ctx, "com.android.runtime", "android_common_hwasan_com.android.runtime_image", []string{ 1238 "lib64/bionic/libc.so", 1239 "lib64/bionic/libclang_rt.hwasan-aarch64-android.so", 1240 }) 1241 1242 hwasan := ctx.ModuleForTests("libclang_rt.hwasan-aarch64-android", "android_arm64_armv8-a_shared") 1243 1244 installed := hwasan.Description("install libclang_rt.hwasan") 1245 ensureContains(t, installed.Output.String(), "/system/lib64/bootstrap/libclang_rt.hwasan-aarch64-android.so") 1246 1247 symlink := hwasan.Description("install symlink libclang_rt.hwasan") 1248 ensureEquals(t, symlink.Args["fromPath"], "/apex/com.android.runtime/lib64/bionic/libclang_rt.hwasan-aarch64-android.so") 1249 ensureContains(t, symlink.Output.String(), "/system/lib64/libclang_rt.hwasan-aarch64-android.so") 1250} 1251 1252func TestRuntimeApexShouldInstallHwasanIfHwaddressSanitized(t *testing.T) { 1253 result := android.GroupFixturePreparers( 1254 prepareForTestOfRuntimeApexWithHwasan, 1255 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1256 variables.SanitizeDevice = []string{"hwaddress"} 1257 }), 1258 ).RunTestWithBp(t, ` 1259 cc_library { 1260 name: "libc", 1261 no_libcrt: true, 1262 nocrt: true, 1263 stl: "none", 1264 system_shared_libs: [], 1265 stubs: { versions: ["1"] }, 1266 apex_available: ["com.android.runtime"], 1267 } 1268 1269 cc_prebuilt_library_shared { 1270 name: "libclang_rt.hwasan-aarch64-android", 1271 no_libcrt: true, 1272 nocrt: true, 1273 stl: "none", 1274 system_shared_libs: [], 1275 srcs: [""], 1276 stubs: { versions: ["1"] }, 1277 1278 sanitize: { 1279 never: true, 1280 }, 1281 } 1282 `) 1283 ctx := result.TestContext 1284 1285 ensureExactContents(t, ctx, "com.android.runtime", "android_common_hwasan_com.android.runtime_image", []string{ 1286 "lib64/bionic/libc.so", 1287 "lib64/bionic/libclang_rt.hwasan-aarch64-android.so", 1288 }) 1289 1290 hwasan := ctx.ModuleForTests("libclang_rt.hwasan-aarch64-android", "android_arm64_armv8-a_shared") 1291 1292 installed := hwasan.Description("install libclang_rt.hwasan") 1293 ensureContains(t, installed.Output.String(), "/system/lib64/bootstrap/libclang_rt.hwasan-aarch64-android.so") 1294 1295 symlink := hwasan.Description("install symlink libclang_rt.hwasan") 1296 ensureEquals(t, symlink.Args["fromPath"], "/apex/com.android.runtime/lib64/bionic/libclang_rt.hwasan-aarch64-android.so") 1297 ensureContains(t, symlink.Output.String(), "/system/lib64/libclang_rt.hwasan-aarch64-android.so") 1298} 1299 1300func TestApexDependsOnLLNDKTransitively(t *testing.T) { 1301 testcases := []struct { 1302 name string 1303 minSdkVersion string 1304 apexVariant string 1305 shouldLink string 1306 shouldNotLink []string 1307 }{ 1308 { 1309 name: "unspecified version links to the latest", 1310 minSdkVersion: "", 1311 apexVariant: "apex10000", 1312 shouldLink: "current", 1313 shouldNotLink: []string{"29", "30"}, 1314 }, 1315 { 1316 name: "always use the latest", 1317 minSdkVersion: "min_sdk_version: \"29\",", 1318 apexVariant: "apex29", 1319 shouldLink: "current", 1320 shouldNotLink: []string{"29", "30"}, 1321 }, 1322 } 1323 for _, tc := range testcases { 1324 t.Run(tc.name, func(t *testing.T) { 1325 ctx := testApex(t, ` 1326 apex { 1327 name: "myapex", 1328 key: "myapex.key", 1329 native_shared_libs: ["mylib"], 1330 updatable: false, 1331 `+tc.minSdkVersion+` 1332 } 1333 1334 apex_key { 1335 name: "myapex.key", 1336 public_key: "testkey.avbpubkey", 1337 private_key: "testkey.pem", 1338 } 1339 1340 cc_library { 1341 name: "mylib", 1342 srcs: ["mylib.cpp"], 1343 vendor_available: true, 1344 shared_libs: ["libbar"], 1345 system_shared_libs: [], 1346 stl: "none", 1347 apex_available: [ "myapex" ], 1348 min_sdk_version: "29", 1349 } 1350 1351 cc_library { 1352 name: "libbar", 1353 srcs: ["mylib.cpp"], 1354 system_shared_libs: [], 1355 stl: "none", 1356 stubs: { versions: ["29","30"] }, 1357 llndk: { 1358 symbol_file: "libbar.map.txt", 1359 } 1360 } 1361 `, 1362 withUnbundledBuild, 1363 ) 1364 1365 // Ensure that LLNDK dep is not included 1366 ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{ 1367 "lib64/mylib.so", 1368 }) 1369 1370 // Ensure that LLNDK dep is required 1371 apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule") 1372 ensureListEmpty(t, names(apexManifestRule.Args["provideNativeLibs"])) 1373 ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libbar.so") 1374 1375 mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_"+tc.apexVariant).Rule("ld").Args["libFlags"] 1376 ensureContains(t, mylibLdFlags, "libbar/android_arm64_armv8-a_shared_"+tc.shouldLink+"/libbar.so") 1377 for _, ver := range tc.shouldNotLink { 1378 ensureNotContains(t, mylibLdFlags, "libbar/android_arm64_armv8-a_shared_"+ver+"/libbar.so") 1379 } 1380 1381 mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_"+tc.apexVariant).Rule("cc").Args["cFlags"] 1382 ver := tc.shouldLink 1383 if tc.shouldLink == "current" { 1384 ver = strconv.Itoa(android.FutureApiLevelInt) 1385 } 1386 ensureContains(t, mylibCFlags, "__LIBBAR_API__="+ver) 1387 }) 1388 } 1389} 1390 1391func TestApexWithSystemLibsStubs(t *testing.T) { 1392 ctx := testApex(t, ` 1393 apex { 1394 name: "myapex", 1395 key: "myapex.key", 1396 native_shared_libs: ["mylib", "mylib_shared", "libdl", "libm"], 1397 updatable: false, 1398 } 1399 1400 apex_key { 1401 name: "myapex.key", 1402 public_key: "testkey.avbpubkey", 1403 private_key: "testkey.pem", 1404 } 1405 1406 cc_library { 1407 name: "mylib", 1408 srcs: ["mylib.cpp"], 1409 system_shared_libs: ["libc", "libm"], 1410 shared_libs: ["libdl#27"], 1411 stl: "none", 1412 apex_available: [ "myapex" ], 1413 } 1414 1415 cc_library_shared { 1416 name: "mylib_shared", 1417 srcs: ["mylib.cpp"], 1418 shared_libs: ["libdl#27"], 1419 stl: "none", 1420 apex_available: [ "myapex" ], 1421 } 1422 1423 cc_library { 1424 name: "libBootstrap", 1425 srcs: ["mylib.cpp"], 1426 stl: "none", 1427 bootstrap: true, 1428 } 1429 `) 1430 1431 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule") 1432 copyCmds := apexRule.Args["copy_commands"] 1433 1434 // Ensure that mylib, libm, libdl are included. 1435 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") 1436 ensureContains(t, copyCmds, "image.apex/lib64/bionic/libm.so") 1437 ensureContains(t, copyCmds, "image.apex/lib64/bionic/libdl.so") 1438 1439 // Ensure that libc is not included (since it has stubs and not listed in native_shared_libs) 1440 ensureNotContains(t, copyCmds, "image.apex/lib64/bionic/libc.so") 1441 1442 mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"] 1443 mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex10000").Rule("cc").Args["cFlags"] 1444 mylibSharedCFlags := ctx.ModuleForTests("mylib_shared", "android_arm64_armv8-a_shared_apex10000").Rule("cc").Args["cFlags"] 1445 1446 // For dependency to libc 1447 // Ensure that mylib is linking with the latest version of stubs 1448 ensureContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_shared_current/libc.so") 1449 // ... and not linking to the non-stub (impl) variant 1450 ensureNotContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_shared/libc.so") 1451 // ... Cflags from stub is correctly exported to mylib 1452 ensureContains(t, mylibCFlags, "__LIBC_API__=10000") 1453 ensureContains(t, mylibSharedCFlags, "__LIBC_API__=10000") 1454 1455 // For dependency to libm 1456 // Ensure that mylib is linking with the non-stub (impl) variant 1457 ensureContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_shared_apex10000/libm.so") 1458 // ... and not linking to the stub variant 1459 ensureNotContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_shared_29/libm.so") 1460 // ... and is not compiling with the stub 1461 ensureNotContains(t, mylibCFlags, "__LIBM_API__=29") 1462 ensureNotContains(t, mylibSharedCFlags, "__LIBM_API__=29") 1463 1464 // For dependency to libdl 1465 // Ensure that mylib is linking with the specified version of stubs 1466 ensureContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_27/libdl.so") 1467 // ... and not linking to the other versions of stubs 1468 ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_28/libdl.so") 1469 ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_29/libdl.so") 1470 // ... and not linking to the non-stub (impl) variant 1471 ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_apex10000/libdl.so") 1472 // ... Cflags from stub is correctly exported to mylib 1473 ensureContains(t, mylibCFlags, "__LIBDL_API__=27") 1474 ensureContains(t, mylibSharedCFlags, "__LIBDL_API__=27") 1475 1476 // Ensure that libBootstrap is depending on the platform variant of bionic libs 1477 libFlags := ctx.ModuleForTests("libBootstrap", "android_arm64_armv8-a_shared").Rule("ld").Args["libFlags"] 1478 ensureContains(t, libFlags, "libc/android_arm64_armv8-a_shared/libc.so") 1479 ensureContains(t, libFlags, "libm/android_arm64_armv8-a_shared/libm.so") 1480 ensureContains(t, libFlags, "libdl/android_arm64_armv8-a_shared/libdl.so") 1481} 1482 1483func TestApexMinSdkVersion_NativeModulesShouldBeBuiltAgainstStubs(t *testing.T) { 1484 // there are three links between liba --> libz. 1485 // 1) myapex -> libx -> liba -> libz : this should be #30 link 1486 // 2) otherapex -> liby -> liba -> libz : this should be #30 link 1487 // 3) (platform) -> liba -> libz : this should be non-stub link 1488 ctx := testApex(t, ` 1489 apex { 1490 name: "myapex", 1491 key: "myapex.key", 1492 native_shared_libs: ["libx"], 1493 min_sdk_version: "29", 1494 } 1495 1496 apex { 1497 name: "otherapex", 1498 key: "myapex.key", 1499 native_shared_libs: ["liby"], 1500 min_sdk_version: "30", 1501 } 1502 1503 apex_key { 1504 name: "myapex.key", 1505 public_key: "testkey.avbpubkey", 1506 private_key: "testkey.pem", 1507 } 1508 1509 cc_library { 1510 name: "libx", 1511 shared_libs: ["liba"], 1512 system_shared_libs: [], 1513 stl: "none", 1514 apex_available: [ "myapex" ], 1515 min_sdk_version: "29", 1516 } 1517 1518 cc_library { 1519 name: "liby", 1520 shared_libs: ["liba"], 1521 system_shared_libs: [], 1522 stl: "none", 1523 apex_available: [ "otherapex" ], 1524 min_sdk_version: "29", 1525 } 1526 1527 cc_library { 1528 name: "liba", 1529 shared_libs: ["libz"], 1530 system_shared_libs: [], 1531 stl: "none", 1532 apex_available: [ 1533 "//apex_available:anyapex", 1534 "//apex_available:platform", 1535 ], 1536 min_sdk_version: "29", 1537 } 1538 1539 cc_library { 1540 name: "libz", 1541 system_shared_libs: [], 1542 stl: "none", 1543 stubs: { 1544 versions: ["28", "30"], 1545 }, 1546 } 1547 `) 1548 1549 expectLink := func(from, from_variant, to, to_variant string) { 1550 ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"] 1551 ensureContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so") 1552 } 1553 expectNoLink := func(from, from_variant, to, to_variant string) { 1554 ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"] 1555 ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so") 1556 } 1557 // platform liba is linked to non-stub version 1558 expectLink("liba", "shared", "libz", "shared") 1559 // liba in myapex is linked to current 1560 expectLink("liba", "shared_apex29", "libz", "shared_current") 1561 expectNoLink("liba", "shared_apex29", "libz", "shared_30") 1562 expectNoLink("liba", "shared_apex29", "libz", "shared_28") 1563 expectNoLink("liba", "shared_apex29", "libz", "shared") 1564 // liba in otherapex is linked to current 1565 expectLink("liba", "shared_apex30", "libz", "shared_current") 1566 expectNoLink("liba", "shared_apex30", "libz", "shared_30") 1567 expectNoLink("liba", "shared_apex30", "libz", "shared_28") 1568 expectNoLink("liba", "shared_apex30", "libz", "shared") 1569} 1570 1571func TestApexMinSdkVersion_SupportsCodeNames(t *testing.T) { 1572 ctx := testApex(t, ` 1573 apex { 1574 name: "myapex", 1575 key: "myapex.key", 1576 native_shared_libs: ["libx"], 1577 min_sdk_version: "R", 1578 } 1579 1580 apex_key { 1581 name: "myapex.key", 1582 public_key: "testkey.avbpubkey", 1583 private_key: "testkey.pem", 1584 } 1585 1586 cc_library { 1587 name: "libx", 1588 shared_libs: ["libz"], 1589 system_shared_libs: [], 1590 stl: "none", 1591 apex_available: [ "myapex" ], 1592 min_sdk_version: "R", 1593 } 1594 1595 cc_library { 1596 name: "libz", 1597 system_shared_libs: [], 1598 stl: "none", 1599 stubs: { 1600 versions: ["29", "R"], 1601 }, 1602 } 1603 `, 1604 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1605 variables.Platform_version_active_codenames = []string{"R"} 1606 }), 1607 ) 1608 1609 expectLink := func(from, from_variant, to, to_variant string) { 1610 ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"] 1611 ensureContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so") 1612 } 1613 expectNoLink := func(from, from_variant, to, to_variant string) { 1614 ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"] 1615 ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so") 1616 } 1617 expectLink("libx", "shared_apex10000", "libz", "shared_current") 1618 expectNoLink("libx", "shared_apex10000", "libz", "shared_R") 1619 expectNoLink("libx", "shared_apex10000", "libz", "shared_29") 1620 expectNoLink("libx", "shared_apex10000", "libz", "shared") 1621} 1622 1623func TestApexMinSdkVersion_DefaultsToLatest(t *testing.T) { 1624 ctx := testApex(t, ` 1625 apex { 1626 name: "myapex", 1627 key: "myapex.key", 1628 native_shared_libs: ["libx"], 1629 updatable: false, 1630 } 1631 1632 apex_key { 1633 name: "myapex.key", 1634 public_key: "testkey.avbpubkey", 1635 private_key: "testkey.pem", 1636 } 1637 1638 cc_library { 1639 name: "libx", 1640 shared_libs: ["libz"], 1641 system_shared_libs: [], 1642 stl: "none", 1643 apex_available: [ "myapex" ], 1644 } 1645 1646 cc_library { 1647 name: "libz", 1648 system_shared_libs: [], 1649 stl: "none", 1650 stubs: { 1651 versions: ["1", "2"], 1652 }, 1653 } 1654 `) 1655 1656 expectLink := func(from, from_variant, to, to_variant string) { 1657 ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"] 1658 ensureContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so") 1659 } 1660 expectNoLink := func(from, from_variant, to, to_variant string) { 1661 ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"] 1662 ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so") 1663 } 1664 expectLink("libx", "shared_apex10000", "libz", "shared_current") 1665 expectNoLink("libx", "shared_apex10000", "libz", "shared_1") 1666 expectNoLink("libx", "shared_apex10000", "libz", "shared_2") 1667 expectNoLink("libx", "shared_apex10000", "libz", "shared") 1668} 1669 1670func TestPlatformUsesLatestStubsFromApexes(t *testing.T) { 1671 ctx := testApex(t, ` 1672 apex { 1673 name: "myapex", 1674 key: "myapex.key", 1675 native_shared_libs: ["libx"], 1676 updatable: false, 1677 } 1678 1679 apex_key { 1680 name: "myapex.key", 1681 public_key: "testkey.avbpubkey", 1682 private_key: "testkey.pem", 1683 } 1684 1685 cc_library { 1686 name: "libx", 1687 system_shared_libs: [], 1688 stl: "none", 1689 apex_available: [ "myapex" ], 1690 stubs: { 1691 versions: ["1", "2"], 1692 }, 1693 } 1694 1695 cc_library { 1696 name: "libz", 1697 shared_libs: ["libx"], 1698 system_shared_libs: [], 1699 stl: "none", 1700 } 1701 `) 1702 1703 expectLink := func(from, from_variant, to, to_variant string) { 1704 t.Helper() 1705 ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"] 1706 ensureContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so") 1707 } 1708 expectNoLink := func(from, from_variant, to, to_variant string) { 1709 t.Helper() 1710 ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"] 1711 ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so") 1712 } 1713 expectLink("libz", "shared", "libx", "shared_current") 1714 expectNoLink("libz", "shared", "libx", "shared_2") 1715 expectNoLink("libz", "shared", "libz", "shared_1") 1716 expectNoLink("libz", "shared", "libz", "shared") 1717} 1718 1719var prepareForTestWithSantitizeHwaddress = android.FixtureModifyProductVariables( 1720 func(variables android.FixtureProductVariables) { 1721 variables.SanitizeDevice = []string{"hwaddress"} 1722 }, 1723) 1724 1725func TestQApexesUseLatestStubsInBundledBuildsAndHWASAN(t *testing.T) { 1726 ctx := testApex(t, ` 1727 apex { 1728 name: "myapex", 1729 key: "myapex.key", 1730 native_shared_libs: ["libx"], 1731 min_sdk_version: "29", 1732 } 1733 1734 apex_key { 1735 name: "myapex.key", 1736 public_key: "testkey.avbpubkey", 1737 private_key: "testkey.pem", 1738 } 1739 1740 cc_library { 1741 name: "libx", 1742 shared_libs: ["libbar"], 1743 apex_available: [ "myapex" ], 1744 min_sdk_version: "29", 1745 } 1746 1747 cc_library { 1748 name: "libbar", 1749 stubs: { 1750 versions: ["29", "30"], 1751 }, 1752 } 1753 `, 1754 prepareForTestWithSantitizeHwaddress, 1755 ) 1756 expectLink := func(from, from_variant, to, to_variant string) { 1757 ld := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld") 1758 libFlags := ld.Args["libFlags"] 1759 ensureContains(t, libFlags, "android_arm64_armv8-a_"+to_variant+"/"+to+".so") 1760 } 1761 expectLink("libx", "shared_hwasan_apex29", "libbar", "shared_current") 1762} 1763 1764func TestQTargetApexUsesStaticUnwinder(t *testing.T) { 1765 ctx := testApex(t, ` 1766 apex { 1767 name: "myapex", 1768 key: "myapex.key", 1769 native_shared_libs: ["libx"], 1770 min_sdk_version: "29", 1771 } 1772 1773 apex_key { 1774 name: "myapex.key", 1775 public_key: "testkey.avbpubkey", 1776 private_key: "testkey.pem", 1777 } 1778 1779 cc_library { 1780 name: "libx", 1781 apex_available: [ "myapex" ], 1782 min_sdk_version: "29", 1783 } 1784 `) 1785 1786 // ensure apex variant of c++ is linked with static unwinder 1787 cm := ctx.ModuleForTests("libc++", "android_arm64_armv8-a_shared_apex29").Module().(*cc.Module) 1788 ensureListContains(t, cm.Properties.AndroidMkStaticLibs, "libunwind") 1789 // note that platform variant is not. 1790 cm = ctx.ModuleForTests("libc++", "android_arm64_armv8-a_shared").Module().(*cc.Module) 1791 ensureListNotContains(t, cm.Properties.AndroidMkStaticLibs, "libunwind") 1792} 1793 1794func TestApexMinSdkVersion_ErrorIfIncompatibleVersion(t *testing.T) { 1795 testApexError(t, `module "mylib".*: should support min_sdk_version\(29\)`, ` 1796 apex { 1797 name: "myapex", 1798 key: "myapex.key", 1799 native_shared_libs: ["mylib"], 1800 min_sdk_version: "29", 1801 } 1802 1803 apex_key { 1804 name: "myapex.key", 1805 public_key: "testkey.avbpubkey", 1806 private_key: "testkey.pem", 1807 } 1808 1809 cc_library { 1810 name: "mylib", 1811 srcs: ["mylib.cpp"], 1812 system_shared_libs: [], 1813 stl: "none", 1814 apex_available: [ 1815 "myapex", 1816 ], 1817 min_sdk_version: "30", 1818 } 1819 `) 1820 1821 testApexError(t, `module "libfoo.ffi".*: should support min_sdk_version\(29\)`, ` 1822 apex { 1823 name: "myapex", 1824 key: "myapex.key", 1825 native_shared_libs: ["libfoo.ffi"], 1826 min_sdk_version: "29", 1827 } 1828 1829 apex_key { 1830 name: "myapex.key", 1831 public_key: "testkey.avbpubkey", 1832 private_key: "testkey.pem", 1833 } 1834 1835 rust_ffi_shared { 1836 name: "libfoo.ffi", 1837 srcs: ["foo.rs"], 1838 crate_name: "foo", 1839 apex_available: [ 1840 "myapex", 1841 ], 1842 min_sdk_version: "30", 1843 } 1844 `) 1845 1846 testApexError(t, `module "libfoo".*: should support min_sdk_version\(29\)`, ` 1847 apex { 1848 name: "myapex", 1849 key: "myapex.key", 1850 java_libs: ["libfoo"], 1851 min_sdk_version: "29", 1852 } 1853 1854 apex_key { 1855 name: "myapex.key", 1856 public_key: "testkey.avbpubkey", 1857 private_key: "testkey.pem", 1858 } 1859 1860 java_import { 1861 name: "libfoo", 1862 jars: ["libfoo.jar"], 1863 apex_available: [ 1864 "myapex", 1865 ], 1866 min_sdk_version: "30", 1867 } 1868 `) 1869} 1870 1871func TestApexMinSdkVersion_Okay(t *testing.T) { 1872 testApex(t, ` 1873 apex { 1874 name: "myapex", 1875 key: "myapex.key", 1876 native_shared_libs: ["libfoo"], 1877 java_libs: ["libbar"], 1878 min_sdk_version: "29", 1879 } 1880 1881 apex_key { 1882 name: "myapex.key", 1883 public_key: "testkey.avbpubkey", 1884 private_key: "testkey.pem", 1885 } 1886 1887 cc_library { 1888 name: "libfoo", 1889 srcs: ["mylib.cpp"], 1890 shared_libs: ["libfoo_dep"], 1891 apex_available: ["myapex"], 1892 min_sdk_version: "29", 1893 } 1894 1895 cc_library { 1896 name: "libfoo_dep", 1897 srcs: ["mylib.cpp"], 1898 apex_available: ["myapex"], 1899 min_sdk_version: "29", 1900 } 1901 1902 java_library { 1903 name: "libbar", 1904 sdk_version: "current", 1905 srcs: ["a.java"], 1906 static_libs: [ 1907 "libbar_dep", 1908 "libbar_import_dep", 1909 ], 1910 apex_available: ["myapex"], 1911 min_sdk_version: "29", 1912 } 1913 1914 java_library { 1915 name: "libbar_dep", 1916 sdk_version: "current", 1917 srcs: ["a.java"], 1918 apex_available: ["myapex"], 1919 min_sdk_version: "29", 1920 } 1921 1922 java_import { 1923 name: "libbar_import_dep", 1924 jars: ["libbar.jar"], 1925 apex_available: ["myapex"], 1926 min_sdk_version: "29", 1927 } 1928 `) 1929} 1930 1931func TestJavaStableSdkVersion(t *testing.T) { 1932 testCases := []struct { 1933 name string 1934 expectedError string 1935 bp string 1936 }{ 1937 { 1938 name: "Non-updatable apex with non-stable dep", 1939 bp: ` 1940 apex { 1941 name: "myapex", 1942 java_libs: ["myjar"], 1943 key: "myapex.key", 1944 updatable: false, 1945 } 1946 apex_key { 1947 name: "myapex.key", 1948 public_key: "testkey.avbpubkey", 1949 private_key: "testkey.pem", 1950 } 1951 java_library { 1952 name: "myjar", 1953 srcs: ["foo/bar/MyClass.java"], 1954 sdk_version: "test_current", 1955 apex_available: ["myapex"], 1956 } 1957 `, 1958 }, 1959 { 1960 name: "Updatable apex with stable dep", 1961 bp: ` 1962 apex { 1963 name: "myapex", 1964 java_libs: ["myjar"], 1965 key: "myapex.key", 1966 updatable: true, 1967 min_sdk_version: "29", 1968 } 1969 apex_key { 1970 name: "myapex.key", 1971 public_key: "testkey.avbpubkey", 1972 private_key: "testkey.pem", 1973 } 1974 java_library { 1975 name: "myjar", 1976 srcs: ["foo/bar/MyClass.java"], 1977 sdk_version: "current", 1978 apex_available: ["myapex"], 1979 min_sdk_version: "29", 1980 } 1981 `, 1982 }, 1983 { 1984 name: "Updatable apex with non-stable dep", 1985 expectedError: "cannot depend on \"myjar\"", 1986 bp: ` 1987 apex { 1988 name: "myapex", 1989 java_libs: ["myjar"], 1990 key: "myapex.key", 1991 updatable: true, 1992 } 1993 apex_key { 1994 name: "myapex.key", 1995 public_key: "testkey.avbpubkey", 1996 private_key: "testkey.pem", 1997 } 1998 java_library { 1999 name: "myjar", 2000 srcs: ["foo/bar/MyClass.java"], 2001 sdk_version: "test_current", 2002 apex_available: ["myapex"], 2003 } 2004 `, 2005 }, 2006 { 2007 name: "Updatable apex with non-stable transitive dep", 2008 // This is not actually detecting that the transitive dependency is unstable, rather it is 2009 // detecting that the transitive dependency is building against a wider API surface than the 2010 // module that depends on it is using. 2011 expectedError: "compiles against Android API, but dependency \"transitive-jar\" is compiling against private API.", 2012 bp: ` 2013 apex { 2014 name: "myapex", 2015 java_libs: ["myjar"], 2016 key: "myapex.key", 2017 updatable: true, 2018 } 2019 apex_key { 2020 name: "myapex.key", 2021 public_key: "testkey.avbpubkey", 2022 private_key: "testkey.pem", 2023 } 2024 java_library { 2025 name: "myjar", 2026 srcs: ["foo/bar/MyClass.java"], 2027 sdk_version: "current", 2028 apex_available: ["myapex"], 2029 static_libs: ["transitive-jar"], 2030 } 2031 java_library { 2032 name: "transitive-jar", 2033 srcs: ["foo/bar/MyClass.java"], 2034 sdk_version: "core_platform", 2035 apex_available: ["myapex"], 2036 } 2037 `, 2038 }, 2039 } 2040 2041 for _, test := range testCases { 2042 t.Run(test.name, func(t *testing.T) { 2043 if test.expectedError == "" { 2044 testApex(t, test.bp) 2045 } else { 2046 testApexError(t, test.expectedError, test.bp) 2047 } 2048 }) 2049 } 2050} 2051 2052func TestApexMinSdkVersion_ErrorIfDepIsNewer(t *testing.T) { 2053 testApexError(t, `module "mylib2".*: should support min_sdk_version\(29\) for "myapex"`, ` 2054 apex { 2055 name: "myapex", 2056 key: "myapex.key", 2057 native_shared_libs: ["mylib"], 2058 min_sdk_version: "29", 2059 } 2060 2061 apex_key { 2062 name: "myapex.key", 2063 public_key: "testkey.avbpubkey", 2064 private_key: "testkey.pem", 2065 } 2066 2067 cc_library { 2068 name: "mylib", 2069 srcs: ["mylib.cpp"], 2070 shared_libs: ["mylib2"], 2071 system_shared_libs: [], 2072 stl: "none", 2073 apex_available: [ 2074 "myapex", 2075 ], 2076 min_sdk_version: "29", 2077 } 2078 2079 // indirect part of the apex 2080 cc_library { 2081 name: "mylib2", 2082 srcs: ["mylib.cpp"], 2083 system_shared_libs: [], 2084 stl: "none", 2085 apex_available: [ 2086 "myapex", 2087 ], 2088 min_sdk_version: "30", 2089 } 2090 `) 2091} 2092 2093func TestApexMinSdkVersion_ErrorIfDepIsNewer_Java(t *testing.T) { 2094 testApexError(t, `module "bar".*: should support min_sdk_version\(29\) for "myapex"`, ` 2095 apex { 2096 name: "myapex", 2097 key: "myapex.key", 2098 apps: ["AppFoo"], 2099 min_sdk_version: "29", 2100 } 2101 2102 apex_key { 2103 name: "myapex.key", 2104 public_key: "testkey.avbpubkey", 2105 private_key: "testkey.pem", 2106 } 2107 2108 android_app { 2109 name: "AppFoo", 2110 srcs: ["foo/bar/MyClass.java"], 2111 sdk_version: "current", 2112 min_sdk_version: "29", 2113 system_modules: "none", 2114 stl: "none", 2115 static_libs: ["bar"], 2116 apex_available: [ "myapex" ], 2117 } 2118 2119 java_library { 2120 name: "bar", 2121 sdk_version: "current", 2122 srcs: ["a.java"], 2123 apex_available: [ "myapex" ], 2124 } 2125 `) 2126} 2127 2128func TestApexMinSdkVersion_OkayEvenWhenDepIsNewer_IfItSatisfiesApexMinSdkVersion(t *testing.T) { 2129 ctx := testApex(t, ` 2130 apex { 2131 name: "myapex", 2132 key: "myapex.key", 2133 native_shared_libs: ["mylib"], 2134 min_sdk_version: "29", 2135 } 2136 2137 apex_key { 2138 name: "myapex.key", 2139 public_key: "testkey.avbpubkey", 2140 private_key: "testkey.pem", 2141 } 2142 2143 // mylib in myapex will link to mylib2#current 2144 // mylib in otherapex will link to mylib2(non-stub) in otherapex as well 2145 cc_library { 2146 name: "mylib", 2147 srcs: ["mylib.cpp"], 2148 shared_libs: ["mylib2"], 2149 system_shared_libs: [], 2150 stl: "none", 2151 apex_available: ["myapex", "otherapex"], 2152 min_sdk_version: "29", 2153 } 2154 2155 cc_library { 2156 name: "mylib2", 2157 srcs: ["mylib.cpp"], 2158 system_shared_libs: [], 2159 stl: "none", 2160 apex_available: ["otherapex"], 2161 stubs: { versions: ["29", "30"] }, 2162 min_sdk_version: "30", 2163 } 2164 2165 apex { 2166 name: "otherapex", 2167 key: "myapex.key", 2168 native_shared_libs: ["mylib", "mylib2"], 2169 min_sdk_version: "30", 2170 } 2171 `) 2172 expectLink := func(from, from_variant, to, to_variant string) { 2173 ld := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld") 2174 libFlags := ld.Args["libFlags"] 2175 ensureContains(t, libFlags, "android_arm64_armv8-a_"+to_variant+"/"+to+".so") 2176 } 2177 expectLink("mylib", "shared_apex29", "mylib2", "shared_current") 2178 expectLink("mylib", "shared_apex30", "mylib2", "shared_apex30") 2179} 2180 2181func TestApexMinSdkVersion_WorksWithSdkCodename(t *testing.T) { 2182 withSAsActiveCodeNames := android.FixtureModifyProductVariables( 2183 func(variables android.FixtureProductVariables) { 2184 variables.Platform_sdk_codename = proptools.StringPtr("S") 2185 variables.Platform_version_active_codenames = []string{"S"} 2186 }, 2187 ) 2188 testApexError(t, `libbar.*: should support min_sdk_version\(S\)`, ` 2189 apex { 2190 name: "myapex", 2191 key: "myapex.key", 2192 native_shared_libs: ["libfoo"], 2193 min_sdk_version: "S", 2194 } 2195 apex_key { 2196 name: "myapex.key", 2197 public_key: "testkey.avbpubkey", 2198 private_key: "testkey.pem", 2199 } 2200 cc_library { 2201 name: "libfoo", 2202 shared_libs: ["libbar"], 2203 apex_available: ["myapex"], 2204 min_sdk_version: "29", 2205 } 2206 cc_library { 2207 name: "libbar", 2208 apex_available: ["myapex"], 2209 } 2210 `, withSAsActiveCodeNames) 2211} 2212 2213func TestApexMinSdkVersion_WorksWithActiveCodenames(t *testing.T) { 2214 withSAsActiveCodeNames := android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 2215 variables.Platform_sdk_codename = proptools.StringPtr("S") 2216 variables.Platform_version_active_codenames = []string{"S", "T"} 2217 }) 2218 ctx := testApex(t, ` 2219 apex { 2220 name: "myapex", 2221 key: "myapex.key", 2222 native_shared_libs: ["libfoo"], 2223 min_sdk_version: "S", 2224 } 2225 apex_key { 2226 name: "myapex.key", 2227 public_key: "testkey.avbpubkey", 2228 private_key: "testkey.pem", 2229 } 2230 cc_library { 2231 name: "libfoo", 2232 shared_libs: ["libbar"], 2233 apex_available: ["myapex"], 2234 min_sdk_version: "S", 2235 } 2236 cc_library { 2237 name: "libbar", 2238 stubs: { 2239 symbol_file: "libbar.map.txt", 2240 versions: ["30", "S", "T"], 2241 }, 2242 } 2243 `, withSAsActiveCodeNames) 2244 2245 // ensure libfoo is linked with current version of libbar stub 2246 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared_apex10000") 2247 libFlags := libfoo.Rule("ld").Args["libFlags"] 2248 ensureContains(t, libFlags, "android_arm64_armv8-a_shared_current/libbar.so") 2249} 2250 2251func TestFilesInSubDir(t *testing.T) { 2252 ctx := testApex(t, ` 2253 apex { 2254 name: "myapex", 2255 key: "myapex.key", 2256 native_shared_libs: ["mylib"], 2257 binaries: ["mybin"], 2258 prebuilts: ["myetc"], 2259 compile_multilib: "both", 2260 updatable: false, 2261 } 2262 2263 apex_key { 2264 name: "myapex.key", 2265 public_key: "testkey.avbpubkey", 2266 private_key: "testkey.pem", 2267 } 2268 2269 prebuilt_etc { 2270 name: "myetc", 2271 src: "myprebuilt", 2272 sub_dir: "foo/bar", 2273 } 2274 2275 cc_library { 2276 name: "mylib", 2277 srcs: ["mylib.cpp"], 2278 relative_install_path: "foo/bar", 2279 system_shared_libs: [], 2280 stl: "none", 2281 apex_available: [ "myapex" ], 2282 } 2283 2284 cc_binary { 2285 name: "mybin", 2286 srcs: ["mylib.cpp"], 2287 relative_install_path: "foo/bar", 2288 system_shared_libs: [], 2289 static_executable: true, 2290 stl: "none", 2291 apex_available: [ "myapex" ], 2292 } 2293 `) 2294 2295 generateFsRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("generateFsConfig") 2296 dirs := strings.Split(generateFsRule.Args["exec_paths"], " ") 2297 2298 // Ensure that the subdirectories are all listed 2299 ensureListContains(t, dirs, "etc") 2300 ensureListContains(t, dirs, "etc/foo") 2301 ensureListContains(t, dirs, "etc/foo/bar") 2302 ensureListContains(t, dirs, "lib64") 2303 ensureListContains(t, dirs, "lib64/foo") 2304 ensureListContains(t, dirs, "lib64/foo/bar") 2305 ensureListContains(t, dirs, "lib") 2306 ensureListContains(t, dirs, "lib/foo") 2307 ensureListContains(t, dirs, "lib/foo/bar") 2308 2309 ensureListContains(t, dirs, "bin") 2310 ensureListContains(t, dirs, "bin/foo") 2311 ensureListContains(t, dirs, "bin/foo/bar") 2312} 2313 2314func TestFilesInSubDirWhenNativeBridgeEnabled(t *testing.T) { 2315 ctx := testApex(t, ` 2316 apex { 2317 name: "myapex", 2318 key: "myapex.key", 2319 multilib: { 2320 both: { 2321 native_shared_libs: ["mylib"], 2322 binaries: ["mybin"], 2323 }, 2324 }, 2325 compile_multilib: "both", 2326 native_bridge_supported: true, 2327 updatable: false, 2328 } 2329 2330 apex_key { 2331 name: "myapex.key", 2332 public_key: "testkey.avbpubkey", 2333 private_key: "testkey.pem", 2334 } 2335 2336 cc_library { 2337 name: "mylib", 2338 relative_install_path: "foo/bar", 2339 system_shared_libs: [], 2340 stl: "none", 2341 apex_available: [ "myapex" ], 2342 native_bridge_supported: true, 2343 } 2344 2345 cc_binary { 2346 name: "mybin", 2347 relative_install_path: "foo/bar", 2348 system_shared_libs: [], 2349 static_executable: true, 2350 stl: "none", 2351 apex_available: [ "myapex" ], 2352 native_bridge_supported: true, 2353 compile_multilib: "both", // default is "first" for binary 2354 multilib: { 2355 lib64: { 2356 suffix: "64", 2357 }, 2358 }, 2359 } 2360 `, withNativeBridgeEnabled) 2361 ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{ 2362 "bin/foo/bar/mybin", 2363 "bin/foo/bar/mybin64", 2364 "bin/arm/foo/bar/mybin", 2365 "bin/arm64/foo/bar/mybin64", 2366 "lib/foo/bar/mylib.so", 2367 "lib/arm/foo/bar/mylib.so", 2368 "lib64/foo/bar/mylib.so", 2369 "lib64/arm64/foo/bar/mylib.so", 2370 }) 2371} 2372 2373func TestVendorApex(t *testing.T) { 2374 ctx := testApex(t, ` 2375 apex { 2376 name: "myapex", 2377 key: "myapex.key", 2378 binaries: ["mybin"], 2379 vendor: true, 2380 updatable: false, 2381 } 2382 apex_key { 2383 name: "myapex.key", 2384 public_key: "testkey.avbpubkey", 2385 private_key: "testkey.pem", 2386 } 2387 cc_binary { 2388 name: "mybin", 2389 vendor: true, 2390 shared_libs: ["libfoo"], 2391 } 2392 cc_library { 2393 name: "libfoo", 2394 proprietary: true, 2395 } 2396 `) 2397 2398 ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{ 2399 "bin/mybin", 2400 "lib64/libfoo.so", 2401 // TODO(b/159195575): Add an option to use VNDK libs from VNDK APEX 2402 "lib64/libc++.so", 2403 }) 2404 2405 apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle) 2406 data := android.AndroidMkDataForTest(t, ctx, apexBundle) 2407 name := apexBundle.BaseModuleName() 2408 prefix := "TARGET_" 2409 var builder strings.Builder 2410 data.Custom(&builder, name, prefix, "", data) 2411 androidMk := android.StringRelativeToTop(ctx.Config(), builder.String()) 2412 installPath := "out/target/product/test_device/vendor/apex" 2413 ensureContains(t, androidMk, "LOCAL_MODULE_PATH := "+installPath) 2414 2415 apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule") 2416 requireNativeLibs := names(apexManifestRule.Args["requireNativeLibs"]) 2417 ensureListNotContains(t, requireNativeLibs, ":vndk") 2418} 2419 2420func TestVendorApex_use_vndk_as_stable(t *testing.T) { 2421 ctx := testApex(t, ` 2422 apex { 2423 name: "myapex", 2424 key: "myapex.key", 2425 binaries: ["mybin"], 2426 vendor: true, 2427 use_vndk_as_stable: true, 2428 updatable: false, 2429 } 2430 apex_key { 2431 name: "myapex.key", 2432 public_key: "testkey.avbpubkey", 2433 private_key: "testkey.pem", 2434 } 2435 cc_binary { 2436 name: "mybin", 2437 vendor: true, 2438 shared_libs: ["libvndk", "libvendor"], 2439 } 2440 cc_library { 2441 name: "libvndk", 2442 vndk: { 2443 enabled: true, 2444 }, 2445 vendor_available: true, 2446 product_available: true, 2447 } 2448 cc_library { 2449 name: "libvendor", 2450 vendor: true, 2451 } 2452 `) 2453 2454 vendorVariant := "android_vendor.29_arm64_armv8-a" 2455 2456 ldRule := ctx.ModuleForTests("mybin", vendorVariant+"_apex10000").Rule("ld") 2457 libs := names(ldRule.Args["libFlags"]) 2458 // VNDK libs(libvndk/libc++) as they are 2459 ensureListContains(t, libs, "out/soong/.intermediates/libvndk/"+vendorVariant+"_shared/libvndk.so") 2460 ensureListContains(t, libs, "out/soong/.intermediates/"+cc.DefaultCcCommonTestModulesDir+"libc++/"+vendorVariant+"_shared/libc++.so") 2461 // non-stable Vendor libs as APEX variants 2462 ensureListContains(t, libs, "out/soong/.intermediates/libvendor/"+vendorVariant+"_shared_apex10000/libvendor.so") 2463 2464 // VNDK libs are not included when use_vndk_as_stable: true 2465 ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{ 2466 "bin/mybin", 2467 "lib64/libvendor.so", 2468 }) 2469 2470 apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule") 2471 requireNativeLibs := names(apexManifestRule.Args["requireNativeLibs"]) 2472 ensureListContains(t, requireNativeLibs, ":vndk") 2473} 2474 2475func TestProductVariant(t *testing.T) { 2476 ctx := testApex(t, ` 2477 apex { 2478 name: "myapex", 2479 key: "myapex.key", 2480 updatable: false, 2481 product_specific: true, 2482 binaries: ["foo"], 2483 } 2484 2485 apex_key { 2486 name: "myapex.key", 2487 public_key: "testkey.avbpubkey", 2488 private_key: "testkey.pem", 2489 } 2490 2491 cc_binary { 2492 name: "foo", 2493 product_available: true, 2494 apex_available: ["myapex"], 2495 srcs: ["foo.cpp"], 2496 } 2497 `, android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 2498 variables.ProductVndkVersion = proptools.StringPtr("current") 2499 }), 2500 ) 2501 2502 cflags := strings.Fields( 2503 ctx.ModuleForTests("foo", "android_product.29_arm64_armv8-a_apex10000").Rule("cc").Args["cFlags"]) 2504 ensureListContains(t, cflags, "-D__ANDROID_VNDK__") 2505 ensureListContains(t, cflags, "-D__ANDROID_APEX__") 2506 ensureListContains(t, cflags, "-D__ANDROID_PRODUCT__") 2507 ensureListNotContains(t, cflags, "-D__ANDROID_VENDOR__") 2508} 2509 2510func TestApex_withPrebuiltFirmware(t *testing.T) { 2511 testCases := []struct { 2512 name string 2513 additionalProp string 2514 }{ 2515 {"system apex with prebuilt_firmware", ""}, 2516 {"vendor apex with prebuilt_firmware", "vendor: true,"}, 2517 } 2518 for _, tc := range testCases { 2519 t.Run(tc.name, func(t *testing.T) { 2520 ctx := testApex(t, ` 2521 apex { 2522 name: "myapex", 2523 key: "myapex.key", 2524 prebuilts: ["myfirmware"], 2525 updatable: false, 2526 `+tc.additionalProp+` 2527 } 2528 apex_key { 2529 name: "myapex.key", 2530 public_key: "testkey.avbpubkey", 2531 private_key: "testkey.pem", 2532 } 2533 prebuilt_firmware { 2534 name: "myfirmware", 2535 src: "myfirmware.bin", 2536 filename_from_src: true, 2537 `+tc.additionalProp+` 2538 } 2539 `) 2540 ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{ 2541 "etc/firmware/myfirmware.bin", 2542 }) 2543 }) 2544 } 2545} 2546 2547func TestAndroidMk_VendorApexRequired(t *testing.T) { 2548 ctx := testApex(t, ` 2549 apex { 2550 name: "myapex", 2551 key: "myapex.key", 2552 vendor: true, 2553 native_shared_libs: ["mylib"], 2554 updatable: false, 2555 } 2556 2557 apex_key { 2558 name: "myapex.key", 2559 public_key: "testkey.avbpubkey", 2560 private_key: "testkey.pem", 2561 } 2562 2563 cc_library { 2564 name: "mylib", 2565 vendor_available: true, 2566 } 2567 `) 2568 2569 apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle) 2570 data := android.AndroidMkDataForTest(t, ctx, apexBundle) 2571 name := apexBundle.BaseModuleName() 2572 prefix := "TARGET_" 2573 var builder strings.Builder 2574 data.Custom(&builder, name, prefix, "", data) 2575 androidMk := builder.String() 2576 ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += libc.vendor libm.vendor libdl.vendor\n") 2577} 2578 2579func TestAndroidMkWritesCommonProperties(t *testing.T) { 2580 ctx := testApex(t, ` 2581 apex { 2582 name: "myapex", 2583 key: "myapex.key", 2584 vintf_fragments: ["fragment.xml"], 2585 init_rc: ["init.rc"], 2586 updatable: false, 2587 } 2588 apex_key { 2589 name: "myapex.key", 2590 public_key: "testkey.avbpubkey", 2591 private_key: "testkey.pem", 2592 } 2593 cc_binary { 2594 name: "mybin", 2595 } 2596 `) 2597 2598 apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle) 2599 data := android.AndroidMkDataForTest(t, ctx, apexBundle) 2600 name := apexBundle.BaseModuleName() 2601 prefix := "TARGET_" 2602 var builder strings.Builder 2603 data.Custom(&builder, name, prefix, "", data) 2604 androidMk := builder.String() 2605 ensureContains(t, androidMk, "LOCAL_FULL_VINTF_FRAGMENTS := fragment.xml\n") 2606 ensureContains(t, androidMk, "LOCAL_FULL_INIT_RC := init.rc\n") 2607} 2608 2609func TestStaticLinking(t *testing.T) { 2610 ctx := testApex(t, ` 2611 apex { 2612 name: "myapex", 2613 key: "myapex.key", 2614 native_shared_libs: ["mylib"], 2615 updatable: false, 2616 } 2617 2618 apex_key { 2619 name: "myapex.key", 2620 public_key: "testkey.avbpubkey", 2621 private_key: "testkey.pem", 2622 } 2623 2624 cc_library { 2625 name: "mylib", 2626 srcs: ["mylib.cpp"], 2627 system_shared_libs: [], 2628 stl: "none", 2629 stubs: { 2630 versions: ["1", "2", "3"], 2631 }, 2632 apex_available: [ 2633 "//apex_available:platform", 2634 "myapex", 2635 ], 2636 } 2637 2638 cc_binary { 2639 name: "not_in_apex", 2640 srcs: ["mylib.cpp"], 2641 static_libs: ["mylib"], 2642 static_executable: true, 2643 system_shared_libs: [], 2644 stl: "none", 2645 } 2646 `) 2647 2648 ldFlags := ctx.ModuleForTests("not_in_apex", "android_arm64_armv8-a").Rule("ld").Args["libFlags"] 2649 2650 // Ensure that not_in_apex is linking with the static variant of mylib 2651 ensureContains(t, ldFlags, "mylib/android_arm64_armv8-a_static/mylib.a") 2652} 2653 2654func TestKeys(t *testing.T) { 2655 ctx := testApex(t, ` 2656 apex { 2657 name: "myapex_keytest", 2658 key: "myapex.key", 2659 certificate: ":myapex.certificate", 2660 native_shared_libs: ["mylib"], 2661 file_contexts: ":myapex-file_contexts", 2662 updatable: false, 2663 } 2664 2665 cc_library { 2666 name: "mylib", 2667 srcs: ["mylib.cpp"], 2668 system_shared_libs: [], 2669 stl: "none", 2670 apex_available: [ "myapex_keytest" ], 2671 } 2672 2673 apex_key { 2674 name: "myapex.key", 2675 public_key: "testkey.avbpubkey", 2676 private_key: "testkey.pem", 2677 } 2678 2679 android_app_certificate { 2680 name: "myapex.certificate", 2681 certificate: "testkey", 2682 } 2683 2684 android_app_certificate { 2685 name: "myapex.certificate.override", 2686 certificate: "testkey.override", 2687 } 2688 2689 `) 2690 2691 // check the APEX keys 2692 keys := ctx.ModuleForTests("myapex.key", "android_common").Module().(*apexKey) 2693 2694 if keys.publicKeyFile.String() != "vendor/foo/devkeys/testkey.avbpubkey" { 2695 t.Errorf("public key %q is not %q", keys.publicKeyFile.String(), 2696 "vendor/foo/devkeys/testkey.avbpubkey") 2697 } 2698 if keys.privateKeyFile.String() != "vendor/foo/devkeys/testkey.pem" { 2699 t.Errorf("private key %q is not %q", keys.privateKeyFile.String(), 2700 "vendor/foo/devkeys/testkey.pem") 2701 } 2702 2703 // check the APK certs. It should be overridden to myapex.certificate.override 2704 certs := ctx.ModuleForTests("myapex_keytest", "android_common_myapex_keytest_image").Rule("signapk").Args["certificates"] 2705 if certs != "testkey.override.x509.pem testkey.override.pk8" { 2706 t.Errorf("cert and private key %q are not %q", certs, 2707 "testkey.override.509.pem testkey.override.pk8") 2708 } 2709} 2710 2711func TestCertificate(t *testing.T) { 2712 t.Run("if unspecified, it defaults to DefaultAppCertificate", func(t *testing.T) { 2713 ctx := testApex(t, ` 2714 apex { 2715 name: "myapex", 2716 key: "myapex.key", 2717 updatable: false, 2718 } 2719 apex_key { 2720 name: "myapex.key", 2721 public_key: "testkey.avbpubkey", 2722 private_key: "testkey.pem", 2723 }`) 2724 rule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("signapk") 2725 expected := "vendor/foo/devkeys/test.x509.pem vendor/foo/devkeys/test.pk8" 2726 if actual := rule.Args["certificates"]; actual != expected { 2727 t.Errorf("certificates should be %q, not %q", expected, actual) 2728 } 2729 }) 2730 t.Run("override when unspecified", func(t *testing.T) { 2731 ctx := testApex(t, ` 2732 apex { 2733 name: "myapex_keytest", 2734 key: "myapex.key", 2735 file_contexts: ":myapex-file_contexts", 2736 updatable: false, 2737 } 2738 apex_key { 2739 name: "myapex.key", 2740 public_key: "testkey.avbpubkey", 2741 private_key: "testkey.pem", 2742 } 2743 android_app_certificate { 2744 name: "myapex.certificate.override", 2745 certificate: "testkey.override", 2746 }`) 2747 rule := ctx.ModuleForTests("myapex_keytest", "android_common_myapex_keytest_image").Rule("signapk") 2748 expected := "testkey.override.x509.pem testkey.override.pk8" 2749 if actual := rule.Args["certificates"]; actual != expected { 2750 t.Errorf("certificates should be %q, not %q", expected, actual) 2751 } 2752 }) 2753 t.Run("if specified as :module, it respects the prop", func(t *testing.T) { 2754 ctx := testApex(t, ` 2755 apex { 2756 name: "myapex", 2757 key: "myapex.key", 2758 certificate: ":myapex.certificate", 2759 updatable: false, 2760 } 2761 apex_key { 2762 name: "myapex.key", 2763 public_key: "testkey.avbpubkey", 2764 private_key: "testkey.pem", 2765 } 2766 android_app_certificate { 2767 name: "myapex.certificate", 2768 certificate: "testkey", 2769 }`) 2770 rule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("signapk") 2771 expected := "testkey.x509.pem testkey.pk8" 2772 if actual := rule.Args["certificates"]; actual != expected { 2773 t.Errorf("certificates should be %q, not %q", expected, actual) 2774 } 2775 }) 2776 t.Run("override when specifiec as <:module>", func(t *testing.T) { 2777 ctx := testApex(t, ` 2778 apex { 2779 name: "myapex_keytest", 2780 key: "myapex.key", 2781 file_contexts: ":myapex-file_contexts", 2782 certificate: ":myapex.certificate", 2783 updatable: false, 2784 } 2785 apex_key { 2786 name: "myapex.key", 2787 public_key: "testkey.avbpubkey", 2788 private_key: "testkey.pem", 2789 } 2790 android_app_certificate { 2791 name: "myapex.certificate.override", 2792 certificate: "testkey.override", 2793 }`) 2794 rule := ctx.ModuleForTests("myapex_keytest", "android_common_myapex_keytest_image").Rule("signapk") 2795 expected := "testkey.override.x509.pem testkey.override.pk8" 2796 if actual := rule.Args["certificates"]; actual != expected { 2797 t.Errorf("certificates should be %q, not %q", expected, actual) 2798 } 2799 }) 2800 t.Run("if specified as name, finds it from DefaultDevKeyDir", func(t *testing.T) { 2801 ctx := testApex(t, ` 2802 apex { 2803 name: "myapex", 2804 key: "myapex.key", 2805 certificate: "testkey", 2806 updatable: false, 2807 } 2808 apex_key { 2809 name: "myapex.key", 2810 public_key: "testkey.avbpubkey", 2811 private_key: "testkey.pem", 2812 }`) 2813 rule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("signapk") 2814 expected := "vendor/foo/devkeys/testkey.x509.pem vendor/foo/devkeys/testkey.pk8" 2815 if actual := rule.Args["certificates"]; actual != expected { 2816 t.Errorf("certificates should be %q, not %q", expected, actual) 2817 } 2818 }) 2819 t.Run("override when specified as <name>", func(t *testing.T) { 2820 ctx := testApex(t, ` 2821 apex { 2822 name: "myapex_keytest", 2823 key: "myapex.key", 2824 file_contexts: ":myapex-file_contexts", 2825 certificate: "testkey", 2826 updatable: false, 2827 } 2828 apex_key { 2829 name: "myapex.key", 2830 public_key: "testkey.avbpubkey", 2831 private_key: "testkey.pem", 2832 } 2833 android_app_certificate { 2834 name: "myapex.certificate.override", 2835 certificate: "testkey.override", 2836 }`) 2837 rule := ctx.ModuleForTests("myapex_keytest", "android_common_myapex_keytest_image").Rule("signapk") 2838 expected := "testkey.override.x509.pem testkey.override.pk8" 2839 if actual := rule.Args["certificates"]; actual != expected { 2840 t.Errorf("certificates should be %q, not %q", expected, actual) 2841 } 2842 }) 2843} 2844 2845func TestMacro(t *testing.T) { 2846 ctx := testApex(t, ` 2847 apex { 2848 name: "myapex", 2849 key: "myapex.key", 2850 native_shared_libs: ["mylib", "mylib2"], 2851 updatable: false, 2852 } 2853 2854 apex { 2855 name: "otherapex", 2856 key: "myapex.key", 2857 native_shared_libs: ["mylib", "mylib2"], 2858 min_sdk_version: "29", 2859 } 2860 2861 apex_key { 2862 name: "myapex.key", 2863 public_key: "testkey.avbpubkey", 2864 private_key: "testkey.pem", 2865 } 2866 2867 cc_library { 2868 name: "mylib", 2869 srcs: ["mylib.cpp"], 2870 system_shared_libs: [], 2871 stl: "none", 2872 apex_available: [ 2873 "myapex", 2874 "otherapex", 2875 ], 2876 recovery_available: true, 2877 min_sdk_version: "29", 2878 } 2879 cc_library { 2880 name: "mylib2", 2881 srcs: ["mylib.cpp"], 2882 system_shared_libs: [], 2883 stl: "none", 2884 apex_available: [ 2885 "myapex", 2886 "otherapex", 2887 ], 2888 static_libs: ["mylib3"], 2889 recovery_available: true, 2890 min_sdk_version: "29", 2891 } 2892 cc_library { 2893 name: "mylib3", 2894 srcs: ["mylib.cpp"], 2895 system_shared_libs: [], 2896 stl: "none", 2897 apex_available: [ 2898 "myapex", 2899 "otherapex", 2900 ], 2901 use_apex_name_macro: true, 2902 recovery_available: true, 2903 min_sdk_version: "29", 2904 } 2905 `) 2906 2907 // non-APEX variant does not have __ANDROID_APEX__ defined 2908 mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"] 2909 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__") 2910 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MIN_SDK_VERSION__") 2911 2912 // APEX variant has __ANDROID_APEX__ and __ANDROID_APEX_SDK__ defined 2913 mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex10000").Rule("cc").Args["cFlags"] 2914 ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__") 2915 ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_MIN_SDK_VERSION__=10000") 2916 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__") 2917 2918 // APEX variant has __ANDROID_APEX__ and __ANDROID_APEX_SDK__ defined 2919 mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex29").Rule("cc").Args["cFlags"] 2920 ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__") 2921 ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_MIN_SDK_VERSION__=29") 2922 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__") 2923 2924 // When a cc_library sets use_apex_name_macro: true each apex gets a unique variant and 2925 // each variant defines additional macros to distinguish which apex variant it is built for 2926 2927 // non-APEX variant does not have __ANDROID_APEX__ defined 2928 mylibCFlags = ctx.ModuleForTests("mylib3", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"] 2929 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__") 2930 2931 // APEX variant has __ANDROID_APEX__ defined 2932 mylibCFlags = ctx.ModuleForTests("mylib3", "android_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"] 2933 ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__") 2934 ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__") 2935 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__") 2936 2937 // APEX variant has __ANDROID_APEX__ defined 2938 mylibCFlags = ctx.ModuleForTests("mylib3", "android_arm64_armv8-a_static_otherapex").Rule("cc").Args["cFlags"] 2939 ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__") 2940 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__") 2941 ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__") 2942 2943 // recovery variant does not set __ANDROID_APEX_MIN_SDK_VERSION__ 2944 mylibCFlags = ctx.ModuleForTests("mylib3", "android_recovery_arm64_armv8-a_static").Rule("cc").Args["cFlags"] 2945 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__") 2946 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MIN_SDK_VERSION__") 2947 2948 // When a dependency of a cc_library sets use_apex_name_macro: true each apex gets a unique 2949 // variant. 2950 2951 // non-APEX variant does not have __ANDROID_APEX__ defined 2952 mylibCFlags = ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"] 2953 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__") 2954 2955 // APEX variant has __ANDROID_APEX__ defined 2956 mylibCFlags = ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"] 2957 ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__") 2958 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__") 2959 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__") 2960 2961 // APEX variant has __ANDROID_APEX__ defined 2962 mylibCFlags = ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static_otherapex").Rule("cc").Args["cFlags"] 2963 ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__") 2964 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__") 2965 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__") 2966 2967 // recovery variant does not set __ANDROID_APEX_MIN_SDK_VERSION__ 2968 mylibCFlags = ctx.ModuleForTests("mylib2", "android_recovery_arm64_armv8-a_static").Rule("cc").Args["cFlags"] 2969 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__") 2970 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MIN_SDK_VERSION__") 2971} 2972 2973func TestHeaderLibsDependency(t *testing.T) { 2974 ctx := testApex(t, ` 2975 apex { 2976 name: "myapex", 2977 key: "myapex.key", 2978 native_shared_libs: ["mylib"], 2979 updatable: false, 2980 } 2981 2982 apex_key { 2983 name: "myapex.key", 2984 public_key: "testkey.avbpubkey", 2985 private_key: "testkey.pem", 2986 } 2987 2988 cc_library_headers { 2989 name: "mylib_headers", 2990 export_include_dirs: ["my_include"], 2991 system_shared_libs: [], 2992 stl: "none", 2993 apex_available: [ "myapex" ], 2994 } 2995 2996 cc_library { 2997 name: "mylib", 2998 srcs: ["mylib.cpp"], 2999 system_shared_libs: [], 3000 stl: "none", 3001 header_libs: ["mylib_headers"], 3002 export_header_lib_headers: ["mylib_headers"], 3003 stubs: { 3004 versions: ["1", "2", "3"], 3005 }, 3006 apex_available: [ "myapex" ], 3007 } 3008 3009 cc_library { 3010 name: "otherlib", 3011 srcs: ["mylib.cpp"], 3012 system_shared_libs: [], 3013 stl: "none", 3014 shared_libs: ["mylib"], 3015 } 3016 `) 3017 3018 cFlags := ctx.ModuleForTests("otherlib", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"] 3019 3020 // Ensure that the include path of the header lib is exported to 'otherlib' 3021 ensureContains(t, cFlags, "-Imy_include") 3022} 3023 3024type fileInApex struct { 3025 path string // path in apex 3026 src string // src path 3027 isLink bool 3028} 3029 3030func getFiles(t *testing.T, ctx *android.TestContext, moduleName, variant string) []fileInApex { 3031 t.Helper() 3032 apexRule := ctx.ModuleForTests(moduleName, variant).Rule("apexRule") 3033 copyCmds := apexRule.Args["copy_commands"] 3034 imageApexDir := "/image.apex/" 3035 var ret []fileInApex 3036 for _, cmd := range strings.Split(copyCmds, "&&") { 3037 cmd = strings.TrimSpace(cmd) 3038 if cmd == "" { 3039 continue 3040 } 3041 terms := strings.Split(cmd, " ") 3042 var dst, src string 3043 var isLink bool 3044 switch terms[0] { 3045 case "mkdir": 3046 case "cp": 3047 if len(terms) != 3 && len(terms) != 4 { 3048 t.Fatal("copyCmds contains invalid cp command", cmd) 3049 } 3050 dst = terms[len(terms)-1] 3051 src = terms[len(terms)-2] 3052 isLink = false 3053 case "ln": 3054 if len(terms) != 3 && len(terms) != 4 { 3055 // ln LINK TARGET or ln -s LINK TARGET 3056 t.Fatal("copyCmds contains invalid ln command", cmd) 3057 } 3058 dst = terms[len(terms)-1] 3059 src = terms[len(terms)-2] 3060 isLink = true 3061 default: 3062 t.Fatalf("copyCmds should contain mkdir/cp commands only: %q", cmd) 3063 } 3064 if dst != "" { 3065 index := strings.Index(dst, imageApexDir) 3066 if index == -1 { 3067 t.Fatal("copyCmds should copy a file to image.apex/", cmd) 3068 } 3069 dstFile := dst[index+len(imageApexDir):] 3070 ret = append(ret, fileInApex{path: dstFile, src: src, isLink: isLink}) 3071 } 3072 } 3073 return ret 3074} 3075 3076func ensureExactContents(t *testing.T, ctx *android.TestContext, moduleName, variant string, files []string) { 3077 t.Helper() 3078 var failed bool 3079 var surplus []string 3080 filesMatched := make(map[string]bool) 3081 for _, file := range getFiles(t, ctx, moduleName, variant) { 3082 mactchFound := false 3083 for _, expected := range files { 3084 if matched, _ := path.Match(expected, file.path); matched { 3085 filesMatched[expected] = true 3086 mactchFound = true 3087 break 3088 } 3089 } 3090 if !mactchFound { 3091 surplus = append(surplus, file.path) 3092 } 3093 } 3094 3095 if len(surplus) > 0 { 3096 sort.Strings(surplus) 3097 t.Log("surplus files", surplus) 3098 failed = true 3099 } 3100 3101 if len(files) > len(filesMatched) { 3102 var missing []string 3103 for _, expected := range files { 3104 if !filesMatched[expected] { 3105 missing = append(missing, expected) 3106 } 3107 } 3108 sort.Strings(missing) 3109 t.Log("missing files", missing) 3110 failed = true 3111 } 3112 if failed { 3113 t.Fail() 3114 } 3115} 3116 3117func TestVndkApexCurrent(t *testing.T) { 3118 ctx := testApex(t, ` 3119 apex_vndk { 3120 name: "com.android.vndk.current", 3121 key: "com.android.vndk.current.key", 3122 updatable: false, 3123 } 3124 3125 apex_key { 3126 name: "com.android.vndk.current.key", 3127 public_key: "testkey.avbpubkey", 3128 private_key: "testkey.pem", 3129 } 3130 3131 cc_library { 3132 name: "libvndk", 3133 srcs: ["mylib.cpp"], 3134 vendor_available: true, 3135 product_available: true, 3136 vndk: { 3137 enabled: true, 3138 }, 3139 system_shared_libs: [], 3140 stl: "none", 3141 apex_available: [ "com.android.vndk.current" ], 3142 } 3143 3144 cc_library { 3145 name: "libvndksp", 3146 srcs: ["mylib.cpp"], 3147 vendor_available: true, 3148 product_available: true, 3149 vndk: { 3150 enabled: true, 3151 support_system_process: true, 3152 }, 3153 system_shared_libs: [], 3154 stl: "none", 3155 apex_available: [ "com.android.vndk.current" ], 3156 } 3157 `+vndkLibrariesTxtFiles("current")) 3158 3159 ensureExactContents(t, ctx, "com.android.vndk.current", "android_common_image", []string{ 3160 "lib/libvndk.so", 3161 "lib/libvndksp.so", 3162 "lib/libc++.so", 3163 "lib64/libvndk.so", 3164 "lib64/libvndksp.so", 3165 "lib64/libc++.so", 3166 "etc/llndk.libraries.29.txt", 3167 "etc/vndkcore.libraries.29.txt", 3168 "etc/vndksp.libraries.29.txt", 3169 "etc/vndkprivate.libraries.29.txt", 3170 "etc/vndkproduct.libraries.29.txt", 3171 }) 3172} 3173 3174func TestVndkApexWithPrebuilt(t *testing.T) { 3175 ctx := testApex(t, ` 3176 apex_vndk { 3177 name: "com.android.vndk.current", 3178 key: "com.android.vndk.current.key", 3179 updatable: false, 3180 } 3181 3182 apex_key { 3183 name: "com.android.vndk.current.key", 3184 public_key: "testkey.avbpubkey", 3185 private_key: "testkey.pem", 3186 } 3187 3188 cc_prebuilt_library_shared { 3189 name: "libvndk", 3190 srcs: ["libvndk.so"], 3191 vendor_available: true, 3192 product_available: true, 3193 vndk: { 3194 enabled: true, 3195 }, 3196 system_shared_libs: [], 3197 stl: "none", 3198 apex_available: [ "com.android.vndk.current" ], 3199 } 3200 3201 cc_prebuilt_library_shared { 3202 name: "libvndk.arm", 3203 srcs: ["libvndk.arm.so"], 3204 vendor_available: true, 3205 product_available: true, 3206 vndk: { 3207 enabled: true, 3208 }, 3209 enabled: false, 3210 arch: { 3211 arm: { 3212 enabled: true, 3213 }, 3214 }, 3215 system_shared_libs: [], 3216 stl: "none", 3217 apex_available: [ "com.android.vndk.current" ], 3218 } 3219 `+vndkLibrariesTxtFiles("current"), 3220 withFiles(map[string][]byte{ 3221 "libvndk.so": nil, 3222 "libvndk.arm.so": nil, 3223 })) 3224 ensureExactContents(t, ctx, "com.android.vndk.current", "android_common_image", []string{ 3225 "lib/libvndk.so", 3226 "lib/libvndk.arm.so", 3227 "lib64/libvndk.so", 3228 "lib/libc++.so", 3229 "lib64/libc++.so", 3230 "etc/*", 3231 }) 3232} 3233 3234func vndkLibrariesTxtFiles(vers ...string) (result string) { 3235 for _, v := range vers { 3236 if v == "current" { 3237 for _, txt := range []string{"llndk", "vndkcore", "vndksp", "vndkprivate", "vndkproduct"} { 3238 result += ` 3239 ` + txt + `_libraries_txt { 3240 name: "` + txt + `.libraries.txt", 3241 } 3242 ` 3243 } 3244 } else { 3245 for _, txt := range []string{"llndk", "vndkcore", "vndksp", "vndkprivate", "vndkproduct"} { 3246 result += ` 3247 prebuilt_etc { 3248 name: "` + txt + `.libraries.` + v + `.txt", 3249 src: "dummy.txt", 3250 } 3251 ` 3252 } 3253 } 3254 } 3255 return 3256} 3257 3258func TestVndkApexVersion(t *testing.T) { 3259 ctx := testApex(t, ` 3260 apex_vndk { 3261 name: "com.android.vndk.v27", 3262 key: "myapex.key", 3263 file_contexts: ":myapex-file_contexts", 3264 vndk_version: "27", 3265 updatable: false, 3266 } 3267 3268 apex_key { 3269 name: "myapex.key", 3270 public_key: "testkey.avbpubkey", 3271 private_key: "testkey.pem", 3272 } 3273 3274 vndk_prebuilt_shared { 3275 name: "libvndk27", 3276 version: "27", 3277 vendor_available: true, 3278 product_available: true, 3279 vndk: { 3280 enabled: true, 3281 }, 3282 target_arch: "arm64", 3283 arch: { 3284 arm: { 3285 srcs: ["libvndk27_arm.so"], 3286 }, 3287 arm64: { 3288 srcs: ["libvndk27_arm64.so"], 3289 }, 3290 }, 3291 apex_available: [ "com.android.vndk.v27" ], 3292 } 3293 3294 vndk_prebuilt_shared { 3295 name: "libvndk27", 3296 version: "27", 3297 vendor_available: true, 3298 product_available: true, 3299 vndk: { 3300 enabled: true, 3301 }, 3302 target_arch: "x86_64", 3303 arch: { 3304 x86: { 3305 srcs: ["libvndk27_x86.so"], 3306 }, 3307 x86_64: { 3308 srcs: ["libvndk27_x86_64.so"], 3309 }, 3310 }, 3311 } 3312 `+vndkLibrariesTxtFiles("27"), 3313 withFiles(map[string][]byte{ 3314 "libvndk27_arm.so": nil, 3315 "libvndk27_arm64.so": nil, 3316 "libvndk27_x86.so": nil, 3317 "libvndk27_x86_64.so": nil, 3318 })) 3319 3320 ensureExactContents(t, ctx, "com.android.vndk.v27", "android_common_image", []string{ 3321 "lib/libvndk27_arm.so", 3322 "lib64/libvndk27_arm64.so", 3323 "etc/*", 3324 }) 3325} 3326 3327func TestVndkApexNameRule(t *testing.T) { 3328 ctx := testApex(t, ` 3329 apex_vndk { 3330 name: "com.android.vndk.current", 3331 key: "myapex.key", 3332 file_contexts: ":myapex-file_contexts", 3333 updatable: false, 3334 } 3335 apex_vndk { 3336 name: "com.android.vndk.v28", 3337 key: "myapex.key", 3338 file_contexts: ":myapex-file_contexts", 3339 vndk_version: "28", 3340 updatable: false, 3341 } 3342 apex_key { 3343 name: "myapex.key", 3344 public_key: "testkey.avbpubkey", 3345 private_key: "testkey.pem", 3346 }`+vndkLibrariesTxtFiles("28", "current")) 3347 3348 assertApexName := func(expected, moduleName string) { 3349 bundle := ctx.ModuleForTests(moduleName, "android_common_image").Module().(*apexBundle) 3350 actual := proptools.String(bundle.properties.Apex_name) 3351 if !reflect.DeepEqual(actual, expected) { 3352 t.Errorf("Got '%v', expected '%v'", actual, expected) 3353 } 3354 } 3355 3356 assertApexName("com.android.vndk.v29", "com.android.vndk.current") 3357 assertApexName("com.android.vndk.v28", "com.android.vndk.v28") 3358} 3359 3360func TestVndkApexSkipsNativeBridgeSupportedModules(t *testing.T) { 3361 ctx := testApex(t, ` 3362 apex_vndk { 3363 name: "com.android.vndk.current", 3364 key: "com.android.vndk.current.key", 3365 file_contexts: ":myapex-file_contexts", 3366 updatable: false, 3367 } 3368 3369 apex_key { 3370 name: "com.android.vndk.current.key", 3371 public_key: "testkey.avbpubkey", 3372 private_key: "testkey.pem", 3373 } 3374 3375 cc_library { 3376 name: "libvndk", 3377 srcs: ["mylib.cpp"], 3378 vendor_available: true, 3379 product_available: true, 3380 native_bridge_supported: true, 3381 host_supported: true, 3382 vndk: { 3383 enabled: true, 3384 }, 3385 system_shared_libs: [], 3386 stl: "none", 3387 apex_available: [ "com.android.vndk.current" ], 3388 } 3389 `+vndkLibrariesTxtFiles("current"), 3390 withNativeBridgeEnabled) 3391 3392 ensureExactContents(t, ctx, "com.android.vndk.current", "android_common_image", []string{ 3393 "lib/libvndk.so", 3394 "lib64/libvndk.so", 3395 "lib/libc++.so", 3396 "lib64/libc++.so", 3397 "etc/*", 3398 }) 3399} 3400 3401func TestVndkApexDoesntSupportNativeBridgeSupported(t *testing.T) { 3402 testApexError(t, `module "com.android.vndk.current" .*: native_bridge_supported: .* doesn't support native bridge binary`, ` 3403 apex_vndk { 3404 name: "com.android.vndk.current", 3405 key: "com.android.vndk.current.key", 3406 file_contexts: ":myapex-file_contexts", 3407 native_bridge_supported: true, 3408 } 3409 3410 apex_key { 3411 name: "com.android.vndk.current.key", 3412 public_key: "testkey.avbpubkey", 3413 private_key: "testkey.pem", 3414 } 3415 3416 cc_library { 3417 name: "libvndk", 3418 srcs: ["mylib.cpp"], 3419 vendor_available: true, 3420 product_available: true, 3421 native_bridge_supported: true, 3422 host_supported: true, 3423 vndk: { 3424 enabled: true, 3425 }, 3426 system_shared_libs: [], 3427 stl: "none", 3428 } 3429 `) 3430} 3431 3432func TestVndkApexWithBinder32(t *testing.T) { 3433 ctx := testApex(t, ` 3434 apex_vndk { 3435 name: "com.android.vndk.v27", 3436 key: "myapex.key", 3437 file_contexts: ":myapex-file_contexts", 3438 vndk_version: "27", 3439 updatable: false, 3440 } 3441 3442 apex_key { 3443 name: "myapex.key", 3444 public_key: "testkey.avbpubkey", 3445 private_key: "testkey.pem", 3446 } 3447 3448 vndk_prebuilt_shared { 3449 name: "libvndk27", 3450 version: "27", 3451 target_arch: "arm", 3452 vendor_available: true, 3453 product_available: true, 3454 vndk: { 3455 enabled: true, 3456 }, 3457 arch: { 3458 arm: { 3459 srcs: ["libvndk27.so"], 3460 } 3461 }, 3462 } 3463 3464 vndk_prebuilt_shared { 3465 name: "libvndk27", 3466 version: "27", 3467 target_arch: "arm", 3468 binder32bit: true, 3469 vendor_available: true, 3470 product_available: true, 3471 vndk: { 3472 enabled: true, 3473 }, 3474 arch: { 3475 arm: { 3476 srcs: ["libvndk27binder32.so"], 3477 } 3478 }, 3479 apex_available: [ "com.android.vndk.v27" ], 3480 } 3481 `+vndkLibrariesTxtFiles("27"), 3482 withFiles(map[string][]byte{ 3483 "libvndk27.so": nil, 3484 "libvndk27binder32.so": nil, 3485 }), 3486 withBinder32bit, 3487 withTargets(map[android.OsType][]android.Target{ 3488 android.Android: []android.Target{ 3489 {Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, 3490 NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""}, 3491 }, 3492 }), 3493 ) 3494 3495 ensureExactContents(t, ctx, "com.android.vndk.v27", "android_common_image", []string{ 3496 "lib/libvndk27binder32.so", 3497 "etc/*", 3498 }) 3499} 3500 3501func TestVndkApexShouldNotProvideNativeLibs(t *testing.T) { 3502 ctx := testApex(t, ` 3503 apex_vndk { 3504 name: "com.android.vndk.current", 3505 key: "com.android.vndk.current.key", 3506 file_contexts: ":myapex-file_contexts", 3507 updatable: false, 3508 } 3509 3510 apex_key { 3511 name: "com.android.vndk.current.key", 3512 public_key: "testkey.avbpubkey", 3513 private_key: "testkey.pem", 3514 } 3515 3516 cc_library { 3517 name: "libz", 3518 vendor_available: true, 3519 product_available: true, 3520 vndk: { 3521 enabled: true, 3522 }, 3523 stubs: { 3524 symbol_file: "libz.map.txt", 3525 versions: ["30"], 3526 } 3527 } 3528 `+vndkLibrariesTxtFiles("current"), withFiles(map[string][]byte{ 3529 "libz.map.txt": nil, 3530 })) 3531 3532 apexManifestRule := ctx.ModuleForTests("com.android.vndk.current", "android_common_image").Rule("apexManifestRule") 3533 provideNativeLibs := names(apexManifestRule.Args["provideNativeLibs"]) 3534 ensureListEmpty(t, provideNativeLibs) 3535} 3536 3537func TestDependenciesInApexManifest(t *testing.T) { 3538 ctx := testApex(t, ` 3539 apex { 3540 name: "myapex_nodep", 3541 key: "myapex.key", 3542 native_shared_libs: ["lib_nodep"], 3543 compile_multilib: "both", 3544 file_contexts: ":myapex-file_contexts", 3545 updatable: false, 3546 } 3547 3548 apex { 3549 name: "myapex_dep", 3550 key: "myapex.key", 3551 native_shared_libs: ["lib_dep"], 3552 compile_multilib: "both", 3553 file_contexts: ":myapex-file_contexts", 3554 updatable: false, 3555 } 3556 3557 apex { 3558 name: "myapex_provider", 3559 key: "myapex.key", 3560 native_shared_libs: ["libfoo"], 3561 compile_multilib: "both", 3562 file_contexts: ":myapex-file_contexts", 3563 updatable: false, 3564 } 3565 3566 apex { 3567 name: "myapex_selfcontained", 3568 key: "myapex.key", 3569 native_shared_libs: ["lib_dep", "libfoo"], 3570 compile_multilib: "both", 3571 file_contexts: ":myapex-file_contexts", 3572 updatable: false, 3573 } 3574 3575 apex_key { 3576 name: "myapex.key", 3577 public_key: "testkey.avbpubkey", 3578 private_key: "testkey.pem", 3579 } 3580 3581 cc_library { 3582 name: "lib_nodep", 3583 srcs: ["mylib.cpp"], 3584 system_shared_libs: [], 3585 stl: "none", 3586 apex_available: [ "myapex_nodep" ], 3587 } 3588 3589 cc_library { 3590 name: "lib_dep", 3591 srcs: ["mylib.cpp"], 3592 shared_libs: ["libfoo"], 3593 system_shared_libs: [], 3594 stl: "none", 3595 apex_available: [ 3596 "myapex_dep", 3597 "myapex_provider", 3598 "myapex_selfcontained", 3599 ], 3600 } 3601 3602 cc_library { 3603 name: "libfoo", 3604 srcs: ["mytest.cpp"], 3605 stubs: { 3606 versions: ["1"], 3607 }, 3608 system_shared_libs: [], 3609 stl: "none", 3610 apex_available: [ 3611 "myapex_provider", 3612 "myapex_selfcontained", 3613 ], 3614 } 3615 `) 3616 3617 var apexManifestRule android.TestingBuildParams 3618 var provideNativeLibs, requireNativeLibs []string 3619 3620 apexManifestRule = ctx.ModuleForTests("myapex_nodep", "android_common_myapex_nodep_image").Rule("apexManifestRule") 3621 provideNativeLibs = names(apexManifestRule.Args["provideNativeLibs"]) 3622 requireNativeLibs = names(apexManifestRule.Args["requireNativeLibs"]) 3623 ensureListEmpty(t, provideNativeLibs) 3624 ensureListEmpty(t, requireNativeLibs) 3625 3626 apexManifestRule = ctx.ModuleForTests("myapex_dep", "android_common_myapex_dep_image").Rule("apexManifestRule") 3627 provideNativeLibs = names(apexManifestRule.Args["provideNativeLibs"]) 3628 requireNativeLibs = names(apexManifestRule.Args["requireNativeLibs"]) 3629 ensureListEmpty(t, provideNativeLibs) 3630 ensureListContains(t, requireNativeLibs, "libfoo.so") 3631 3632 apexManifestRule = ctx.ModuleForTests("myapex_provider", "android_common_myapex_provider_image").Rule("apexManifestRule") 3633 provideNativeLibs = names(apexManifestRule.Args["provideNativeLibs"]) 3634 requireNativeLibs = names(apexManifestRule.Args["requireNativeLibs"]) 3635 ensureListContains(t, provideNativeLibs, "libfoo.so") 3636 ensureListEmpty(t, requireNativeLibs) 3637 3638 apexManifestRule = ctx.ModuleForTests("myapex_selfcontained", "android_common_myapex_selfcontained_image").Rule("apexManifestRule") 3639 provideNativeLibs = names(apexManifestRule.Args["provideNativeLibs"]) 3640 requireNativeLibs = names(apexManifestRule.Args["requireNativeLibs"]) 3641 ensureListContains(t, provideNativeLibs, "libfoo.so") 3642 ensureListEmpty(t, requireNativeLibs) 3643} 3644 3645func TestApexName(t *testing.T) { 3646 ctx := testApex(t, ` 3647 apex { 3648 name: "myapex", 3649 key: "myapex.key", 3650 apex_name: "com.android.myapex", 3651 native_shared_libs: ["mylib"], 3652 updatable: false, 3653 } 3654 3655 apex_key { 3656 name: "myapex.key", 3657 public_key: "testkey.avbpubkey", 3658 private_key: "testkey.pem", 3659 } 3660 3661 cc_library { 3662 name: "mylib", 3663 srcs: ["mylib.cpp"], 3664 system_shared_libs: [], 3665 stl: "none", 3666 apex_available: [ 3667 "//apex_available:platform", 3668 "myapex", 3669 ], 3670 } 3671 `) 3672 3673 module := ctx.ModuleForTests("myapex", "android_common_com.android.myapex_image") 3674 apexManifestRule := module.Rule("apexManifestRule") 3675 ensureContains(t, apexManifestRule.Args["opt"], "-v name com.android.myapex") 3676 apexRule := module.Rule("apexRule") 3677 ensureContains(t, apexRule.Args["opt_flags"], "--do_not_check_keyname") 3678 3679 apexBundle := module.Module().(*apexBundle) 3680 data := android.AndroidMkDataForTest(t, ctx, apexBundle) 3681 name := apexBundle.BaseModuleName() 3682 prefix := "TARGET_" 3683 var builder strings.Builder 3684 data.Custom(&builder, name, prefix, "", data) 3685 androidMk := builder.String() 3686 ensureContains(t, androidMk, "LOCAL_MODULE := mylib.myapex\n") 3687 ensureNotContains(t, androidMk, "LOCAL_MODULE := mylib.com.android.myapex\n") 3688} 3689 3690func TestNonTestApex(t *testing.T) { 3691 ctx := testApex(t, ` 3692 apex { 3693 name: "myapex", 3694 key: "myapex.key", 3695 native_shared_libs: ["mylib_common"], 3696 updatable: false, 3697 } 3698 3699 apex_key { 3700 name: "myapex.key", 3701 public_key: "testkey.avbpubkey", 3702 private_key: "testkey.pem", 3703 } 3704 3705 cc_library { 3706 name: "mylib_common", 3707 srcs: ["mylib.cpp"], 3708 system_shared_libs: [], 3709 stl: "none", 3710 apex_available: [ 3711 "//apex_available:platform", 3712 "myapex", 3713 ], 3714 } 3715 `) 3716 3717 module := ctx.ModuleForTests("myapex", "android_common_myapex_image") 3718 apexRule := module.Rule("apexRule") 3719 copyCmds := apexRule.Args["copy_commands"] 3720 3721 if apex, ok := module.Module().(*apexBundle); !ok || apex.testApex { 3722 t.Log("Apex was a test apex!") 3723 t.Fail() 3724 } 3725 // Ensure that main rule creates an output 3726 ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned") 3727 3728 // Ensure that apex variant is created for the direct dep 3729 ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared_apex10000") 3730 3731 // Ensure that both direct and indirect deps are copied into apex 3732 ensureContains(t, copyCmds, "image.apex/lib64/mylib_common.so") 3733 3734 // Ensure that the platform variant ends with _shared 3735 ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared") 3736 3737 if !ctx.ModuleForTests("mylib_common", "android_arm64_armv8-a_shared_apex10000").Module().(*cc.Module).InAnyApex() { 3738 t.Log("Found mylib_common not in any apex!") 3739 t.Fail() 3740 } 3741} 3742 3743func TestTestApex(t *testing.T) { 3744 ctx := testApex(t, ` 3745 apex_test { 3746 name: "myapex", 3747 key: "myapex.key", 3748 native_shared_libs: ["mylib_common_test"], 3749 updatable: false, 3750 } 3751 3752 apex_key { 3753 name: "myapex.key", 3754 public_key: "testkey.avbpubkey", 3755 private_key: "testkey.pem", 3756 } 3757 3758 cc_library { 3759 name: "mylib_common_test", 3760 srcs: ["mylib.cpp"], 3761 system_shared_libs: [], 3762 stl: "none", 3763 // TODO: remove //apex_available:platform 3764 apex_available: [ 3765 "//apex_available:platform", 3766 "myapex", 3767 ], 3768 } 3769 `) 3770 3771 module := ctx.ModuleForTests("myapex", "android_common_myapex_image") 3772 apexRule := module.Rule("apexRule") 3773 copyCmds := apexRule.Args["copy_commands"] 3774 3775 if apex, ok := module.Module().(*apexBundle); !ok || !apex.testApex { 3776 t.Log("Apex was not a test apex!") 3777 t.Fail() 3778 } 3779 // Ensure that main rule creates an output 3780 ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned") 3781 3782 // Ensure that apex variant is created for the direct dep 3783 ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common_test"), "android_arm64_armv8-a_shared_apex10000") 3784 3785 // Ensure that both direct and indirect deps are copied into apex 3786 ensureContains(t, copyCmds, "image.apex/lib64/mylib_common_test.so") 3787 3788 // Ensure that the platform variant ends with _shared 3789 ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common_test"), "android_arm64_armv8-a_shared") 3790} 3791 3792func TestApexWithTarget(t *testing.T) { 3793 ctx := testApex(t, ` 3794 apex { 3795 name: "myapex", 3796 key: "myapex.key", 3797 updatable: false, 3798 multilib: { 3799 first: { 3800 native_shared_libs: ["mylib_common"], 3801 } 3802 }, 3803 target: { 3804 android: { 3805 multilib: { 3806 first: { 3807 native_shared_libs: ["mylib"], 3808 } 3809 } 3810 }, 3811 host: { 3812 multilib: { 3813 first: { 3814 native_shared_libs: ["mylib2"], 3815 } 3816 } 3817 } 3818 } 3819 } 3820 3821 apex_key { 3822 name: "myapex.key", 3823 public_key: "testkey.avbpubkey", 3824 private_key: "testkey.pem", 3825 } 3826 3827 cc_library { 3828 name: "mylib", 3829 srcs: ["mylib.cpp"], 3830 system_shared_libs: [], 3831 stl: "none", 3832 // TODO: remove //apex_available:platform 3833 apex_available: [ 3834 "//apex_available:platform", 3835 "myapex", 3836 ], 3837 } 3838 3839 cc_library { 3840 name: "mylib_common", 3841 srcs: ["mylib.cpp"], 3842 system_shared_libs: [], 3843 stl: "none", 3844 compile_multilib: "first", 3845 // TODO: remove //apex_available:platform 3846 apex_available: [ 3847 "//apex_available:platform", 3848 "myapex", 3849 ], 3850 } 3851 3852 cc_library { 3853 name: "mylib2", 3854 srcs: ["mylib.cpp"], 3855 system_shared_libs: [], 3856 stl: "none", 3857 compile_multilib: "first", 3858 } 3859 `) 3860 3861 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule") 3862 copyCmds := apexRule.Args["copy_commands"] 3863 3864 // Ensure that main rule creates an output 3865 ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned") 3866 3867 // Ensure that apex variant is created for the direct dep 3868 ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_apex10000") 3869 ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared_apex10000") 3870 ensureListNotContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_apex10000") 3871 3872 // Ensure that both direct and indirect deps are copied into apex 3873 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") 3874 ensureContains(t, copyCmds, "image.apex/lib64/mylib_common.so") 3875 ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so") 3876 3877 // Ensure that the platform variant ends with _shared 3878 ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared") 3879 ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared") 3880 ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared") 3881} 3882 3883func TestApexWithArch(t *testing.T) { 3884 ctx := testApex(t, ` 3885 apex { 3886 name: "myapex", 3887 key: "myapex.key", 3888 updatable: false, 3889 arch: { 3890 arm64: { 3891 native_shared_libs: ["mylib.arm64"], 3892 }, 3893 x86_64: { 3894 native_shared_libs: ["mylib.x64"], 3895 }, 3896 } 3897 } 3898 3899 apex_key { 3900 name: "myapex.key", 3901 public_key: "testkey.avbpubkey", 3902 private_key: "testkey.pem", 3903 } 3904 3905 cc_library { 3906 name: "mylib.arm64", 3907 srcs: ["mylib.cpp"], 3908 system_shared_libs: [], 3909 stl: "none", 3910 // TODO: remove //apex_available:platform 3911 apex_available: [ 3912 "//apex_available:platform", 3913 "myapex", 3914 ], 3915 } 3916 3917 cc_library { 3918 name: "mylib.x64", 3919 srcs: ["mylib.cpp"], 3920 system_shared_libs: [], 3921 stl: "none", 3922 // TODO: remove //apex_available:platform 3923 apex_available: [ 3924 "//apex_available:platform", 3925 "myapex", 3926 ], 3927 } 3928 `) 3929 3930 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule") 3931 copyCmds := apexRule.Args["copy_commands"] 3932 3933 // Ensure that apex variant is created for the direct dep 3934 ensureListContains(t, ctx.ModuleVariantsForTests("mylib.arm64"), "android_arm64_armv8-a_shared_apex10000") 3935 ensureListNotContains(t, ctx.ModuleVariantsForTests("mylib.x64"), "android_arm64_armv8-a_shared_apex10000") 3936 3937 // Ensure that both direct and indirect deps are copied into apex 3938 ensureContains(t, copyCmds, "image.apex/lib64/mylib.arm64.so") 3939 ensureNotContains(t, copyCmds, "image.apex/lib64/mylib.x64.so") 3940} 3941 3942func TestApexWithShBinary(t *testing.T) { 3943 ctx := testApex(t, ` 3944 apex { 3945 name: "myapex", 3946 key: "myapex.key", 3947 binaries: ["myscript"], 3948 updatable: false, 3949 } 3950 3951 apex_key { 3952 name: "myapex.key", 3953 public_key: "testkey.avbpubkey", 3954 private_key: "testkey.pem", 3955 } 3956 3957 sh_binary { 3958 name: "myscript", 3959 src: "mylib.cpp", 3960 filename: "myscript.sh", 3961 sub_dir: "script", 3962 } 3963 `) 3964 3965 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule") 3966 copyCmds := apexRule.Args["copy_commands"] 3967 3968 ensureContains(t, copyCmds, "image.apex/bin/script/myscript.sh") 3969} 3970 3971func TestApexInVariousPartition(t *testing.T) { 3972 testcases := []struct { 3973 propName, parition, flattenedPartition string 3974 }{ 3975 {"", "system", "system_ext"}, 3976 {"product_specific: true", "product", "product"}, 3977 {"soc_specific: true", "vendor", "vendor"}, 3978 {"proprietary: true", "vendor", "vendor"}, 3979 {"vendor: true", "vendor", "vendor"}, 3980 {"system_ext_specific: true", "system_ext", "system_ext"}, 3981 } 3982 for _, tc := range testcases { 3983 t.Run(tc.propName+":"+tc.parition, func(t *testing.T) { 3984 ctx := testApex(t, ` 3985 apex { 3986 name: "myapex", 3987 key: "myapex.key", 3988 updatable: false, 3989 `+tc.propName+` 3990 } 3991 3992 apex_key { 3993 name: "myapex.key", 3994 public_key: "testkey.avbpubkey", 3995 private_key: "testkey.pem", 3996 } 3997 `) 3998 3999 apex := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle) 4000 expected := "out/soong/target/product/test_device/" + tc.parition + "/apex" 4001 actual := apex.installDir.RelativeToTop().String() 4002 if actual != expected { 4003 t.Errorf("wrong install path. expected %q. actual %q", expected, actual) 4004 } 4005 4006 flattened := ctx.ModuleForTests("myapex", "android_common_myapex_flattened").Module().(*apexBundle) 4007 expected = "out/soong/target/product/test_device/" + tc.flattenedPartition + "/apex" 4008 actual = flattened.installDir.RelativeToTop().String() 4009 if actual != expected { 4010 t.Errorf("wrong install path. expected %q. actual %q", expected, actual) 4011 } 4012 }) 4013 } 4014} 4015 4016func TestFileContexts_FindInDefaultLocationIfNotSet(t *testing.T) { 4017 ctx := testApex(t, ` 4018 apex { 4019 name: "myapex", 4020 key: "myapex.key", 4021 updatable: false, 4022 } 4023 4024 apex_key { 4025 name: "myapex.key", 4026 public_key: "testkey.avbpubkey", 4027 private_key: "testkey.pem", 4028 } 4029 `) 4030 module := ctx.ModuleForTests("myapex", "android_common_myapex_image") 4031 rule := module.Output("file_contexts") 4032 ensureContains(t, rule.RuleParams.Command, "cat system/sepolicy/apex/myapex-file_contexts") 4033} 4034 4035func TestFileContexts_ShouldBeUnderSystemSepolicyForSystemApexes(t *testing.T) { 4036 testApexError(t, `"myapex" .*: file_contexts: should be under system/sepolicy`, ` 4037 apex { 4038 name: "myapex", 4039 key: "myapex.key", 4040 file_contexts: "my_own_file_contexts", 4041 updatable: false, 4042 } 4043 4044 apex_key { 4045 name: "myapex.key", 4046 public_key: "testkey.avbpubkey", 4047 private_key: "testkey.pem", 4048 } 4049 `, withFiles(map[string][]byte{ 4050 "my_own_file_contexts": nil, 4051 })) 4052} 4053 4054func TestFileContexts_ProductSpecificApexes(t *testing.T) { 4055 testApexError(t, `"myapex" .*: file_contexts: cannot find`, ` 4056 apex { 4057 name: "myapex", 4058 key: "myapex.key", 4059 product_specific: true, 4060 file_contexts: "product_specific_file_contexts", 4061 updatable: false, 4062 } 4063 4064 apex_key { 4065 name: "myapex.key", 4066 public_key: "testkey.avbpubkey", 4067 private_key: "testkey.pem", 4068 } 4069 `) 4070 4071 ctx := testApex(t, ` 4072 apex { 4073 name: "myapex", 4074 key: "myapex.key", 4075 product_specific: true, 4076 file_contexts: "product_specific_file_contexts", 4077 updatable: false, 4078 } 4079 4080 apex_key { 4081 name: "myapex.key", 4082 public_key: "testkey.avbpubkey", 4083 private_key: "testkey.pem", 4084 } 4085 `, withFiles(map[string][]byte{ 4086 "product_specific_file_contexts": nil, 4087 })) 4088 module := ctx.ModuleForTests("myapex", "android_common_myapex_image") 4089 rule := module.Output("file_contexts") 4090 ensureContains(t, rule.RuleParams.Command, "cat product_specific_file_contexts") 4091} 4092 4093func TestFileContexts_SetViaFileGroup(t *testing.T) { 4094 ctx := testApex(t, ` 4095 apex { 4096 name: "myapex", 4097 key: "myapex.key", 4098 product_specific: true, 4099 file_contexts: ":my-file-contexts", 4100 updatable: false, 4101 } 4102 4103 apex_key { 4104 name: "myapex.key", 4105 public_key: "testkey.avbpubkey", 4106 private_key: "testkey.pem", 4107 } 4108 4109 filegroup { 4110 name: "my-file-contexts", 4111 srcs: ["product_specific_file_contexts"], 4112 } 4113 `, withFiles(map[string][]byte{ 4114 "product_specific_file_contexts": nil, 4115 })) 4116 module := ctx.ModuleForTests("myapex", "android_common_myapex_image") 4117 rule := module.Output("file_contexts") 4118 ensureContains(t, rule.RuleParams.Command, "cat product_specific_file_contexts") 4119} 4120 4121func TestApexKeyFromOtherModule(t *testing.T) { 4122 ctx := testApex(t, ` 4123 apex_key { 4124 name: "myapex.key", 4125 public_key: ":my.avbpubkey", 4126 private_key: ":my.pem", 4127 product_specific: true, 4128 } 4129 4130 filegroup { 4131 name: "my.avbpubkey", 4132 srcs: ["testkey2.avbpubkey"], 4133 } 4134 4135 filegroup { 4136 name: "my.pem", 4137 srcs: ["testkey2.pem"], 4138 } 4139 `) 4140 4141 apex_key := ctx.ModuleForTests("myapex.key", "android_common").Module().(*apexKey) 4142 expected_pubkey := "testkey2.avbpubkey" 4143 actual_pubkey := apex_key.publicKeyFile.String() 4144 if actual_pubkey != expected_pubkey { 4145 t.Errorf("wrong public key path. expected %q. actual %q", expected_pubkey, actual_pubkey) 4146 } 4147 expected_privkey := "testkey2.pem" 4148 actual_privkey := apex_key.privateKeyFile.String() 4149 if actual_privkey != expected_privkey { 4150 t.Errorf("wrong private key path. expected %q. actual %q", expected_privkey, actual_privkey) 4151 } 4152} 4153 4154func TestPrebuilt(t *testing.T) { 4155 ctx := testApex(t, ` 4156 prebuilt_apex { 4157 name: "myapex", 4158 arch: { 4159 arm64: { 4160 src: "myapex-arm64.apex", 4161 }, 4162 arm: { 4163 src: "myapex-arm.apex", 4164 }, 4165 }, 4166 } 4167 `) 4168 4169 prebuilt := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*Prebuilt) 4170 4171 expectedInput := "myapex-arm64.apex" 4172 if prebuilt.inputApex.String() != expectedInput { 4173 t.Errorf("inputApex invalid. expected: %q, actual: %q", expectedInput, prebuilt.inputApex.String()) 4174 } 4175} 4176 4177func TestPrebuiltMissingSrc(t *testing.T) { 4178 testApexError(t, `module "myapex" variant "android_common_myapex".*: prebuilt_apex does not support "arm64_armv8-a"`, ` 4179 prebuilt_apex { 4180 name: "myapex", 4181 } 4182 `) 4183} 4184 4185func TestPrebuiltFilenameOverride(t *testing.T) { 4186 ctx := testApex(t, ` 4187 prebuilt_apex { 4188 name: "myapex", 4189 src: "myapex-arm.apex", 4190 filename: "notmyapex.apex", 4191 } 4192 `) 4193 4194 p := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*Prebuilt) 4195 4196 expected := "notmyapex.apex" 4197 if p.installFilename != expected { 4198 t.Errorf("installFilename invalid. expected: %q, actual: %q", expected, p.installFilename) 4199 } 4200} 4201 4202func TestPrebuiltOverrides(t *testing.T) { 4203 ctx := testApex(t, ` 4204 prebuilt_apex { 4205 name: "myapex.prebuilt", 4206 src: "myapex-arm.apex", 4207 overrides: [ 4208 "myapex", 4209 ], 4210 } 4211 `) 4212 4213 p := ctx.ModuleForTests("myapex.prebuilt", "android_common_myapex.prebuilt").Module().(*Prebuilt) 4214 4215 expected := []string{"myapex"} 4216 actual := android.AndroidMkEntriesForTest(t, ctx, p)[0].EntryMap["LOCAL_OVERRIDES_MODULES"] 4217 if !reflect.DeepEqual(actual, expected) { 4218 t.Errorf("Incorrect LOCAL_OVERRIDES_MODULES value '%s', expected '%s'", actual, expected) 4219 } 4220} 4221 4222func TestPrebuiltApexName(t *testing.T) { 4223 testApex(t, ` 4224 prebuilt_apex { 4225 name: "com.company.android.myapex", 4226 apex_name: "com.android.myapex", 4227 src: "company-myapex-arm.apex", 4228 } 4229 `).ModuleForTests("com.company.android.myapex", "android_common_com.android.myapex") 4230 4231 testApex(t, ` 4232 apex_set { 4233 name: "com.company.android.myapex", 4234 apex_name: "com.android.myapex", 4235 set: "company-myapex.apks", 4236 } 4237 `).ModuleForTests("com.company.android.myapex", "android_common_com.android.myapex") 4238} 4239 4240func TestPrebuiltApexNameWithPlatformBootclasspath(t *testing.T) { 4241 _ = android.GroupFixturePreparers( 4242 java.PrepareForTestWithJavaDefaultModules, 4243 PrepareForTestWithApexBuildComponents, 4244 android.FixtureWithRootAndroidBp(` 4245 platform_bootclasspath { 4246 name: "platform-bootclasspath", 4247 fragments: [ 4248 { 4249 apex: "com.android.art", 4250 module: "art-bootclasspath-fragment", 4251 }, 4252 ], 4253 } 4254 4255 prebuilt_apex { 4256 name: "com.company.android.art", 4257 apex_name: "com.android.art", 4258 src: "com.company.android.art-arm.apex", 4259 exported_bootclasspath_fragments: ["art-bootclasspath-fragment"], 4260 } 4261 4262 prebuilt_bootclasspath_fragment { 4263 name: "art-bootclasspath-fragment", 4264 contents: ["core-oj"], 4265 } 4266 4267 java_import { 4268 name: "core-oj", 4269 jars: ["prebuilt.jar"], 4270 } 4271 `), 4272 ).RunTest(t) 4273} 4274 4275// These tests verify that the prebuilt_apex/deapexer to java_import wiring allows for the 4276// propagation of paths to dex implementation jars from the former to the latter. 4277func TestPrebuiltExportDexImplementationJars(t *testing.T) { 4278 transform := android.NullFixturePreparer 4279 4280 checkDexJarBuildPath := func(t *testing.T, ctx *android.TestContext, name string) { 4281 // Make sure the import has been given the correct path to the dex jar. 4282 p := ctx.ModuleForTests(name, "android_common_myapex").Module().(java.UsesLibraryDependency) 4283 dexJarBuildPath := p.DexJarBuildPath() 4284 stem := android.RemoveOptionalPrebuiltPrefix(name) 4285 if expected, actual := ".intermediates/myapex.deapexer/android_common/deapexer/javalib/"+stem+".jar", android.NormalizePathForTesting(dexJarBuildPath); actual != expected { 4286 t.Errorf("Incorrect DexJarBuildPath value '%s', expected '%s'", actual, expected) 4287 } 4288 } 4289 4290 ensureNoSourceVariant := func(t *testing.T, ctx *android.TestContext, name string) { 4291 // Make sure that an apex variant is not created for the source module. 4292 if expected, actual := []string{"android_common"}, ctx.ModuleVariantsForTests(name); !reflect.DeepEqual(expected, actual) { 4293 t.Errorf("invalid set of variants for %q: expected %q, found %q", "libfoo", expected, actual) 4294 } 4295 } 4296 4297 t.Run("prebuilt only", func(t *testing.T) { 4298 bp := ` 4299 prebuilt_apex { 4300 name: "myapex", 4301 arch: { 4302 arm64: { 4303 src: "myapex-arm64.apex", 4304 }, 4305 arm: { 4306 src: "myapex-arm.apex", 4307 }, 4308 }, 4309 exported_java_libs: ["libfoo", "libbar"], 4310 } 4311 4312 java_import { 4313 name: "libfoo", 4314 jars: ["libfoo.jar"], 4315 } 4316 4317 java_sdk_library_import { 4318 name: "libbar", 4319 public: { 4320 jars: ["libbar.jar"], 4321 }, 4322 } 4323 ` 4324 4325 // Make sure that dexpreopt can access dex implementation files from the prebuilt. 4326 ctx := testDexpreoptWithApexes(t, bp, "", transform) 4327 4328 // Make sure that the deapexer has the correct input APEX. 4329 deapexer := ctx.ModuleForTests("myapex.deapexer", "android_common") 4330 rule := deapexer.Rule("deapexer") 4331 if expected, actual := []string{"myapex-arm64.apex"}, android.NormalizePathsForTesting(rule.Implicits); !reflect.DeepEqual(expected, actual) { 4332 t.Errorf("expected: %q, found: %q", expected, actual) 4333 } 4334 4335 // Make sure that the prebuilt_apex has the correct input APEX. 4336 prebuiltApex := ctx.ModuleForTests("myapex", "android_common_myapex") 4337 rule = prebuiltApex.Rule("android/soong/android.Cp") 4338 if expected, actual := "myapex-arm64.apex", android.NormalizePathForTesting(rule.Input); !reflect.DeepEqual(expected, actual) { 4339 t.Errorf("expected: %q, found: %q", expected, actual) 4340 } 4341 4342 checkDexJarBuildPath(t, ctx, "libfoo") 4343 4344 checkDexJarBuildPath(t, ctx, "libbar") 4345 }) 4346 4347 t.Run("prebuilt with source preferred", func(t *testing.T) { 4348 4349 bp := ` 4350 prebuilt_apex { 4351 name: "myapex", 4352 arch: { 4353 arm64: { 4354 src: "myapex-arm64.apex", 4355 }, 4356 arm: { 4357 src: "myapex-arm.apex", 4358 }, 4359 }, 4360 exported_java_libs: ["libfoo", "libbar"], 4361 } 4362 4363 java_import { 4364 name: "libfoo", 4365 jars: ["libfoo.jar"], 4366 } 4367 4368 java_library { 4369 name: "libfoo", 4370 } 4371 4372 java_sdk_library_import { 4373 name: "libbar", 4374 public: { 4375 jars: ["libbar.jar"], 4376 }, 4377 } 4378 4379 java_sdk_library { 4380 name: "libbar", 4381 srcs: ["foo/bar/MyClass.java"], 4382 unsafe_ignore_missing_latest_api: true, 4383 } 4384 ` 4385 4386 // Make sure that dexpreopt can access dex implementation files from the prebuilt. 4387 ctx := testDexpreoptWithApexes(t, bp, "", transform) 4388 4389 checkDexJarBuildPath(t, ctx, "prebuilt_libfoo") 4390 ensureNoSourceVariant(t, ctx, "libfoo") 4391 4392 checkDexJarBuildPath(t, ctx, "prebuilt_libbar") 4393 ensureNoSourceVariant(t, ctx, "libbar") 4394 }) 4395 4396 t.Run("prebuilt preferred with source", func(t *testing.T) { 4397 bp := ` 4398 prebuilt_apex { 4399 name: "myapex", 4400 arch: { 4401 arm64: { 4402 src: "myapex-arm64.apex", 4403 }, 4404 arm: { 4405 src: "myapex-arm.apex", 4406 }, 4407 }, 4408 exported_java_libs: ["libfoo", "libbar"], 4409 } 4410 4411 java_import { 4412 name: "libfoo", 4413 prefer: true, 4414 jars: ["libfoo.jar"], 4415 } 4416 4417 java_library { 4418 name: "libfoo", 4419 } 4420 4421 java_sdk_library_import { 4422 name: "libbar", 4423 prefer: true, 4424 public: { 4425 jars: ["libbar.jar"], 4426 }, 4427 } 4428 4429 java_sdk_library { 4430 name: "libbar", 4431 srcs: ["foo/bar/MyClass.java"], 4432 unsafe_ignore_missing_latest_api: true, 4433 } 4434 ` 4435 4436 // Make sure that dexpreopt can access dex implementation files from the prebuilt. 4437 ctx := testDexpreoptWithApexes(t, bp, "", transform) 4438 4439 checkDexJarBuildPath(t, ctx, "prebuilt_libfoo") 4440 ensureNoSourceVariant(t, ctx, "libfoo") 4441 4442 checkDexJarBuildPath(t, ctx, "prebuilt_libbar") 4443 ensureNoSourceVariant(t, ctx, "libbar") 4444 }) 4445} 4446 4447func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { 4448 preparer := android.GroupFixturePreparers( 4449 java.FixtureConfigureBootJars("myapex:libfoo", "myapex:libbar"), 4450 // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding 4451 // is disabled. 4452 android.FixtureAddTextFile("frameworks/base/Android.bp", ""), 4453 ) 4454 4455 checkBootDexJarPath := func(t *testing.T, ctx *android.TestContext, stem string, bootDexJarPath string) { 4456 t.Helper() 4457 s := ctx.ModuleForTests("platform-bootclasspath", "android_common") 4458 foundLibfooJar := false 4459 base := stem + ".jar" 4460 for _, output := range s.AllOutputs() { 4461 if filepath.Base(output) == base { 4462 foundLibfooJar = true 4463 buildRule := s.Output(output) 4464 android.AssertStringEquals(t, "boot dex jar path", bootDexJarPath, buildRule.Input.String()) 4465 } 4466 } 4467 if !foundLibfooJar { 4468 t.Errorf("Rule for libfoo.jar missing in dex_bootjars singleton outputs %q", android.StringPathsRelativeToTop(ctx.Config().BuildDir(), s.AllOutputs())) 4469 } 4470 } 4471 4472 checkHiddenAPIIndexInputs := func(t *testing.T, ctx *android.TestContext, expectedIntermediateInputs string) { 4473 t.Helper() 4474 platformBootclasspath := ctx.ModuleForTests("platform-bootclasspath", "android_common") 4475 var rule android.TestingBuildParams 4476 4477 rule = platformBootclasspath.Output("hiddenapi-monolithic/index-from-classes.csv") 4478 java.CheckHiddenAPIRuleInputs(t, "intermediate index", expectedIntermediateInputs, rule) 4479 } 4480 4481 fragment := java.ApexVariantReference{ 4482 Apex: proptools.StringPtr("myapex"), 4483 Module: proptools.StringPtr("my-bootclasspath-fragment"), 4484 } 4485 4486 t.Run("prebuilt only", func(t *testing.T) { 4487 bp := ` 4488 prebuilt_apex { 4489 name: "myapex", 4490 arch: { 4491 arm64: { 4492 src: "myapex-arm64.apex", 4493 }, 4494 arm: { 4495 src: "myapex-arm.apex", 4496 }, 4497 }, 4498 exported_bootclasspath_fragments: ["my-bootclasspath-fragment"], 4499 } 4500 4501 prebuilt_bootclasspath_fragment { 4502 name: "my-bootclasspath-fragment", 4503 contents: ["libfoo", "libbar"], 4504 apex_available: ["myapex"], 4505 } 4506 4507 java_import { 4508 name: "libfoo", 4509 jars: ["libfoo.jar"], 4510 apex_available: ["myapex"], 4511 } 4512 4513 java_sdk_library_import { 4514 name: "libbar", 4515 public: { 4516 jars: ["libbar.jar"], 4517 }, 4518 apex_available: ["myapex"], 4519 shared_library: false, 4520 } 4521 ` 4522 4523 ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment) 4524 checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar") 4525 checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar") 4526 4527 // Verify the correct module jars contribute to the hiddenapi index file. 4528 checkHiddenAPIIndexInputs(t, ctx, ` 4529 out/soong/.intermediates/libbar.stubs/android_common/combined/libbar.stubs.jar 4530 out/soong/.intermediates/libfoo/android_common_myapex/combined/libfoo.jar 4531 `) 4532 }) 4533 4534 t.Run("apex_set only", func(t *testing.T) { 4535 bp := ` 4536 apex_set { 4537 name: "myapex", 4538 set: "myapex.apks", 4539 exported_bootclasspath_fragments: ["my-bootclasspath-fragment"], 4540 } 4541 4542 prebuilt_bootclasspath_fragment { 4543 name: "my-bootclasspath-fragment", 4544 contents: ["libfoo", "libbar"], 4545 apex_available: ["myapex"], 4546 } 4547 4548 java_import { 4549 name: "libfoo", 4550 jars: ["libfoo.jar"], 4551 apex_available: ["myapex"], 4552 } 4553 4554 java_sdk_library_import { 4555 name: "libbar", 4556 public: { 4557 jars: ["libbar.jar"], 4558 }, 4559 apex_available: ["myapex"], 4560 shared_library: false, 4561 } 4562 ` 4563 4564 ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment) 4565 checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar") 4566 checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar") 4567 4568 // Verify the correct module jars contribute to the hiddenapi index file. 4569 checkHiddenAPIIndexInputs(t, ctx, ` 4570 out/soong/.intermediates/libbar.stubs/android_common/combined/libbar.stubs.jar 4571 out/soong/.intermediates/libfoo/android_common_myapex/combined/libfoo.jar 4572 `) 4573 }) 4574 4575 t.Run("prebuilt with source library preferred", func(t *testing.T) { 4576 bp := ` 4577 prebuilt_apex { 4578 name: "myapex", 4579 arch: { 4580 arm64: { 4581 src: "myapex-arm64.apex", 4582 }, 4583 arm: { 4584 src: "myapex-arm.apex", 4585 }, 4586 }, 4587 exported_bootclasspath_fragments: ["my-bootclasspath-fragment"], 4588 } 4589 4590 prebuilt_bootclasspath_fragment { 4591 name: "my-bootclasspath-fragment", 4592 contents: ["libfoo", "libbar"], 4593 apex_available: ["myapex"], 4594 } 4595 4596 java_import { 4597 name: "libfoo", 4598 jars: ["libfoo.jar"], 4599 apex_available: ["myapex"], 4600 } 4601 4602 java_library { 4603 name: "libfoo", 4604 srcs: ["foo/bar/MyClass.java"], 4605 apex_available: ["myapex"], 4606 } 4607 4608 java_sdk_library_import { 4609 name: "libbar", 4610 public: { 4611 jars: ["libbar.jar"], 4612 }, 4613 apex_available: ["myapex"], 4614 shared_library: false, 4615 } 4616 4617 java_sdk_library { 4618 name: "libbar", 4619 srcs: ["foo/bar/MyClass.java"], 4620 unsafe_ignore_missing_latest_api: true, 4621 apex_available: ["myapex"], 4622 } 4623 ` 4624 4625 // In this test the source (java_library) libfoo is active since the 4626 // prebuilt (java_import) defaults to prefer:false. However the 4627 // prebuilt_apex module always depends on the prebuilt, and so it doesn't 4628 // find the dex boot jar in it. We either need to disable the source libfoo 4629 // or make the prebuilt libfoo preferred. 4630 testDexpreoptWithApexes(t, bp, "module libfoo does not provide a dex boot jar", preparer, fragment) 4631 }) 4632 4633 t.Run("prebuilt library preferred with source", func(t *testing.T) { 4634 bp := ` 4635 prebuilt_apex { 4636 name: "myapex", 4637 arch: { 4638 arm64: { 4639 src: "myapex-arm64.apex", 4640 }, 4641 arm: { 4642 src: "myapex-arm.apex", 4643 }, 4644 }, 4645 exported_bootclasspath_fragments: ["my-bootclasspath-fragment"], 4646 } 4647 4648 prebuilt_bootclasspath_fragment { 4649 name: "my-bootclasspath-fragment", 4650 contents: ["libfoo", "libbar"], 4651 apex_available: ["myapex"], 4652 } 4653 4654 java_import { 4655 name: "libfoo", 4656 prefer: true, 4657 jars: ["libfoo.jar"], 4658 apex_available: ["myapex"], 4659 } 4660 4661 java_library { 4662 name: "libfoo", 4663 srcs: ["foo/bar/MyClass.java"], 4664 apex_available: ["myapex"], 4665 } 4666 4667 java_sdk_library_import { 4668 name: "libbar", 4669 prefer: true, 4670 public: { 4671 jars: ["libbar.jar"], 4672 }, 4673 apex_available: ["myapex"], 4674 shared_library: false, 4675 } 4676 4677 java_sdk_library { 4678 name: "libbar", 4679 srcs: ["foo/bar/MyClass.java"], 4680 unsafe_ignore_missing_latest_api: true, 4681 apex_available: ["myapex"], 4682 } 4683 ` 4684 4685 ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment) 4686 checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar") 4687 checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar") 4688 4689 // Verify the correct module jars contribute to the hiddenapi index file. 4690 checkHiddenAPIIndexInputs(t, ctx, ` 4691 out/soong/.intermediates/prebuilt_libbar.stubs/android_common/combined/libbar.stubs.jar 4692 out/soong/.intermediates/prebuilt_libfoo/android_common_myapex/combined/libfoo.jar 4693 `) 4694 }) 4695 4696 t.Run("prebuilt with source apex preferred", func(t *testing.T) { 4697 bp := ` 4698 apex { 4699 name: "myapex", 4700 key: "myapex.key", 4701 java_libs: ["libfoo", "libbar"], 4702 updatable: false, 4703 } 4704 4705 apex_key { 4706 name: "myapex.key", 4707 public_key: "testkey.avbpubkey", 4708 private_key: "testkey.pem", 4709 } 4710 4711 prebuilt_apex { 4712 name: "myapex", 4713 arch: { 4714 arm64: { 4715 src: "myapex-arm64.apex", 4716 }, 4717 arm: { 4718 src: "myapex-arm.apex", 4719 }, 4720 }, 4721 exported_bootclasspath_fragments: ["my-bootclasspath-fragment"], 4722 } 4723 4724 prebuilt_bootclasspath_fragment { 4725 name: "my-bootclasspath-fragment", 4726 contents: ["libfoo", "libbar"], 4727 apex_available: ["myapex"], 4728 } 4729 4730 java_import { 4731 name: "libfoo", 4732 jars: ["libfoo.jar"], 4733 apex_available: ["myapex"], 4734 } 4735 4736 java_library { 4737 name: "libfoo", 4738 srcs: ["foo/bar/MyClass.java"], 4739 apex_available: ["myapex"], 4740 } 4741 4742 java_sdk_library_import { 4743 name: "libbar", 4744 public: { 4745 jars: ["libbar.jar"], 4746 }, 4747 apex_available: ["myapex"], 4748 shared_library: false, 4749 } 4750 4751 java_sdk_library { 4752 name: "libbar", 4753 srcs: ["foo/bar/MyClass.java"], 4754 unsafe_ignore_missing_latest_api: true, 4755 apex_available: ["myapex"], 4756 } 4757 ` 4758 4759 ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment) 4760 checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/libfoo/android_common_apex10000/hiddenapi/libfoo.jar") 4761 checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/libbar/android_common_myapex/hiddenapi/libbar.jar") 4762 4763 // Verify the correct module jars contribute to the hiddenapi index file. 4764 checkHiddenAPIIndexInputs(t, ctx, ` 4765 out/soong/.intermediates/libbar/android_common_myapex/javac/libbar.jar 4766 out/soong/.intermediates/libfoo/android_common_apex10000/javac/libfoo.jar 4767 `) 4768 }) 4769 4770 t.Run("prebuilt preferred with source apex disabled", func(t *testing.T) { 4771 bp := ` 4772 apex { 4773 name: "myapex", 4774 enabled: false, 4775 key: "myapex.key", 4776 java_libs: ["libfoo", "libbar"], 4777 } 4778 4779 apex_key { 4780 name: "myapex.key", 4781 public_key: "testkey.avbpubkey", 4782 private_key: "testkey.pem", 4783 } 4784 4785 prebuilt_apex { 4786 name: "myapex", 4787 arch: { 4788 arm64: { 4789 src: "myapex-arm64.apex", 4790 }, 4791 arm: { 4792 src: "myapex-arm.apex", 4793 }, 4794 }, 4795 exported_bootclasspath_fragments: ["my-bootclasspath-fragment"], 4796 } 4797 4798 prebuilt_bootclasspath_fragment { 4799 name: "my-bootclasspath-fragment", 4800 contents: ["libfoo", "libbar"], 4801 apex_available: ["myapex"], 4802 } 4803 4804 java_import { 4805 name: "libfoo", 4806 prefer: true, 4807 jars: ["libfoo.jar"], 4808 apex_available: ["myapex"], 4809 } 4810 4811 java_library { 4812 name: "libfoo", 4813 srcs: ["foo/bar/MyClass.java"], 4814 apex_available: ["myapex"], 4815 } 4816 4817 java_sdk_library_import { 4818 name: "libbar", 4819 prefer: true, 4820 public: { 4821 jars: ["libbar.jar"], 4822 }, 4823 apex_available: ["myapex"], 4824 shared_library: false, 4825 } 4826 4827 java_sdk_library { 4828 name: "libbar", 4829 srcs: ["foo/bar/MyClass.java"], 4830 unsafe_ignore_missing_latest_api: true, 4831 apex_available: ["myapex"], 4832 } 4833 ` 4834 4835 ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment) 4836 checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar") 4837 checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar") 4838 4839 // Verify the correct module jars contribute to the hiddenapi index file. 4840 checkHiddenAPIIndexInputs(t, ctx, ` 4841 out/soong/.intermediates/prebuilt_libbar.stubs/android_common/combined/libbar.stubs.jar 4842 out/soong/.intermediates/prebuilt_libfoo/android_common_myapex/combined/libfoo.jar 4843 `) 4844 }) 4845} 4846 4847func TestApexWithTests(t *testing.T) { 4848 ctx := testApex(t, ` 4849 apex_test { 4850 name: "myapex", 4851 key: "myapex.key", 4852 updatable: false, 4853 tests: [ 4854 "mytest", 4855 "mytests", 4856 ], 4857 } 4858 4859 apex_key { 4860 name: "myapex.key", 4861 public_key: "testkey.avbpubkey", 4862 private_key: "testkey.pem", 4863 } 4864 4865 filegroup { 4866 name: "fg", 4867 srcs: [ 4868 "baz", 4869 "bar/baz" 4870 ], 4871 } 4872 4873 cc_test { 4874 name: "mytest", 4875 gtest: false, 4876 srcs: ["mytest.cpp"], 4877 relative_install_path: "test", 4878 shared_libs: ["mylib"], 4879 system_shared_libs: [], 4880 static_executable: true, 4881 stl: "none", 4882 data: [":fg"], 4883 } 4884 4885 cc_library { 4886 name: "mylib", 4887 srcs: ["mylib.cpp"], 4888 system_shared_libs: [], 4889 stl: "none", 4890 } 4891 4892 filegroup { 4893 name: "fg2", 4894 srcs: [ 4895 "testdata/baz" 4896 ], 4897 } 4898 4899 cc_test { 4900 name: "mytests", 4901 gtest: false, 4902 srcs: [ 4903 "mytest1.cpp", 4904 "mytest2.cpp", 4905 "mytest3.cpp", 4906 ], 4907 test_per_src: true, 4908 relative_install_path: "test", 4909 system_shared_libs: [], 4910 static_executable: true, 4911 stl: "none", 4912 data: [ 4913 ":fg", 4914 ":fg2", 4915 ], 4916 } 4917 `) 4918 4919 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule") 4920 copyCmds := apexRule.Args["copy_commands"] 4921 4922 // Ensure that test dep (and their transitive dependencies) are copied into apex. 4923 ensureContains(t, copyCmds, "image.apex/bin/test/mytest") 4924 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") 4925 4926 //Ensure that test data are copied into apex. 4927 ensureContains(t, copyCmds, "image.apex/bin/test/baz") 4928 ensureContains(t, copyCmds, "image.apex/bin/test/bar/baz") 4929 4930 // Ensure that test deps built with `test_per_src` are copied into apex. 4931 ensureContains(t, copyCmds, "image.apex/bin/test/mytest1") 4932 ensureContains(t, copyCmds, "image.apex/bin/test/mytest2") 4933 ensureContains(t, copyCmds, "image.apex/bin/test/mytest3") 4934 4935 // Ensure the module is correctly translated. 4936 bundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle) 4937 data := android.AndroidMkDataForTest(t, ctx, bundle) 4938 name := bundle.BaseModuleName() 4939 prefix := "TARGET_" 4940 var builder strings.Builder 4941 data.Custom(&builder, name, prefix, "", data) 4942 androidMk := builder.String() 4943 ensureContains(t, androidMk, "LOCAL_MODULE := mytest.myapex\n") 4944 ensureContains(t, androidMk, "LOCAL_MODULE := mytest1.myapex\n") 4945 ensureContains(t, androidMk, "LOCAL_MODULE := mytest2.myapex\n") 4946 ensureContains(t, androidMk, "LOCAL_MODULE := mytest3.myapex\n") 4947 ensureContains(t, androidMk, "LOCAL_MODULE := apex_manifest.pb.myapex\n") 4948 ensureContains(t, androidMk, "LOCAL_MODULE := apex_pubkey.myapex\n") 4949 ensureContains(t, androidMk, "LOCAL_MODULE := myapex\n") 4950 4951 flatBundle := ctx.ModuleForTests("myapex", "android_common_myapex_flattened").Module().(*apexBundle) 4952 data = android.AndroidMkDataForTest(t, ctx, flatBundle) 4953 data.Custom(&builder, name, prefix, "", data) 4954 flatAndroidMk := builder.String() 4955 ensureContainsOnce(t, flatAndroidMk, "LOCAL_TEST_DATA := :baz :bar/baz\n") 4956 ensureContainsOnce(t, flatAndroidMk, "LOCAL_TEST_DATA := :testdata/baz\n") 4957} 4958 4959func TestInstallExtraFlattenedApexes(t *testing.T) { 4960 ctx := testApex(t, ` 4961 apex { 4962 name: "myapex", 4963 key: "myapex.key", 4964 updatable: false, 4965 } 4966 apex_key { 4967 name: "myapex.key", 4968 public_key: "testkey.avbpubkey", 4969 private_key: "testkey.pem", 4970 } 4971 `, 4972 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 4973 variables.InstallExtraFlattenedApexes = proptools.BoolPtr(true) 4974 }), 4975 ) 4976 ab := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle) 4977 ensureListContains(t, ab.requiredDeps, "myapex.flattened") 4978 mk := android.AndroidMkDataForTest(t, ctx, ab) 4979 var builder strings.Builder 4980 mk.Custom(&builder, ab.Name(), "TARGET_", "", mk) 4981 androidMk := builder.String() 4982 ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += myapex.flattened") 4983} 4984 4985func TestErrorsIfDepsAreNotEnabled(t *testing.T) { 4986 testApexError(t, `module "myapex" .* depends on disabled module "libfoo"`, ` 4987 apex { 4988 name: "myapex", 4989 key: "myapex.key", 4990 native_shared_libs: ["libfoo"], 4991 } 4992 4993 apex_key { 4994 name: "myapex.key", 4995 public_key: "testkey.avbpubkey", 4996 private_key: "testkey.pem", 4997 } 4998 4999 cc_library { 5000 name: "libfoo", 5001 stl: "none", 5002 system_shared_libs: [], 5003 enabled: false, 5004 apex_available: ["myapex"], 5005 } 5006 `) 5007 testApexError(t, `module "myapex" .* depends on disabled module "myjar"`, ` 5008 apex { 5009 name: "myapex", 5010 key: "myapex.key", 5011 java_libs: ["myjar"], 5012 } 5013 5014 apex_key { 5015 name: "myapex.key", 5016 public_key: "testkey.avbpubkey", 5017 private_key: "testkey.pem", 5018 } 5019 5020 java_library { 5021 name: "myjar", 5022 srcs: ["foo/bar/MyClass.java"], 5023 sdk_version: "none", 5024 system_modules: "none", 5025 enabled: false, 5026 apex_available: ["myapex"], 5027 } 5028 `) 5029} 5030 5031func TestApexWithJavaImport(t *testing.T) { 5032 ctx := testApex(t, ` 5033 apex { 5034 name: "myapex", 5035 key: "myapex.key", 5036 java_libs: ["myjavaimport"], 5037 updatable: false, 5038 } 5039 5040 apex_key { 5041 name: "myapex.key", 5042 public_key: "testkey.avbpubkey", 5043 private_key: "testkey.pem", 5044 } 5045 5046 java_import { 5047 name: "myjavaimport", 5048 apex_available: ["myapex"], 5049 jars: ["my.jar"], 5050 compile_dex: true, 5051 } 5052 `) 5053 5054 module := ctx.ModuleForTests("myapex", "android_common_myapex_image") 5055 apexRule := module.Rule("apexRule") 5056 copyCmds := apexRule.Args["copy_commands"] 5057 ensureContains(t, copyCmds, "image.apex/javalib/myjavaimport.jar") 5058} 5059 5060func TestApexWithApps(t *testing.T) { 5061 ctx := testApex(t, ` 5062 apex { 5063 name: "myapex", 5064 key: "myapex.key", 5065 apps: [ 5066 "AppFoo", 5067 "AppFooPriv", 5068 ], 5069 updatable: false, 5070 } 5071 5072 apex_key { 5073 name: "myapex.key", 5074 public_key: "testkey.avbpubkey", 5075 private_key: "testkey.pem", 5076 } 5077 5078 android_app { 5079 name: "AppFoo", 5080 srcs: ["foo/bar/MyClass.java"], 5081 sdk_version: "current", 5082 system_modules: "none", 5083 jni_libs: ["libjni"], 5084 stl: "none", 5085 apex_available: [ "myapex" ], 5086 } 5087 5088 android_app { 5089 name: "AppFooPriv", 5090 srcs: ["foo/bar/MyClass.java"], 5091 sdk_version: "current", 5092 system_modules: "none", 5093 privileged: true, 5094 stl: "none", 5095 apex_available: [ "myapex" ], 5096 } 5097 5098 cc_library_shared { 5099 name: "libjni", 5100 srcs: ["mylib.cpp"], 5101 shared_libs: ["libfoo"], 5102 stl: "none", 5103 system_shared_libs: [], 5104 apex_available: [ "myapex" ], 5105 sdk_version: "current", 5106 } 5107 5108 cc_library_shared { 5109 name: "libfoo", 5110 stl: "none", 5111 system_shared_libs: [], 5112 apex_available: [ "myapex" ], 5113 sdk_version: "current", 5114 } 5115 `) 5116 5117 module := ctx.ModuleForTests("myapex", "android_common_myapex_image") 5118 apexRule := module.Rule("apexRule") 5119 copyCmds := apexRule.Args["copy_commands"] 5120 5121 ensureContains(t, copyCmds, "image.apex/app/AppFoo/AppFoo.apk") 5122 ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPriv/AppFooPriv.apk") 5123 5124 appZipRule := ctx.ModuleForTests("AppFoo", "android_common_apex10000").Description("zip jni libs") 5125 // JNI libraries are uncompressed 5126 if args := appZipRule.Args["jarArgs"]; !strings.Contains(args, "-L 0") { 5127 t.Errorf("jni libs are not uncompressed for AppFoo") 5128 } 5129 // JNI libraries including transitive deps are 5130 for _, jni := range []string{"libjni", "libfoo"} { 5131 jniOutput := ctx.ModuleForTests(jni, "android_arm64_armv8-a_sdk_shared_apex10000").Module().(*cc.Module).OutputFile().RelativeToTop() 5132 // ... embedded inside APK (jnilibs.zip) 5133 ensureListContains(t, appZipRule.Implicits.Strings(), jniOutput.String()) 5134 // ... and not directly inside the APEX 5135 ensureNotContains(t, copyCmds, "image.apex/lib64/"+jni+".so") 5136 } 5137} 5138 5139func TestApexWithAppImports(t *testing.T) { 5140 ctx := testApex(t, ` 5141 apex { 5142 name: "myapex", 5143 key: "myapex.key", 5144 apps: [ 5145 "AppFooPrebuilt", 5146 "AppFooPrivPrebuilt", 5147 ], 5148 updatable: false, 5149 } 5150 5151 apex_key { 5152 name: "myapex.key", 5153 public_key: "testkey.avbpubkey", 5154 private_key: "testkey.pem", 5155 } 5156 5157 android_app_import { 5158 name: "AppFooPrebuilt", 5159 apk: "PrebuiltAppFoo.apk", 5160 presigned: true, 5161 dex_preopt: { 5162 enabled: false, 5163 }, 5164 apex_available: ["myapex"], 5165 } 5166 5167 android_app_import { 5168 name: "AppFooPrivPrebuilt", 5169 apk: "PrebuiltAppFooPriv.apk", 5170 privileged: true, 5171 presigned: true, 5172 dex_preopt: { 5173 enabled: false, 5174 }, 5175 filename: "AwesomePrebuiltAppFooPriv.apk", 5176 apex_available: ["myapex"], 5177 } 5178 `) 5179 5180 module := ctx.ModuleForTests("myapex", "android_common_myapex_image") 5181 apexRule := module.Rule("apexRule") 5182 copyCmds := apexRule.Args["copy_commands"] 5183 5184 ensureContains(t, copyCmds, "image.apex/app/AppFooPrebuilt/AppFooPrebuilt.apk") 5185 ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPrivPrebuilt/AwesomePrebuiltAppFooPriv.apk") 5186} 5187 5188func TestApexWithAppImportsPrefer(t *testing.T) { 5189 ctx := testApex(t, ` 5190 apex { 5191 name: "myapex", 5192 key: "myapex.key", 5193 apps: [ 5194 "AppFoo", 5195 ], 5196 updatable: false, 5197 } 5198 5199 apex_key { 5200 name: "myapex.key", 5201 public_key: "testkey.avbpubkey", 5202 private_key: "testkey.pem", 5203 } 5204 5205 android_app { 5206 name: "AppFoo", 5207 srcs: ["foo/bar/MyClass.java"], 5208 sdk_version: "none", 5209 system_modules: "none", 5210 apex_available: [ "myapex" ], 5211 } 5212 5213 android_app_import { 5214 name: "AppFoo", 5215 apk: "AppFooPrebuilt.apk", 5216 filename: "AppFooPrebuilt.apk", 5217 presigned: true, 5218 prefer: true, 5219 apex_available: ["myapex"], 5220 } 5221 `, withFiles(map[string][]byte{ 5222 "AppFooPrebuilt.apk": nil, 5223 })) 5224 5225 ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{ 5226 "app/AppFoo/AppFooPrebuilt.apk", 5227 }) 5228} 5229 5230func TestApexWithTestHelperApp(t *testing.T) { 5231 ctx := testApex(t, ` 5232 apex { 5233 name: "myapex", 5234 key: "myapex.key", 5235 apps: [ 5236 "TesterHelpAppFoo", 5237 ], 5238 updatable: false, 5239 } 5240 5241 apex_key { 5242 name: "myapex.key", 5243 public_key: "testkey.avbpubkey", 5244 private_key: "testkey.pem", 5245 } 5246 5247 android_test_helper_app { 5248 name: "TesterHelpAppFoo", 5249 srcs: ["foo/bar/MyClass.java"], 5250 apex_available: [ "myapex" ], 5251 } 5252 5253 `) 5254 5255 module := ctx.ModuleForTests("myapex", "android_common_myapex_image") 5256 apexRule := module.Rule("apexRule") 5257 copyCmds := apexRule.Args["copy_commands"] 5258 5259 ensureContains(t, copyCmds, "image.apex/app/TesterHelpAppFoo/TesterHelpAppFoo.apk") 5260} 5261 5262func TestApexPropertiesShouldBeDefaultable(t *testing.T) { 5263 // libfoo's apex_available comes from cc_defaults 5264 testApexError(t, `requires "libfoo" that doesn't list the APEX under 'apex_available'.`, ` 5265 apex { 5266 name: "myapex", 5267 key: "myapex.key", 5268 native_shared_libs: ["libfoo"], 5269 updatable: false, 5270 } 5271 5272 apex_key { 5273 name: "myapex.key", 5274 public_key: "testkey.avbpubkey", 5275 private_key: "testkey.pem", 5276 } 5277 5278 apex { 5279 name: "otherapex", 5280 key: "myapex.key", 5281 native_shared_libs: ["libfoo"], 5282 updatable: false, 5283 } 5284 5285 cc_defaults { 5286 name: "libfoo-defaults", 5287 apex_available: ["otherapex"], 5288 } 5289 5290 cc_library { 5291 name: "libfoo", 5292 defaults: ["libfoo-defaults"], 5293 stl: "none", 5294 system_shared_libs: [], 5295 }`) 5296} 5297 5298func TestApexAvailable_DirectDep(t *testing.T) { 5299 // libfoo is not available to myapex, but only to otherapex 5300 testApexError(t, "requires \"libfoo\" that doesn't list the APEX under 'apex_available'.", ` 5301 apex { 5302 name: "myapex", 5303 key: "myapex.key", 5304 native_shared_libs: ["libfoo"], 5305 updatable: false, 5306 } 5307 5308 apex_key { 5309 name: "myapex.key", 5310 public_key: "testkey.avbpubkey", 5311 private_key: "testkey.pem", 5312 } 5313 5314 apex { 5315 name: "otherapex", 5316 key: "otherapex.key", 5317 native_shared_libs: ["libfoo"], 5318 updatable: false, 5319 } 5320 5321 apex_key { 5322 name: "otherapex.key", 5323 public_key: "testkey.avbpubkey", 5324 private_key: "testkey.pem", 5325 } 5326 5327 cc_library { 5328 name: "libfoo", 5329 stl: "none", 5330 system_shared_libs: [], 5331 apex_available: ["otherapex"], 5332 }`) 5333} 5334 5335func TestApexAvailable_IndirectDep(t *testing.T) { 5336 // libbbaz is an indirect dep 5337 testApexError(t, `requires "libbaz" that doesn't list the APEX under 'apex_available'.\n\nDependency path: 5338.*via tag apex\.dependencyTag.*name:sharedLib.* 5339.*-> libfoo.*link:shared.* 5340.*via tag cc\.libraryDependencyTag.*Kind:sharedLibraryDependency.* 5341.*-> libbar.*link:shared.* 5342.*via tag cc\.libraryDependencyTag.*Kind:sharedLibraryDependency.* 5343.*-> libbaz.*link:shared.*`, ` 5344 apex { 5345 name: "myapex", 5346 key: "myapex.key", 5347 native_shared_libs: ["libfoo"], 5348 updatable: false, 5349 } 5350 5351 apex_key { 5352 name: "myapex.key", 5353 public_key: "testkey.avbpubkey", 5354 private_key: "testkey.pem", 5355 } 5356 5357 cc_library { 5358 name: "libfoo", 5359 stl: "none", 5360 shared_libs: ["libbar"], 5361 system_shared_libs: [], 5362 apex_available: ["myapex"], 5363 } 5364 5365 cc_library { 5366 name: "libbar", 5367 stl: "none", 5368 shared_libs: ["libbaz"], 5369 system_shared_libs: [], 5370 apex_available: ["myapex"], 5371 } 5372 5373 cc_library { 5374 name: "libbaz", 5375 stl: "none", 5376 system_shared_libs: [], 5377 }`) 5378} 5379 5380func TestApexAvailable_InvalidApexName(t *testing.T) { 5381 testApexError(t, "\"otherapex\" is not a valid module name", ` 5382 apex { 5383 name: "myapex", 5384 key: "myapex.key", 5385 native_shared_libs: ["libfoo"], 5386 updatable: false, 5387 } 5388 5389 apex_key { 5390 name: "myapex.key", 5391 public_key: "testkey.avbpubkey", 5392 private_key: "testkey.pem", 5393 } 5394 5395 cc_library { 5396 name: "libfoo", 5397 stl: "none", 5398 system_shared_libs: [], 5399 apex_available: ["otherapex"], 5400 }`) 5401 5402 testApex(t, ` 5403 apex { 5404 name: "myapex", 5405 key: "myapex.key", 5406 native_shared_libs: ["libfoo", "libbar"], 5407 updatable: false, 5408 } 5409 5410 apex_key { 5411 name: "myapex.key", 5412 public_key: "testkey.avbpubkey", 5413 private_key: "testkey.pem", 5414 } 5415 5416 cc_library { 5417 name: "libfoo", 5418 stl: "none", 5419 system_shared_libs: [], 5420 runtime_libs: ["libbaz"], 5421 apex_available: ["myapex"], 5422 } 5423 5424 cc_library { 5425 name: "libbar", 5426 stl: "none", 5427 system_shared_libs: [], 5428 apex_available: ["//apex_available:anyapex"], 5429 } 5430 5431 cc_library { 5432 name: "libbaz", 5433 stl: "none", 5434 system_shared_libs: [], 5435 stubs: { 5436 versions: ["10", "20", "30"], 5437 }, 5438 }`) 5439} 5440 5441func TestApexAvailable_CheckForPlatform(t *testing.T) { 5442 ctx := testApex(t, ` 5443 apex { 5444 name: "myapex", 5445 key: "myapex.key", 5446 native_shared_libs: ["libbar", "libbaz"], 5447 updatable: false, 5448 } 5449 5450 apex_key { 5451 name: "myapex.key", 5452 public_key: "testkey.avbpubkey", 5453 private_key: "testkey.pem", 5454 } 5455 5456 cc_library { 5457 name: "libfoo", 5458 stl: "none", 5459 system_shared_libs: [], 5460 shared_libs: ["libbar"], 5461 apex_available: ["//apex_available:platform"], 5462 } 5463 5464 cc_library { 5465 name: "libfoo2", 5466 stl: "none", 5467 system_shared_libs: [], 5468 shared_libs: ["libbaz"], 5469 apex_available: ["//apex_available:platform"], 5470 } 5471 5472 cc_library { 5473 name: "libbar", 5474 stl: "none", 5475 system_shared_libs: [], 5476 apex_available: ["myapex"], 5477 } 5478 5479 cc_library { 5480 name: "libbaz", 5481 stl: "none", 5482 system_shared_libs: [], 5483 apex_available: ["myapex"], 5484 stubs: { 5485 versions: ["1"], 5486 }, 5487 }`) 5488 5489 // libfoo shouldn't be available to platform even though it has "//apex_available:platform", 5490 // because it depends on libbar which isn't available to platform 5491 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module().(*cc.Module) 5492 if libfoo.NotAvailableForPlatform() != true { 5493 t.Errorf("%q shouldn't be available to platform", libfoo.String()) 5494 } 5495 5496 // libfoo2 however can be available to platform because it depends on libbaz which provides 5497 // stubs 5498 libfoo2 := ctx.ModuleForTests("libfoo2", "android_arm64_armv8-a_shared").Module().(*cc.Module) 5499 if libfoo2.NotAvailableForPlatform() == true { 5500 t.Errorf("%q should be available to platform", libfoo2.String()) 5501 } 5502} 5503 5504func TestApexAvailable_CreatedForApex(t *testing.T) { 5505 ctx := testApex(t, ` 5506 apex { 5507 name: "myapex", 5508 key: "myapex.key", 5509 native_shared_libs: ["libfoo"], 5510 updatable: false, 5511 } 5512 5513 apex_key { 5514 name: "myapex.key", 5515 public_key: "testkey.avbpubkey", 5516 private_key: "testkey.pem", 5517 } 5518 5519 cc_library { 5520 name: "libfoo", 5521 stl: "none", 5522 system_shared_libs: [], 5523 apex_available: ["myapex"], 5524 static: { 5525 apex_available: ["//apex_available:platform"], 5526 }, 5527 }`) 5528 5529 libfooShared := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module().(*cc.Module) 5530 if libfooShared.NotAvailableForPlatform() != true { 5531 t.Errorf("%q shouldn't be available to platform", libfooShared.String()) 5532 } 5533 libfooStatic := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Module().(*cc.Module) 5534 if libfooStatic.NotAvailableForPlatform() != false { 5535 t.Errorf("%q should be available to platform", libfooStatic.String()) 5536 } 5537} 5538 5539func TestOverrideApex(t *testing.T) { 5540 ctx := testApex(t, ` 5541 apex { 5542 name: "myapex", 5543 key: "myapex.key", 5544 apps: ["app"], 5545 overrides: ["oldapex"], 5546 updatable: false, 5547 } 5548 5549 override_apex { 5550 name: "override_myapex", 5551 base: "myapex", 5552 apps: ["override_app"], 5553 overrides: ["unknownapex"], 5554 logging_parent: "com.foo.bar", 5555 package_name: "test.overridden.package", 5556 key: "mynewapex.key", 5557 certificate: ":myapex.certificate", 5558 } 5559 5560 apex_key { 5561 name: "myapex.key", 5562 public_key: "testkey.avbpubkey", 5563 private_key: "testkey.pem", 5564 } 5565 5566 apex_key { 5567 name: "mynewapex.key", 5568 public_key: "testkey2.avbpubkey", 5569 private_key: "testkey2.pem", 5570 } 5571 5572 android_app_certificate { 5573 name: "myapex.certificate", 5574 certificate: "testkey", 5575 } 5576 5577 android_app { 5578 name: "app", 5579 srcs: ["foo/bar/MyClass.java"], 5580 package_name: "foo", 5581 sdk_version: "none", 5582 system_modules: "none", 5583 apex_available: [ "myapex" ], 5584 } 5585 5586 override_android_app { 5587 name: "override_app", 5588 base: "app", 5589 package_name: "bar", 5590 } 5591 `, withManifestPackageNameOverrides([]string{"myapex:com.android.myapex"})) 5592 5593 originalVariant := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(android.OverridableModule) 5594 overriddenVariant := ctx.ModuleForTests("myapex", "android_common_override_myapex_myapex_image").Module().(android.OverridableModule) 5595 if originalVariant.GetOverriddenBy() != "" { 5596 t.Errorf("GetOverriddenBy should be empty, but was %q", originalVariant.GetOverriddenBy()) 5597 } 5598 if overriddenVariant.GetOverriddenBy() != "override_myapex" { 5599 t.Errorf("GetOverriddenBy should be \"override_myapex\", but was %q", overriddenVariant.GetOverriddenBy()) 5600 } 5601 5602 module := ctx.ModuleForTests("myapex", "android_common_override_myapex_myapex_image") 5603 apexRule := module.Rule("apexRule") 5604 copyCmds := apexRule.Args["copy_commands"] 5605 5606 ensureNotContains(t, copyCmds, "image.apex/app/app/app.apk") 5607 ensureContains(t, copyCmds, "image.apex/app/override_app/override_app.apk") 5608 5609 apexBundle := module.Module().(*apexBundle) 5610 name := apexBundle.Name() 5611 if name != "override_myapex" { 5612 t.Errorf("name should be \"override_myapex\", but was %q", name) 5613 } 5614 5615 if apexBundle.overridableProperties.Logging_parent != "com.foo.bar" { 5616 t.Errorf("override_myapex should have logging parent (com.foo.bar), but was %q.", apexBundle.overridableProperties.Logging_parent) 5617 } 5618 5619 optFlags := apexRule.Args["opt_flags"] 5620 ensureContains(t, optFlags, "--override_apk_package_name test.overridden.package") 5621 ensureContains(t, optFlags, "--pubkey testkey2.avbpubkey") 5622 5623 signApkRule := module.Rule("signapk") 5624 ensureEquals(t, signApkRule.Args["certificates"], "testkey.x509.pem testkey.pk8") 5625 5626 data := android.AndroidMkDataForTest(t, ctx, apexBundle) 5627 var builder strings.Builder 5628 data.Custom(&builder, name, "TARGET_", "", data) 5629 androidMk := builder.String() 5630 ensureContains(t, androidMk, "LOCAL_MODULE := override_app.override_myapex") 5631 ensureContains(t, androidMk, "LOCAL_MODULE := apex_manifest.pb.override_myapex") 5632 ensureContains(t, androidMk, "LOCAL_MODULE_STEM := override_myapex.apex") 5633 ensureContains(t, androidMk, "LOCAL_OVERRIDES_MODULES := unknownapex myapex") 5634 ensureNotContains(t, androidMk, "LOCAL_MODULE := app.myapex") 5635 ensureNotContains(t, androidMk, "LOCAL_MODULE := override_app.myapex") 5636 ensureNotContains(t, androidMk, "LOCAL_MODULE := apex_manifest.pb.myapex") 5637 ensureNotContains(t, androidMk, "LOCAL_MODULE_STEM := myapex.apex") 5638} 5639 5640func TestLegacyAndroid10Support(t *testing.T) { 5641 ctx := testApex(t, ` 5642 apex { 5643 name: "myapex", 5644 key: "myapex.key", 5645 native_shared_libs: ["mylib"], 5646 min_sdk_version: "29", 5647 } 5648 5649 apex_key { 5650 name: "myapex.key", 5651 public_key: "testkey.avbpubkey", 5652 private_key: "testkey.pem", 5653 } 5654 5655 cc_library { 5656 name: "mylib", 5657 srcs: ["mylib.cpp"], 5658 stl: "libc++", 5659 system_shared_libs: [], 5660 apex_available: [ "myapex" ], 5661 min_sdk_version: "29", 5662 } 5663 `, withUnbundledBuild) 5664 5665 module := ctx.ModuleForTests("myapex", "android_common_myapex_image") 5666 args := module.Rule("apexRule").Args 5667 ensureContains(t, args["opt_flags"], "--manifest_json "+module.Output("apex_manifest.json").Output.String()) 5668 ensureNotContains(t, args["opt_flags"], "--no_hashtree") 5669 5670 // The copies of the libraries in the apex should have one more dependency than 5671 // the ones outside the apex, namely the unwinder. Ideally we should check 5672 // the dependency names directly here but for some reason the names are blank in 5673 // this test. 5674 for _, lib := range []string{"libc++", "mylib"} { 5675 apexImplicits := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared_apex29").Rule("ld").Implicits 5676 nonApexImplicits := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld").Implicits 5677 if len(apexImplicits) != len(nonApexImplicits)+1 { 5678 t.Errorf("%q missing unwinder dep", lib) 5679 } 5680 } 5681} 5682 5683var filesForSdkLibrary = android.MockFS{ 5684 "api/current.txt": nil, 5685 "api/removed.txt": nil, 5686 "api/system-current.txt": nil, 5687 "api/system-removed.txt": nil, 5688 "api/test-current.txt": nil, 5689 "api/test-removed.txt": nil, 5690 5691 "100/public/api/foo.txt": nil, 5692 "100/public/api/foo-removed.txt": nil, 5693 "100/system/api/foo.txt": nil, 5694 "100/system/api/foo-removed.txt": nil, 5695 5696 // For java_sdk_library_import 5697 "a.jar": nil, 5698} 5699 5700func TestJavaSDKLibrary(t *testing.T) { 5701 ctx := testApex(t, ` 5702 apex { 5703 name: "myapex", 5704 key: "myapex.key", 5705 java_libs: ["foo"], 5706 updatable: false, 5707 } 5708 5709 apex_key { 5710 name: "myapex.key", 5711 public_key: "testkey.avbpubkey", 5712 private_key: "testkey.pem", 5713 } 5714 5715 java_sdk_library { 5716 name: "foo", 5717 srcs: ["a.java"], 5718 api_packages: ["foo"], 5719 apex_available: [ "myapex" ], 5720 } 5721 5722 prebuilt_apis { 5723 name: "sdk", 5724 api_dirs: ["100"], 5725 } 5726 `, withFiles(filesForSdkLibrary)) 5727 5728 // java_sdk_library installs both impl jar and permission XML 5729 ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{ 5730 "javalib/foo.jar", 5731 "etc/permissions/foo.xml", 5732 }) 5733 // Permission XML should point to the activated path of impl jar of java_sdk_library 5734 sdkLibrary := ctx.ModuleForTests("foo.xml", "android_common_myapex").Rule("java_sdk_xml") 5735 ensureContains(t, sdkLibrary.RuleParams.Command, `<library name=\"foo\" file=\"/apex/myapex/javalib/foo.jar\"`) 5736} 5737 5738func TestJavaSDKLibrary_WithinApex(t *testing.T) { 5739 ctx := testApex(t, ` 5740 apex { 5741 name: "myapex", 5742 key: "myapex.key", 5743 java_libs: ["foo", "bar"], 5744 updatable: false, 5745 } 5746 5747 apex_key { 5748 name: "myapex.key", 5749 public_key: "testkey.avbpubkey", 5750 private_key: "testkey.pem", 5751 } 5752 5753 java_sdk_library { 5754 name: "foo", 5755 srcs: ["a.java"], 5756 api_packages: ["foo"], 5757 apex_available: ["myapex"], 5758 sdk_version: "none", 5759 system_modules: "none", 5760 } 5761 5762 java_library { 5763 name: "bar", 5764 srcs: ["a.java"], 5765 libs: ["foo"], 5766 apex_available: ["myapex"], 5767 sdk_version: "none", 5768 system_modules: "none", 5769 } 5770 5771 prebuilt_apis { 5772 name: "sdk", 5773 api_dirs: ["100"], 5774 } 5775 `, withFiles(filesForSdkLibrary)) 5776 5777 // java_sdk_library installs both impl jar and permission XML 5778 ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{ 5779 "javalib/bar.jar", 5780 "javalib/foo.jar", 5781 "etc/permissions/foo.xml", 5782 }) 5783 5784 // The bar library should depend on the implementation jar. 5785 barLibrary := ctx.ModuleForTests("bar", "android_common_myapex").Rule("javac") 5786 if expected, actual := `^-classpath [^:]*/turbine-combined/foo\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { 5787 t.Errorf("expected %q, found %#q", expected, actual) 5788 } 5789} 5790 5791func TestJavaSDKLibrary_CrossBoundary(t *testing.T) { 5792 ctx := testApex(t, ` 5793 apex { 5794 name: "myapex", 5795 key: "myapex.key", 5796 java_libs: ["foo"], 5797 updatable: false, 5798 } 5799 5800 apex_key { 5801 name: "myapex.key", 5802 public_key: "testkey.avbpubkey", 5803 private_key: "testkey.pem", 5804 } 5805 5806 java_sdk_library { 5807 name: "foo", 5808 srcs: ["a.java"], 5809 api_packages: ["foo"], 5810 apex_available: ["myapex"], 5811 sdk_version: "none", 5812 system_modules: "none", 5813 } 5814 5815 java_library { 5816 name: "bar", 5817 srcs: ["a.java"], 5818 libs: ["foo"], 5819 sdk_version: "none", 5820 system_modules: "none", 5821 } 5822 5823 prebuilt_apis { 5824 name: "sdk", 5825 api_dirs: ["100"], 5826 } 5827 `, withFiles(filesForSdkLibrary)) 5828 5829 // java_sdk_library installs both impl jar and permission XML 5830 ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{ 5831 "javalib/foo.jar", 5832 "etc/permissions/foo.xml", 5833 }) 5834 5835 // The bar library should depend on the stubs jar. 5836 barLibrary := ctx.ModuleForTests("bar", "android_common").Rule("javac") 5837 if expected, actual := `^-classpath [^:]*/turbine-combined/foo\.stubs\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { 5838 t.Errorf("expected %q, found %#q", expected, actual) 5839 } 5840} 5841 5842func TestJavaSDKLibrary_ImportPreferred(t *testing.T) { 5843 ctx := testApex(t, ` 5844 prebuilt_apis { 5845 name: "sdk", 5846 api_dirs: ["100"], 5847 }`, 5848 withFiles(map[string][]byte{ 5849 "apex/a.java": nil, 5850 "apex/apex_manifest.json": nil, 5851 "apex/Android.bp": []byte(` 5852 package { 5853 default_visibility: ["//visibility:private"], 5854 } 5855 5856 apex { 5857 name: "myapex", 5858 key: "myapex.key", 5859 java_libs: ["foo", "bar"], 5860 updatable: false, 5861 } 5862 5863 apex_key { 5864 name: "myapex.key", 5865 public_key: "testkey.avbpubkey", 5866 private_key: "testkey.pem", 5867 } 5868 5869 java_library { 5870 name: "bar", 5871 srcs: ["a.java"], 5872 libs: ["foo"], 5873 apex_available: ["myapex"], 5874 sdk_version: "none", 5875 system_modules: "none", 5876 } 5877`), 5878 "source/a.java": nil, 5879 "source/api/current.txt": nil, 5880 "source/api/removed.txt": nil, 5881 "source/Android.bp": []byte(` 5882 package { 5883 default_visibility: ["//visibility:private"], 5884 } 5885 5886 java_sdk_library { 5887 name: "foo", 5888 visibility: ["//apex"], 5889 srcs: ["a.java"], 5890 api_packages: ["foo"], 5891 apex_available: ["myapex"], 5892 sdk_version: "none", 5893 system_modules: "none", 5894 public: { 5895 enabled: true, 5896 }, 5897 } 5898`), 5899 "prebuilt/a.jar": nil, 5900 "prebuilt/Android.bp": []byte(` 5901 package { 5902 default_visibility: ["//visibility:private"], 5903 } 5904 5905 java_sdk_library_import { 5906 name: "foo", 5907 visibility: ["//apex", "//source"], 5908 apex_available: ["myapex"], 5909 prefer: true, 5910 public: { 5911 jars: ["a.jar"], 5912 }, 5913 } 5914`), 5915 }), withFiles(filesForSdkLibrary), 5916 ) 5917 5918 // java_sdk_library installs both impl jar and permission XML 5919 ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{ 5920 "javalib/bar.jar", 5921 "javalib/foo.jar", 5922 "etc/permissions/foo.xml", 5923 }) 5924 5925 // The bar library should depend on the implementation jar. 5926 barLibrary := ctx.ModuleForTests("bar", "android_common_myapex").Rule("javac") 5927 if expected, actual := `^-classpath [^:]*/turbine-combined/foo\.impl\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { 5928 t.Errorf("expected %q, found %#q", expected, actual) 5929 } 5930} 5931 5932func TestJavaSDKLibrary_ImportOnly(t *testing.T) { 5933 testApexError(t, `java_libs: "foo" is not configured to be compiled into dex`, ` 5934 apex { 5935 name: "myapex", 5936 key: "myapex.key", 5937 java_libs: ["foo"], 5938 updatable: false, 5939 } 5940 5941 apex_key { 5942 name: "myapex.key", 5943 public_key: "testkey.avbpubkey", 5944 private_key: "testkey.pem", 5945 } 5946 5947 java_sdk_library_import { 5948 name: "foo", 5949 apex_available: ["myapex"], 5950 prefer: true, 5951 public: { 5952 jars: ["a.jar"], 5953 }, 5954 } 5955 5956 `, withFiles(filesForSdkLibrary)) 5957} 5958 5959func TestCompatConfig(t *testing.T) { 5960 result := android.GroupFixturePreparers( 5961 prepareForApexTest, 5962 java.PrepareForTestWithPlatformCompatConfig, 5963 ).RunTestWithBp(t, ` 5964 apex { 5965 name: "myapex", 5966 key: "myapex.key", 5967 compat_configs: ["myjar-platform-compat-config"], 5968 java_libs: ["myjar"], 5969 updatable: false, 5970 } 5971 5972 apex_key { 5973 name: "myapex.key", 5974 public_key: "testkey.avbpubkey", 5975 private_key: "testkey.pem", 5976 } 5977 5978 platform_compat_config { 5979 name: "myjar-platform-compat-config", 5980 src: ":myjar", 5981 } 5982 5983 java_library { 5984 name: "myjar", 5985 srcs: ["foo/bar/MyClass.java"], 5986 sdk_version: "none", 5987 system_modules: "none", 5988 apex_available: [ "myapex" ], 5989 } 5990 5991 // Make sure that a preferred prebuilt does not affect the apex contents. 5992 prebuilt_platform_compat_config { 5993 name: "myjar-platform-compat-config", 5994 metadata: "compat-config/metadata.xml", 5995 prefer: true, 5996 } 5997 `) 5998 ctx := result.TestContext 5999 ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{ 6000 "etc/compatconfig/myjar-platform-compat-config.xml", 6001 "javalib/myjar.jar", 6002 }) 6003} 6004 6005func TestRejectNonInstallableJavaLibrary(t *testing.T) { 6006 testApexError(t, `"myjar" is not configured to be compiled into dex`, ` 6007 apex { 6008 name: "myapex", 6009 key: "myapex.key", 6010 java_libs: ["myjar"], 6011 updatable: false, 6012 } 6013 6014 apex_key { 6015 name: "myapex.key", 6016 public_key: "testkey.avbpubkey", 6017 private_key: "testkey.pem", 6018 } 6019 6020 java_library { 6021 name: "myjar", 6022 srcs: ["foo/bar/MyClass.java"], 6023 sdk_version: "none", 6024 system_modules: "none", 6025 compile_dex: false, 6026 apex_available: ["myapex"], 6027 } 6028 `) 6029} 6030 6031func TestCarryRequiredModuleNames(t *testing.T) { 6032 ctx := testApex(t, ` 6033 apex { 6034 name: "myapex", 6035 key: "myapex.key", 6036 native_shared_libs: ["mylib"], 6037 updatable: false, 6038 } 6039 6040 apex_key { 6041 name: "myapex.key", 6042 public_key: "testkey.avbpubkey", 6043 private_key: "testkey.pem", 6044 } 6045 6046 cc_library { 6047 name: "mylib", 6048 srcs: ["mylib.cpp"], 6049 system_shared_libs: [], 6050 stl: "none", 6051 required: ["a", "b"], 6052 host_required: ["c", "d"], 6053 target_required: ["e", "f"], 6054 apex_available: [ "myapex" ], 6055 } 6056 `) 6057 6058 apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle) 6059 data := android.AndroidMkDataForTest(t, ctx, apexBundle) 6060 name := apexBundle.BaseModuleName() 6061 prefix := "TARGET_" 6062 var builder strings.Builder 6063 data.Custom(&builder, name, prefix, "", data) 6064 androidMk := builder.String() 6065 ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += a b\n") 6066 ensureContains(t, androidMk, "LOCAL_HOST_REQUIRED_MODULES += c d\n") 6067 ensureContains(t, androidMk, "LOCAL_TARGET_REQUIRED_MODULES += e f\n") 6068} 6069 6070func TestSymlinksFromApexToSystem(t *testing.T) { 6071 bp := ` 6072 apex { 6073 name: "myapex", 6074 key: "myapex.key", 6075 native_shared_libs: ["mylib"], 6076 java_libs: ["myjar"], 6077 updatable: false, 6078 } 6079 6080 apex { 6081 name: "myapex.updatable", 6082 key: "myapex.key", 6083 native_shared_libs: ["mylib"], 6084 java_libs: ["myjar"], 6085 updatable: true, 6086 min_sdk_version: "current", 6087 } 6088 6089 apex_key { 6090 name: "myapex.key", 6091 public_key: "testkey.avbpubkey", 6092 private_key: "testkey.pem", 6093 } 6094 6095 cc_library { 6096 name: "mylib", 6097 srcs: ["mylib.cpp"], 6098 shared_libs: ["myotherlib"], 6099 system_shared_libs: [], 6100 stl: "none", 6101 apex_available: [ 6102 "myapex", 6103 "myapex.updatable", 6104 "//apex_available:platform", 6105 ], 6106 min_sdk_version: "current", 6107 } 6108 6109 cc_library { 6110 name: "myotherlib", 6111 srcs: ["mylib.cpp"], 6112 system_shared_libs: [], 6113 stl: "none", 6114 apex_available: [ 6115 "myapex", 6116 "myapex.updatable", 6117 "//apex_available:platform", 6118 ], 6119 min_sdk_version: "current", 6120 } 6121 6122 java_library { 6123 name: "myjar", 6124 srcs: ["foo/bar/MyClass.java"], 6125 sdk_version: "none", 6126 system_modules: "none", 6127 libs: ["myotherjar"], 6128 apex_available: [ 6129 "myapex", 6130 "myapex.updatable", 6131 "//apex_available:platform", 6132 ], 6133 min_sdk_version: "current", 6134 } 6135 6136 java_library { 6137 name: "myotherjar", 6138 srcs: ["foo/bar/MyClass.java"], 6139 sdk_version: "none", 6140 system_modules: "none", 6141 apex_available: [ 6142 "myapex", 6143 "myapex.updatable", 6144 "//apex_available:platform", 6145 ], 6146 min_sdk_version: "current", 6147 } 6148 ` 6149 6150 ensureRealfileExists := func(t *testing.T, files []fileInApex, file string) { 6151 for _, f := range files { 6152 if f.path == file { 6153 if f.isLink { 6154 t.Errorf("%q is not a real file", file) 6155 } 6156 return 6157 } 6158 } 6159 t.Errorf("%q is not found", file) 6160 } 6161 6162 ensureSymlinkExists := func(t *testing.T, files []fileInApex, file string) { 6163 for _, f := range files { 6164 if f.path == file { 6165 if !f.isLink { 6166 t.Errorf("%q is not a symlink", file) 6167 } 6168 return 6169 } 6170 } 6171 t.Errorf("%q is not found", file) 6172 } 6173 6174 // For unbundled build, symlink shouldn't exist regardless of whether an APEX 6175 // is updatable or not 6176 ctx := testApex(t, bp, withUnbundledBuild) 6177 files := getFiles(t, ctx, "myapex", "android_common_myapex_image") 6178 ensureRealfileExists(t, files, "javalib/myjar.jar") 6179 ensureRealfileExists(t, files, "lib64/mylib.so") 6180 ensureRealfileExists(t, files, "lib64/myotherlib.so") 6181 6182 files = getFiles(t, ctx, "myapex.updatable", "android_common_myapex.updatable_image") 6183 ensureRealfileExists(t, files, "javalib/myjar.jar") 6184 ensureRealfileExists(t, files, "lib64/mylib.so") 6185 ensureRealfileExists(t, files, "lib64/myotherlib.so") 6186 6187 // For bundled build, symlink to the system for the non-updatable APEXes only 6188 ctx = testApex(t, bp) 6189 files = getFiles(t, ctx, "myapex", "android_common_myapex_image") 6190 ensureRealfileExists(t, files, "javalib/myjar.jar") 6191 ensureRealfileExists(t, files, "lib64/mylib.so") 6192 ensureSymlinkExists(t, files, "lib64/myotherlib.so") // this is symlink 6193 6194 files = getFiles(t, ctx, "myapex.updatable", "android_common_myapex.updatable_image") 6195 ensureRealfileExists(t, files, "javalib/myjar.jar") 6196 ensureRealfileExists(t, files, "lib64/mylib.so") 6197 ensureRealfileExists(t, files, "lib64/myotherlib.so") // this is a real file 6198} 6199 6200func TestSymlinksFromApexToSystemRequiredModuleNames(t *testing.T) { 6201 ctx := testApex(t, ` 6202 apex { 6203 name: "myapex", 6204 key: "myapex.key", 6205 native_shared_libs: ["mylib"], 6206 updatable: false, 6207 } 6208 6209 apex_key { 6210 name: "myapex.key", 6211 public_key: "testkey.avbpubkey", 6212 private_key: "testkey.pem", 6213 } 6214 6215 cc_library_shared { 6216 name: "mylib", 6217 srcs: ["mylib.cpp"], 6218 shared_libs: ["myotherlib"], 6219 system_shared_libs: [], 6220 stl: "none", 6221 apex_available: [ 6222 "myapex", 6223 "//apex_available:platform", 6224 ], 6225 } 6226 6227 cc_prebuilt_library_shared { 6228 name: "myotherlib", 6229 srcs: ["prebuilt.so"], 6230 system_shared_libs: [], 6231 stl: "none", 6232 apex_available: [ 6233 "myapex", 6234 "//apex_available:platform", 6235 ], 6236 } 6237 `) 6238 6239 apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle) 6240 data := android.AndroidMkDataForTest(t, ctx, apexBundle) 6241 var builder strings.Builder 6242 data.Custom(&builder, apexBundle.BaseModuleName(), "TARGET_", "", data) 6243 androidMk := builder.String() 6244 // `myotherlib` is added to `myapex` as symlink 6245 ensureContains(t, androidMk, "LOCAL_MODULE := mylib.myapex\n") 6246 ensureNotContains(t, androidMk, "LOCAL_MODULE := prebuilt_myotherlib.myapex\n") 6247 ensureNotContains(t, androidMk, "LOCAL_MODULE := myotherlib.myapex\n") 6248 // `myapex` should have `myotherlib` in its required line, not `prebuilt_myotherlib` 6249 ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += mylib.myapex:64 myotherlib:64 apex_manifest.pb.myapex apex_pubkey.myapex\n") 6250} 6251 6252func TestApexWithJniLibs(t *testing.T) { 6253 ctx := testApex(t, ` 6254 apex { 6255 name: "myapex", 6256 key: "myapex.key", 6257 jni_libs: ["mylib"], 6258 updatable: false, 6259 } 6260 6261 apex_key { 6262 name: "myapex.key", 6263 public_key: "testkey.avbpubkey", 6264 private_key: "testkey.pem", 6265 } 6266 6267 cc_library { 6268 name: "mylib", 6269 srcs: ["mylib.cpp"], 6270 shared_libs: ["mylib2"], 6271 system_shared_libs: [], 6272 stl: "none", 6273 apex_available: [ "myapex" ], 6274 } 6275 6276 cc_library { 6277 name: "mylib2", 6278 srcs: ["mylib.cpp"], 6279 system_shared_libs: [], 6280 stl: "none", 6281 apex_available: [ "myapex" ], 6282 } 6283 `) 6284 6285 rule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule") 6286 // Notice mylib2.so (transitive dep) is not added as a jni_lib 6287 ensureEquals(t, rule.Args["opt"], "-a jniLibs mylib.so") 6288 ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{ 6289 "lib64/mylib.so", 6290 "lib64/mylib2.so", 6291 }) 6292} 6293 6294func TestApexMutatorsDontRunIfDisabled(t *testing.T) { 6295 ctx := testApex(t, ` 6296 apex { 6297 name: "myapex", 6298 key: "myapex.key", 6299 updatable: false, 6300 } 6301 apex_key { 6302 name: "myapex.key", 6303 public_key: "testkey.avbpubkey", 6304 private_key: "testkey.pem", 6305 } 6306 `, 6307 android.FixtureModifyConfig(func(config android.Config) { 6308 delete(config.Targets, android.Android) 6309 config.AndroidCommonTarget = android.Target{} 6310 }), 6311 ) 6312 6313 if expected, got := []string{""}, ctx.ModuleVariantsForTests("myapex"); !reflect.DeepEqual(expected, got) { 6314 t.Errorf("Expected variants: %v, but got: %v", expected, got) 6315 } 6316} 6317 6318func TestAppBundle(t *testing.T) { 6319 ctx := testApex(t, ` 6320 apex { 6321 name: "myapex", 6322 key: "myapex.key", 6323 apps: ["AppFoo"], 6324 updatable: false, 6325 } 6326 6327 apex_key { 6328 name: "myapex.key", 6329 public_key: "testkey.avbpubkey", 6330 private_key: "testkey.pem", 6331 } 6332 6333 android_app { 6334 name: "AppFoo", 6335 srcs: ["foo/bar/MyClass.java"], 6336 sdk_version: "none", 6337 system_modules: "none", 6338 apex_available: [ "myapex" ], 6339 } 6340 `, withManifestPackageNameOverrides([]string{"AppFoo:com.android.foo"})) 6341 6342 bundleConfigRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Output("bundle_config.json") 6343 content := bundleConfigRule.Args["content"] 6344 6345 ensureContains(t, content, `"compression":{"uncompressed_glob":["apex_payload.img","apex_manifest.*"]}`) 6346 ensureContains(t, content, `"apex_config":{"apex_embedded_apk_config":[{"package_name":"com.android.foo","path":"app/AppFoo/AppFoo.apk"}]}`) 6347} 6348 6349func TestAppSetBundle(t *testing.T) { 6350 ctx := testApex(t, ` 6351 apex { 6352 name: "myapex", 6353 key: "myapex.key", 6354 apps: ["AppSet"], 6355 updatable: false, 6356 } 6357 6358 apex_key { 6359 name: "myapex.key", 6360 public_key: "testkey.avbpubkey", 6361 private_key: "testkey.pem", 6362 } 6363 6364 android_app_set { 6365 name: "AppSet", 6366 set: "AppSet.apks", 6367 }`) 6368 mod := ctx.ModuleForTests("myapex", "android_common_myapex_image") 6369 bundleConfigRule := mod.Output("bundle_config.json") 6370 content := bundleConfigRule.Args["content"] 6371 ensureContains(t, content, `"compression":{"uncompressed_glob":["apex_payload.img","apex_manifest.*"]}`) 6372 s := mod.Rule("apexRule").Args["copy_commands"] 6373 copyCmds := regexp.MustCompile(" *&& *").Split(s, -1) 6374 if len(copyCmds) != 3 { 6375 t.Fatalf("Expected 3 commands, got %d in:\n%s", len(copyCmds), s) 6376 } 6377 ensureMatches(t, copyCmds[0], "^rm -rf .*/app/AppSet$") 6378 ensureMatches(t, copyCmds[1], "^mkdir -p .*/app/AppSet$") 6379 ensureMatches(t, copyCmds[2], "^unzip .*-d .*/app/AppSet .*/AppSet.zip$") 6380} 6381 6382func TestAppSetBundlePrebuilt(t *testing.T) { 6383 bp := ` 6384 apex_set { 6385 name: "myapex", 6386 filename: "foo_v2.apex", 6387 sanitized: { 6388 none: { set: "myapex.apks", }, 6389 hwaddress: { set: "myapex.hwasan.apks", }, 6390 }, 6391 } 6392 ` 6393 ctx := testApex(t, bp, prepareForTestWithSantitizeHwaddress) 6394 6395 // Check that the extractor produces the correct output file from the correct input file. 6396 extractorOutput := "out/soong/.intermediates/myapex.apex.extractor/android_common/extracted/myapex.hwasan.apks" 6397 6398 m := ctx.ModuleForTests("myapex.apex.extractor", "android_common") 6399 extractedApex := m.Output(extractorOutput) 6400 6401 android.AssertArrayString(t, "extractor input", []string{"myapex.hwasan.apks"}, extractedApex.Inputs.Strings()) 6402 6403 // Ditto for the apex. 6404 m = ctx.ModuleForTests("myapex", "android_common_myapex") 6405 copiedApex := m.Output("out/soong/.intermediates/myapex/android_common_myapex/foo_v2.apex") 6406 6407 android.AssertStringEquals(t, "myapex input", extractorOutput, copiedApex.Input.String()) 6408} 6409 6410func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, preparer android.FixturePreparer, fragments ...java.ApexVariantReference) { 6411 t.Helper() 6412 6413 bp := ` 6414 java_library { 6415 name: "some-updatable-apex-lib", 6416 srcs: ["a.java"], 6417 sdk_version: "current", 6418 apex_available: [ 6419 "some-updatable-apex", 6420 ], 6421 } 6422 6423 java_library { 6424 name: "some-non-updatable-apex-lib", 6425 srcs: ["a.java"], 6426 apex_available: [ 6427 "some-non-updatable-apex", 6428 ], 6429 compile_dex: true, 6430 } 6431 6432 bootclasspath_fragment { 6433 name: "some-non-updatable-fragment", 6434 contents: ["some-non-updatable-apex-lib"], 6435 apex_available: [ 6436 "some-non-updatable-apex", 6437 ], 6438 } 6439 6440 java_library { 6441 name: "some-platform-lib", 6442 srcs: ["a.java"], 6443 sdk_version: "current", 6444 installable: true, 6445 } 6446 6447 java_library { 6448 name: "some-art-lib", 6449 srcs: ["a.java"], 6450 sdk_version: "current", 6451 apex_available: [ 6452 "com.android.art.debug", 6453 ], 6454 hostdex: true, 6455 compile_dex: true, 6456 } 6457 6458 apex { 6459 name: "some-updatable-apex", 6460 key: "some-updatable-apex.key", 6461 java_libs: ["some-updatable-apex-lib"], 6462 updatable: true, 6463 min_sdk_version: "current", 6464 } 6465 6466 apex { 6467 name: "some-non-updatable-apex", 6468 key: "some-non-updatable-apex.key", 6469 bootclasspath_fragments: ["some-non-updatable-fragment"], 6470 updatable: false, 6471 } 6472 6473 apex_key { 6474 name: "some-updatable-apex.key", 6475 } 6476 6477 apex_key { 6478 name: "some-non-updatable-apex.key", 6479 } 6480 6481 apex { 6482 name: "com.android.art.debug", 6483 key: "com.android.art.debug.key", 6484 bootclasspath_fragments: ["art-bootclasspath-fragment"], 6485 updatable: true, 6486 min_sdk_version: "current", 6487 } 6488 6489 bootclasspath_fragment { 6490 name: "art-bootclasspath-fragment", 6491 image_name: "art", 6492 contents: ["some-art-lib"], 6493 apex_available: [ 6494 "com.android.art.debug", 6495 ], 6496 } 6497 6498 apex_key { 6499 name: "com.android.art.debug.key", 6500 } 6501 6502 filegroup { 6503 name: "some-updatable-apex-file_contexts", 6504 srcs: [ 6505 "system/sepolicy/apex/some-updatable-apex-file_contexts", 6506 ], 6507 } 6508 6509 filegroup { 6510 name: "some-non-updatable-apex-file_contexts", 6511 srcs: [ 6512 "system/sepolicy/apex/some-non-updatable-apex-file_contexts", 6513 ], 6514 } 6515 ` 6516 6517 testDexpreoptWithApexes(t, bp, errmsg, preparer, fragments...) 6518} 6519 6520func testDexpreoptWithApexes(t *testing.T, bp, errmsg string, preparer android.FixturePreparer, fragments ...java.ApexVariantReference) *android.TestContext { 6521 t.Helper() 6522 6523 fs := android.MockFS{ 6524 "a.java": nil, 6525 "a.jar": nil, 6526 "apex_manifest.json": nil, 6527 "AndroidManifest.xml": nil, 6528 "system/sepolicy/apex/myapex-file_contexts": nil, 6529 "system/sepolicy/apex/some-updatable-apex-file_contexts": nil, 6530 "system/sepolicy/apex/some-non-updatable-apex-file_contexts": nil, 6531 "system/sepolicy/apex/com.android.art.debug-file_contexts": nil, 6532 "framework/aidl/a.aidl": nil, 6533 } 6534 6535 errorHandler := android.FixtureExpectsNoErrors 6536 if errmsg != "" { 6537 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(errmsg) 6538 } 6539 6540 result := android.GroupFixturePreparers( 6541 cc.PrepareForTestWithCcDefaultModules, 6542 java.PrepareForTestWithHiddenApiBuildComponents, 6543 java.PrepareForTestWithJavaDefaultModules, 6544 java.PrepareForTestWithJavaSdkLibraryFiles, 6545 PrepareForTestWithApexBuildComponents, 6546 preparer, 6547 fs.AddToFixture(), 6548 android.FixtureModifyMockFS(func(fs android.MockFS) { 6549 if _, ok := fs["frameworks/base/boot/Android.bp"]; !ok { 6550 insert := "" 6551 for _, fragment := range fragments { 6552 insert += fmt.Sprintf("{apex: %q, module: %q},\n", *fragment.Apex, *fragment.Module) 6553 } 6554 fs["frameworks/base/boot/Android.bp"] = []byte(fmt.Sprintf(` 6555 platform_bootclasspath { 6556 name: "platform-bootclasspath", 6557 fragments: [ 6558 %s 6559 ], 6560 } 6561 `, insert)) 6562 } 6563 }), 6564 ). 6565 ExtendWithErrorHandler(errorHandler). 6566 RunTestWithBp(t, bp) 6567 6568 return result.TestContext 6569} 6570 6571func TestDuplicateDeapexeresFromPrebuiltApexes(t *testing.T) { 6572 preparers := android.GroupFixturePreparers( 6573 java.PrepareForTestWithJavaDefaultModules, 6574 PrepareForTestWithApexBuildComponents, 6575 ). 6576 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( 6577 `Ambiguous duplicate deapexer module dependencies "com.android.myapex.deapexer" and "com.mycompany.android.myapex.deapexer"`)) 6578 6579 bpBase := ` 6580 apex_set { 6581 name: "com.android.myapex", 6582 exported_bootclasspath_fragments: ["my-bootclasspath-fragment"], 6583 set: "myapex.apks", 6584 } 6585 6586 apex_set { 6587 name: "com.mycompany.android.myapex", 6588 apex_name: "com.android.myapex", 6589 exported_bootclasspath_fragments: ["my-bootclasspath-fragment"], 6590 set: "company-myapex.apks", 6591 } 6592 6593 prebuilt_bootclasspath_fragment { 6594 name: "my-bootclasspath-fragment", 6595 apex_available: ["com.android.myapex"], 6596 %s 6597 } 6598 ` 6599 6600 t.Run("java_import", func(t *testing.T) { 6601 _ = preparers.RunTestWithBp(t, fmt.Sprintf(bpBase, `contents: ["libfoo"]`)+` 6602 java_import { 6603 name: "libfoo", 6604 jars: ["libfoo.jar"], 6605 apex_available: ["com.android.myapex"], 6606 } 6607 `) 6608 }) 6609 6610 t.Run("java_sdk_library_import", func(t *testing.T) { 6611 _ = preparers.RunTestWithBp(t, fmt.Sprintf(bpBase, `contents: ["libfoo"]`)+` 6612 java_sdk_library_import { 6613 name: "libfoo", 6614 public: { 6615 jars: ["libbar.jar"], 6616 }, 6617 apex_available: ["com.android.myapex"], 6618 } 6619 `) 6620 }) 6621 6622 t.Run("prebuilt_bootclasspath_fragment", func(t *testing.T) { 6623 _ = preparers.RunTestWithBp(t, fmt.Sprintf(bpBase, ` 6624 image_name: "art", 6625 contents: ["libfoo"], 6626 `)+` 6627 java_sdk_library_import { 6628 name: "libfoo", 6629 public: { 6630 jars: ["libbar.jar"], 6631 }, 6632 apex_available: ["com.android.myapex"], 6633 } 6634 `) 6635 }) 6636} 6637 6638func TestUpdatable_should_set_min_sdk_version(t *testing.T) { 6639 testApexError(t, `"myapex" .*: updatable: updatable APEXes should set min_sdk_version`, ` 6640 apex { 6641 name: "myapex", 6642 key: "myapex.key", 6643 updatable: true, 6644 } 6645 6646 apex_key { 6647 name: "myapex.key", 6648 public_key: "testkey.avbpubkey", 6649 private_key: "testkey.pem", 6650 } 6651 `) 6652} 6653 6654func TestUpdatableDefault_should_set_min_sdk_version(t *testing.T) { 6655 testApexError(t, `"myapex" .*: updatable: updatable APEXes should set min_sdk_version`, ` 6656 apex { 6657 name: "myapex", 6658 key: "myapex.key", 6659 } 6660 6661 apex_key { 6662 name: "myapex.key", 6663 public_key: "testkey.avbpubkey", 6664 private_key: "testkey.pem", 6665 } 6666 `) 6667} 6668 6669func TestNoUpdatableJarsInBootImage(t *testing.T) { 6670 // Set the BootJars in dexpreopt.GlobalConfig and productVariables to the same value. This can 6671 // result in an invalid configuration as it does not set the ArtApexJars and allows art apex 6672 // modules to be included in the BootJars. 6673 prepareSetBootJars := func(bootJars ...string) android.FixturePreparer { 6674 return android.GroupFixturePreparers( 6675 dexpreopt.FixtureSetBootJars(bootJars...), 6676 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 6677 variables.BootJars = android.CreateTestConfiguredJarList(bootJars) 6678 }), 6679 ) 6680 } 6681 6682 // Set the ArtApexJars and BootJars in dexpreopt.GlobalConfig and productVariables all to the 6683 // same value. This can result in an invalid configuration as it allows non art apex jars to be 6684 // specified in the ArtApexJars configuration. 6685 prepareSetArtJars := func(bootJars ...string) android.FixturePreparer { 6686 return android.GroupFixturePreparers( 6687 dexpreopt.FixtureSetArtBootJars(bootJars...), 6688 dexpreopt.FixtureSetBootJars(bootJars...), 6689 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 6690 variables.BootJars = android.CreateTestConfiguredJarList(bootJars) 6691 }), 6692 ) 6693 } 6694 6695 t.Run("updatable jar from ART apex in the ART boot image => ok", func(t *testing.T) { 6696 preparer := java.FixtureConfigureBootJars("com.android.art.debug:some-art-lib") 6697 fragment := java.ApexVariantReference{ 6698 Apex: proptools.StringPtr("com.android.art.debug"), 6699 Module: proptools.StringPtr("art-bootclasspath-fragment"), 6700 } 6701 testNoUpdatableJarsInBootImage(t, "", preparer, fragment) 6702 }) 6703 6704 t.Run("updatable jar from ART apex in the framework boot image => error", func(t *testing.T) { 6705 err := `module "some-art-lib" from updatable apexes \["com.android.art.debug"\] is not allowed in the framework boot image` 6706 // Update the dexpreopt BootJars directly. 6707 preparer := prepareSetBootJars("com.android.art.debug:some-art-lib") 6708 testNoUpdatableJarsInBootImage(t, err, preparer) 6709 }) 6710 6711 t.Run("updatable jar from some other apex in the ART boot image => error", func(t *testing.T) { 6712 err := `ArtApexJars expects this to be in apex "some-updatable-apex" but this is only in apexes.*"com.android.art.debug"` 6713 // Update the dexpreopt ArtApexJars directly. 6714 preparer := prepareSetArtJars("some-updatable-apex:some-updatable-apex-lib") 6715 testNoUpdatableJarsInBootImage(t, err, preparer) 6716 }) 6717 6718 t.Run("non-updatable jar from some other apex in the ART boot image => error", func(t *testing.T) { 6719 err := `ArtApexJars expects this to be in apex "some-non-updatable-apex" but this is only in apexes.*"com.android.art.debug"` 6720 // Update the dexpreopt ArtApexJars directly. 6721 preparer := prepareSetArtJars("some-non-updatable-apex:some-non-updatable-apex-lib") 6722 testNoUpdatableJarsInBootImage(t, err, preparer) 6723 }) 6724 6725 t.Run("updatable jar from some other apex in the framework boot image => error", func(t *testing.T) { 6726 err := `module "some-updatable-apex-lib" from updatable apexes \["some-updatable-apex"\] is not allowed in the framework boot image` 6727 preparer := java.FixtureConfigureBootJars("some-updatable-apex:some-updatable-apex-lib") 6728 testNoUpdatableJarsInBootImage(t, err, preparer) 6729 }) 6730 6731 t.Run("non-updatable jar from some other apex in the framework boot image => ok", func(t *testing.T) { 6732 preparer := java.FixtureConfigureBootJars("some-non-updatable-apex:some-non-updatable-apex-lib") 6733 fragment := java.ApexVariantReference{ 6734 Apex: proptools.StringPtr("some-non-updatable-apex"), 6735 Module: proptools.StringPtr("some-non-updatable-fragment"), 6736 } 6737 testNoUpdatableJarsInBootImage(t, "", preparer, fragment) 6738 }) 6739 6740 t.Run("nonexistent jar in the ART boot image => error", func(t *testing.T) { 6741 err := `"platform-bootclasspath" depends on undefined module "nonexistent"` 6742 preparer := java.FixtureConfigureBootJars("platform:nonexistent") 6743 testNoUpdatableJarsInBootImage(t, err, preparer) 6744 }) 6745 6746 t.Run("nonexistent jar in the framework boot image => error", func(t *testing.T) { 6747 err := `"platform-bootclasspath" depends on undefined module "nonexistent"` 6748 preparer := java.FixtureConfigureBootJars("platform:nonexistent") 6749 testNoUpdatableJarsInBootImage(t, err, preparer) 6750 }) 6751 6752 t.Run("platform jar in the ART boot image => error", func(t *testing.T) { 6753 err := `ArtApexJars is invalid as it requests a platform variant of "some-platform-lib"` 6754 // Update the dexpreopt ArtApexJars directly. 6755 preparer := prepareSetArtJars("platform:some-platform-lib") 6756 testNoUpdatableJarsInBootImage(t, err, preparer) 6757 }) 6758 6759 t.Run("platform jar in the framework boot image => ok", func(t *testing.T) { 6760 preparer := java.FixtureConfigureBootJars("platform:some-platform-lib") 6761 testNoUpdatableJarsInBootImage(t, "", preparer) 6762 }) 6763} 6764 6765func TestDexpreoptAccessDexFilesFromPrebuiltApex(t *testing.T) { 6766 preparer := java.FixtureConfigureBootJars("myapex:libfoo") 6767 t.Run("prebuilt no source", func(t *testing.T) { 6768 fragment := java.ApexVariantReference{ 6769 Apex: proptools.StringPtr("myapex"), 6770 Module: proptools.StringPtr("my-bootclasspath-fragment"), 6771 } 6772 6773 testDexpreoptWithApexes(t, ` 6774 prebuilt_apex { 6775 name: "myapex" , 6776 arch: { 6777 arm64: { 6778 src: "myapex-arm64.apex", 6779 }, 6780 arm: { 6781 src: "myapex-arm.apex", 6782 }, 6783 }, 6784 exported_bootclasspath_fragments: ["my-bootclasspath-fragment"], 6785 } 6786 6787 prebuilt_bootclasspath_fragment { 6788 name: "my-bootclasspath-fragment", 6789 contents: ["libfoo"], 6790 apex_available: ["myapex"], 6791 } 6792 6793 java_import { 6794 name: "libfoo", 6795 jars: ["libfoo.jar"], 6796 apex_available: ["myapex"], 6797 } 6798 `, "", preparer, fragment) 6799 }) 6800} 6801 6802func testApexPermittedPackagesRules(t *testing.T, errmsg, bp string, apexBootJars []string, rules []android.Rule) { 6803 t.Helper() 6804 bp += ` 6805 apex_key { 6806 name: "myapex.key", 6807 public_key: "testkey.avbpubkey", 6808 private_key: "testkey.pem", 6809 }` 6810 fs := android.MockFS{ 6811 "lib1/src/A.java": nil, 6812 "lib2/src/B.java": nil, 6813 "system/sepolicy/apex/myapex-file_contexts": nil, 6814 } 6815 6816 errorHandler := android.FixtureExpectsNoErrors 6817 if errmsg != "" { 6818 errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(errmsg) 6819 } 6820 6821 android.GroupFixturePreparers( 6822 android.PrepareForTestWithAndroidBuildComponents, 6823 java.PrepareForTestWithJavaBuildComponents, 6824 PrepareForTestWithApexBuildComponents, 6825 android.PrepareForTestWithNeverallowRules(rules), 6826 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 6827 updatableBootJars := make([]string, 0, len(apexBootJars)) 6828 for _, apexBootJar := range apexBootJars { 6829 updatableBootJars = append(updatableBootJars, "myapex:"+apexBootJar) 6830 } 6831 variables.UpdatableBootJars = android.CreateTestConfiguredJarList(updatableBootJars) 6832 }), 6833 fs.AddToFixture(), 6834 ). 6835 ExtendWithErrorHandler(errorHandler). 6836 RunTestWithBp(t, bp) 6837} 6838 6839func TestApexPermittedPackagesRules(t *testing.T) { 6840 testcases := []struct { 6841 name string 6842 expectedError string 6843 bp string 6844 bootJars []string 6845 modulesPackages map[string][]string 6846 }{ 6847 6848 { 6849 name: "Non-Bootclasspath apex jar not satisfying allowed module packages.", 6850 expectedError: "", 6851 bp: ` 6852 java_library { 6853 name: "bcp_lib1", 6854 srcs: ["lib1/src/*.java"], 6855 permitted_packages: ["foo.bar"], 6856 apex_available: ["myapex"], 6857 sdk_version: "none", 6858 system_modules: "none", 6859 } 6860 java_library { 6861 name: "nonbcp_lib2", 6862 srcs: ["lib2/src/*.java"], 6863 apex_available: ["myapex"], 6864 permitted_packages: ["a.b"], 6865 sdk_version: "none", 6866 system_modules: "none", 6867 } 6868 apex { 6869 name: "myapex", 6870 key: "myapex.key", 6871 java_libs: ["bcp_lib1", "nonbcp_lib2"], 6872 updatable: false, 6873 }`, 6874 bootJars: []string{"bcp_lib1"}, 6875 modulesPackages: map[string][]string{ 6876 "myapex": []string{ 6877 "foo.bar", 6878 }, 6879 }, 6880 }, 6881 { 6882 name: "Bootclasspath apex jar not satisfying allowed module packages.", 6883 expectedError: `module "bcp_lib2" .* which is restricted because jars that are part of the myapex module may only allow these packages: foo.bar. Please jarjar or move code around.`, 6884 bp: ` 6885 java_library { 6886 name: "bcp_lib1", 6887 srcs: ["lib1/src/*.java"], 6888 apex_available: ["myapex"], 6889 permitted_packages: ["foo.bar"], 6890 sdk_version: "none", 6891 system_modules: "none", 6892 } 6893 java_library { 6894 name: "bcp_lib2", 6895 srcs: ["lib2/src/*.java"], 6896 apex_available: ["myapex"], 6897 permitted_packages: ["foo.bar", "bar.baz"], 6898 sdk_version: "none", 6899 system_modules: "none", 6900 } 6901 apex { 6902 name: "myapex", 6903 key: "myapex.key", 6904 java_libs: ["bcp_lib1", "bcp_lib2"], 6905 updatable: false, 6906 } 6907 `, 6908 bootJars: []string{"bcp_lib1", "bcp_lib2"}, 6909 modulesPackages: map[string][]string{ 6910 "myapex": []string{ 6911 "foo.bar", 6912 }, 6913 }, 6914 }, 6915 } 6916 for _, tc := range testcases { 6917 t.Run(tc.name, func(t *testing.T) { 6918 rules := createApexPermittedPackagesRules(tc.modulesPackages) 6919 testApexPermittedPackagesRules(t, tc.expectedError, tc.bp, tc.bootJars, rules) 6920 }) 6921 } 6922} 6923 6924func TestTestFor(t *testing.T) { 6925 ctx := testApex(t, ` 6926 apex { 6927 name: "myapex", 6928 key: "myapex.key", 6929 native_shared_libs: ["mylib", "myprivlib"], 6930 updatable: false, 6931 } 6932 6933 apex_key { 6934 name: "myapex.key", 6935 public_key: "testkey.avbpubkey", 6936 private_key: "testkey.pem", 6937 } 6938 6939 cc_library { 6940 name: "mylib", 6941 srcs: ["mylib.cpp"], 6942 system_shared_libs: [], 6943 stl: "none", 6944 stubs: { 6945 versions: ["1"], 6946 }, 6947 apex_available: ["myapex"], 6948 } 6949 6950 cc_library { 6951 name: "myprivlib", 6952 srcs: ["mylib.cpp"], 6953 system_shared_libs: [], 6954 stl: "none", 6955 apex_available: ["myapex"], 6956 } 6957 6958 6959 cc_test { 6960 name: "mytest", 6961 gtest: false, 6962 srcs: ["mylib.cpp"], 6963 system_shared_libs: [], 6964 stl: "none", 6965 shared_libs: ["mylib", "myprivlib", "mytestlib"], 6966 test_for: ["myapex"] 6967 } 6968 6969 cc_library { 6970 name: "mytestlib", 6971 srcs: ["mylib.cpp"], 6972 system_shared_libs: [], 6973 shared_libs: ["mylib", "myprivlib"], 6974 stl: "none", 6975 test_for: ["myapex"], 6976 } 6977 6978 cc_benchmark { 6979 name: "mybench", 6980 srcs: ["mylib.cpp"], 6981 system_shared_libs: [], 6982 shared_libs: ["mylib", "myprivlib"], 6983 stl: "none", 6984 test_for: ["myapex"], 6985 } 6986 `) 6987 6988 ensureLinkedLibIs := func(mod, variant, linkedLib, expectedVariant string) { 6989 ldFlags := strings.Split(ctx.ModuleForTests(mod, variant).Rule("ld").Args["libFlags"], " ") 6990 mylibLdFlags := android.FilterListPred(ldFlags, func(s string) bool { return strings.HasPrefix(s, linkedLib) }) 6991 android.AssertArrayString(t, "unexpected "+linkedLib+" link library for "+mod, []string{linkedLib + expectedVariant}, mylibLdFlags) 6992 } 6993 6994 // These modules are tests for the apex, therefore are linked to the 6995 // actual implementation of mylib instead of its stub. 6996 ensureLinkedLibIs("mytest", "android_arm64_armv8-a", "out/soong/.intermediates/mylib/", "android_arm64_armv8-a_shared/mylib.so") 6997 ensureLinkedLibIs("mytestlib", "android_arm64_armv8-a_shared", "out/soong/.intermediates/mylib/", "android_arm64_armv8-a_shared/mylib.so") 6998 ensureLinkedLibIs("mybench", "android_arm64_armv8-a", "out/soong/.intermediates/mylib/", "android_arm64_armv8-a_shared/mylib.so") 6999} 7000 7001func TestIndirectTestFor(t *testing.T) { 7002 ctx := testApex(t, ` 7003 apex { 7004 name: "myapex", 7005 key: "myapex.key", 7006 native_shared_libs: ["mylib", "myprivlib"], 7007 updatable: false, 7008 } 7009 7010 apex_key { 7011 name: "myapex.key", 7012 public_key: "testkey.avbpubkey", 7013 private_key: "testkey.pem", 7014 } 7015 7016 cc_library { 7017 name: "mylib", 7018 srcs: ["mylib.cpp"], 7019 system_shared_libs: [], 7020 stl: "none", 7021 stubs: { 7022 versions: ["1"], 7023 }, 7024 apex_available: ["myapex"], 7025 } 7026 7027 cc_library { 7028 name: "myprivlib", 7029 srcs: ["mylib.cpp"], 7030 system_shared_libs: [], 7031 stl: "none", 7032 shared_libs: ["mylib"], 7033 apex_available: ["myapex"], 7034 } 7035 7036 cc_library { 7037 name: "mytestlib", 7038 srcs: ["mylib.cpp"], 7039 system_shared_libs: [], 7040 shared_libs: ["myprivlib"], 7041 stl: "none", 7042 test_for: ["myapex"], 7043 } 7044 `) 7045 7046 ensureLinkedLibIs := func(mod, variant, linkedLib, expectedVariant string) { 7047 ldFlags := strings.Split(ctx.ModuleForTests(mod, variant).Rule("ld").Args["libFlags"], " ") 7048 mylibLdFlags := android.FilterListPred(ldFlags, func(s string) bool { return strings.HasPrefix(s, linkedLib) }) 7049 android.AssertArrayString(t, "unexpected "+linkedLib+" link library for "+mod, []string{linkedLib + expectedVariant}, mylibLdFlags) 7050 } 7051 7052 // The platform variant of mytestlib links to the platform variant of the 7053 // internal myprivlib. 7054 ensureLinkedLibIs("mytestlib", "android_arm64_armv8-a_shared", "out/soong/.intermediates/myprivlib/", "android_arm64_armv8-a_shared/myprivlib.so") 7055 7056 // The platform variant of myprivlib links to the platform variant of mylib 7057 // and bypasses its stubs. 7058 ensureLinkedLibIs("myprivlib", "android_arm64_armv8-a_shared", "out/soong/.intermediates/mylib/", "android_arm64_armv8-a_shared/mylib.so") 7059} 7060 7061func TestTestForForLibInOtherApex(t *testing.T) { 7062 // This case is only allowed for known overlapping APEXes, i.e. the ART APEXes. 7063 _ = testApex(t, ` 7064 apex { 7065 name: "com.android.art", 7066 key: "myapex.key", 7067 native_shared_libs: ["mylib"], 7068 updatable: false, 7069 } 7070 7071 apex { 7072 name: "com.android.art.debug", 7073 key: "myapex.key", 7074 native_shared_libs: ["mylib", "mytestlib"], 7075 updatable: false, 7076 } 7077 7078 apex_key { 7079 name: "myapex.key", 7080 public_key: "testkey.avbpubkey", 7081 private_key: "testkey.pem", 7082 } 7083 7084 cc_library { 7085 name: "mylib", 7086 srcs: ["mylib.cpp"], 7087 system_shared_libs: [], 7088 stl: "none", 7089 stubs: { 7090 versions: ["1"], 7091 }, 7092 apex_available: ["com.android.art", "com.android.art.debug"], 7093 } 7094 7095 cc_library { 7096 name: "mytestlib", 7097 srcs: ["mylib.cpp"], 7098 system_shared_libs: [], 7099 shared_libs: ["mylib"], 7100 stl: "none", 7101 apex_available: ["com.android.art.debug"], 7102 test_for: ["com.android.art"], 7103 } 7104 `, 7105 android.MockFS{ 7106 "system/sepolicy/apex/com.android.art-file_contexts": nil, 7107 "system/sepolicy/apex/com.android.art.debug-file_contexts": nil, 7108 }.AddToFixture()) 7109} 7110 7111// TODO(jungjw): Move this to proptools 7112func intPtr(i int) *int { 7113 return &i 7114} 7115 7116func TestApexSet(t *testing.T) { 7117 ctx := testApex(t, ` 7118 apex_set { 7119 name: "myapex", 7120 set: "myapex.apks", 7121 filename: "foo_v2.apex", 7122 overrides: ["foo"], 7123 } 7124 `, 7125 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 7126 variables.Platform_sdk_version = intPtr(30) 7127 }), 7128 android.FixtureModifyConfig(func(config android.Config) { 7129 config.Targets[android.Android] = []android.Target{ 7130 {Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}}, 7131 {Os: android.Android, Arch: android.Arch{ArchType: android.Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}}, 7132 } 7133 }), 7134 ) 7135 7136 m := ctx.ModuleForTests("myapex.apex.extractor", "android_common") 7137 7138 // Check extract_apks tool parameters. 7139 extractedApex := m.Output("extracted/myapex.apks") 7140 actual := extractedApex.Args["abis"] 7141 expected := "ARMEABI_V7A,ARM64_V8A" 7142 if actual != expected { 7143 t.Errorf("Unexpected abis parameter - expected %q vs actual %q", expected, actual) 7144 } 7145 actual = extractedApex.Args["sdk-version"] 7146 expected = "30" 7147 if actual != expected { 7148 t.Errorf("Unexpected abis parameter - expected %q vs actual %q", expected, actual) 7149 } 7150 7151 m = ctx.ModuleForTests("myapex", "android_common_myapex") 7152 a := m.Module().(*ApexSet) 7153 expectedOverrides := []string{"foo"} 7154 actualOverrides := android.AndroidMkEntriesForTest(t, ctx, a)[0].EntryMap["LOCAL_OVERRIDES_MODULES"] 7155 if !reflect.DeepEqual(actualOverrides, expectedOverrides) { 7156 t.Errorf("Incorrect LOCAL_OVERRIDES_MODULES - expected %q vs actual %q", expectedOverrides, actualOverrides) 7157 } 7158} 7159 7160func TestNoStaticLinkingToStubsLib(t *testing.T) { 7161 testApexError(t, `.*required by "mylib" is a native library providing stub.*`, ` 7162 apex { 7163 name: "myapex", 7164 key: "myapex.key", 7165 native_shared_libs: ["mylib"], 7166 updatable: false, 7167 } 7168 7169 apex_key { 7170 name: "myapex.key", 7171 public_key: "testkey.avbpubkey", 7172 private_key: "testkey.pem", 7173 } 7174 7175 cc_library { 7176 name: "mylib", 7177 srcs: ["mylib.cpp"], 7178 static_libs: ["otherlib"], 7179 system_shared_libs: [], 7180 stl: "none", 7181 apex_available: [ "myapex" ], 7182 } 7183 7184 cc_library { 7185 name: "otherlib", 7186 srcs: ["mylib.cpp"], 7187 system_shared_libs: [], 7188 stl: "none", 7189 stubs: { 7190 versions: ["1", "2", "3"], 7191 }, 7192 apex_available: [ "myapex" ], 7193 } 7194 `) 7195} 7196 7197func TestApexKeysTxt(t *testing.T) { 7198 ctx := testApex(t, ` 7199 apex { 7200 name: "myapex", 7201 key: "myapex.key", 7202 updatable: false, 7203 } 7204 7205 apex_key { 7206 name: "myapex.key", 7207 public_key: "testkey.avbpubkey", 7208 private_key: "testkey.pem", 7209 } 7210 7211 prebuilt_apex { 7212 name: "myapex", 7213 prefer: true, 7214 arch: { 7215 arm64: { 7216 src: "myapex-arm64.apex", 7217 }, 7218 arm: { 7219 src: "myapex-arm.apex", 7220 }, 7221 }, 7222 } 7223 7224 apex_set { 7225 name: "myapex_set", 7226 set: "myapex.apks", 7227 filename: "myapex_set.apex", 7228 overrides: ["myapex"], 7229 } 7230 `) 7231 7232 apexKeysText := ctx.SingletonForTests("apex_keys_text") 7233 content := apexKeysText.MaybeDescription("apexkeys.txt").BuildParams.Args["content"] 7234 ensureContains(t, content, `name="myapex_set.apex" public_key="PRESIGNED" private_key="PRESIGNED" container_certificate="PRESIGNED" container_private_key="PRESIGNED" partition="system"`) 7235 ensureContains(t, content, `name="myapex.apex" public_key="PRESIGNED" private_key="PRESIGNED" container_certificate="PRESIGNED" container_private_key="PRESIGNED" partition="system"`) 7236} 7237 7238func TestAllowedFiles(t *testing.T) { 7239 ctx := testApex(t, ` 7240 apex { 7241 name: "myapex", 7242 key: "myapex.key", 7243 apps: ["app"], 7244 allowed_files: "allowed.txt", 7245 updatable: false, 7246 } 7247 7248 apex_key { 7249 name: "myapex.key", 7250 public_key: "testkey.avbpubkey", 7251 private_key: "testkey.pem", 7252 } 7253 7254 android_app { 7255 name: "app", 7256 srcs: ["foo/bar/MyClass.java"], 7257 package_name: "foo", 7258 sdk_version: "none", 7259 system_modules: "none", 7260 apex_available: [ "myapex" ], 7261 } 7262 `, withFiles(map[string][]byte{ 7263 "sub/Android.bp": []byte(` 7264 override_apex { 7265 name: "override_myapex", 7266 base: "myapex", 7267 apps: ["override_app"], 7268 allowed_files: ":allowed", 7269 } 7270 // Overridable "path" property should be referenced indirectly 7271 filegroup { 7272 name: "allowed", 7273 srcs: ["allowed.txt"], 7274 } 7275 override_android_app { 7276 name: "override_app", 7277 base: "app", 7278 package_name: "bar", 7279 } 7280 `), 7281 })) 7282 7283 rule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("diffApexContentRule") 7284 if expected, actual := "allowed.txt", rule.Args["allowed_files_file"]; expected != actual { 7285 t.Errorf("allowed_files_file: expected %q but got %q", expected, actual) 7286 } 7287 7288 rule2 := ctx.ModuleForTests("myapex", "android_common_override_myapex_myapex_image").Rule("diffApexContentRule") 7289 if expected, actual := "sub/allowed.txt", rule2.Args["allowed_files_file"]; expected != actual { 7290 t.Errorf("allowed_files_file: expected %q but got %q", expected, actual) 7291 } 7292} 7293 7294func TestNonPreferredPrebuiltDependency(t *testing.T) { 7295 testApex(t, ` 7296 apex { 7297 name: "myapex", 7298 key: "myapex.key", 7299 native_shared_libs: ["mylib"], 7300 updatable: false, 7301 } 7302 7303 apex_key { 7304 name: "myapex.key", 7305 public_key: "testkey.avbpubkey", 7306 private_key: "testkey.pem", 7307 } 7308 7309 cc_library { 7310 name: "mylib", 7311 srcs: ["mylib.cpp"], 7312 stubs: { 7313 versions: ["current"], 7314 }, 7315 apex_available: ["myapex"], 7316 } 7317 7318 cc_prebuilt_library_shared { 7319 name: "mylib", 7320 prefer: false, 7321 srcs: ["prebuilt.so"], 7322 stubs: { 7323 versions: ["current"], 7324 }, 7325 apex_available: ["myapex"], 7326 } 7327 `) 7328} 7329 7330func TestCompressedApex(t *testing.T) { 7331 ctx := testApex(t, ` 7332 apex { 7333 name: "myapex", 7334 key: "myapex.key", 7335 compressible: true, 7336 updatable: false, 7337 } 7338 apex_key { 7339 name: "myapex.key", 7340 public_key: "testkey.avbpubkey", 7341 private_key: "testkey.pem", 7342 } 7343 `, 7344 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 7345 variables.CompressedApex = proptools.BoolPtr(true) 7346 }), 7347 ) 7348 7349 compressRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("compressRule") 7350 ensureContains(t, compressRule.Output.String(), "myapex.capex.unsigned") 7351 7352 signApkRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Description("sign compressedApex") 7353 ensureEquals(t, signApkRule.Input.String(), compressRule.Output.String()) 7354 7355 // Make sure output of bundle is .capex 7356 ab := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle) 7357 ensureContains(t, ab.outputFile.String(), "myapex.capex") 7358 7359 // Verify android.mk rules 7360 data := android.AndroidMkDataForTest(t, ctx, ab) 7361 var builder strings.Builder 7362 data.Custom(&builder, ab.BaseModuleName(), "TARGET_", "", data) 7363 androidMk := builder.String() 7364 ensureContains(t, androidMk, "LOCAL_MODULE_STEM := myapex.capex\n") 7365} 7366 7367func TestPreferredPrebuiltSharedLibDep(t *testing.T) { 7368 ctx := testApex(t, ` 7369 apex { 7370 name: "myapex", 7371 key: "myapex.key", 7372 native_shared_libs: ["mylib"], 7373 updatable: false, 7374 } 7375 7376 apex_key { 7377 name: "myapex.key", 7378 public_key: "testkey.avbpubkey", 7379 private_key: "testkey.pem", 7380 } 7381 7382 cc_library { 7383 name: "mylib", 7384 srcs: ["mylib.cpp"], 7385 apex_available: ["myapex"], 7386 shared_libs: ["otherlib"], 7387 system_shared_libs: [], 7388 } 7389 7390 cc_library { 7391 name: "otherlib", 7392 srcs: ["mylib.cpp"], 7393 stubs: { 7394 versions: ["current"], 7395 }, 7396 } 7397 7398 cc_prebuilt_library_shared { 7399 name: "otherlib", 7400 prefer: true, 7401 srcs: ["prebuilt.so"], 7402 stubs: { 7403 versions: ["current"], 7404 }, 7405 } 7406 `) 7407 7408 ab := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle) 7409 data := android.AndroidMkDataForTest(t, ctx, ab) 7410 var builder strings.Builder 7411 data.Custom(&builder, ab.BaseModuleName(), "TARGET_", "", data) 7412 androidMk := builder.String() 7413 7414 // The make level dependency needs to be on otherlib - prebuilt_otherlib isn't 7415 // a thing there. 7416 ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += otherlib\n") 7417} 7418 7419func TestExcludeDependency(t *testing.T) { 7420 ctx := testApex(t, ` 7421 apex { 7422 name: "myapex", 7423 key: "myapex.key", 7424 native_shared_libs: ["mylib"], 7425 updatable: false, 7426 } 7427 7428 apex_key { 7429 name: "myapex.key", 7430 public_key: "testkey.avbpubkey", 7431 private_key: "testkey.pem", 7432 } 7433 7434 cc_library { 7435 name: "mylib", 7436 srcs: ["mylib.cpp"], 7437 system_shared_libs: [], 7438 stl: "none", 7439 apex_available: ["myapex"], 7440 shared_libs: ["mylib2"], 7441 target: { 7442 apex: { 7443 exclude_shared_libs: ["mylib2"], 7444 }, 7445 }, 7446 } 7447 7448 cc_library { 7449 name: "mylib2", 7450 srcs: ["mylib.cpp"], 7451 system_shared_libs: [], 7452 stl: "none", 7453 } 7454 `) 7455 7456 // Check if mylib is linked to mylib2 for the non-apex target 7457 ldFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared").Rule("ld").Args["libFlags"] 7458 ensureContains(t, ldFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so") 7459 7460 // Make sure that the link doesn't occur for the apex target 7461 ldFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"] 7462 ensureNotContains(t, ldFlags, "mylib2/android_arm64_armv8-a_shared_apex10000/mylib2.so") 7463 7464 // It shouldn't appear in the copy cmd as well. 7465 copyCmds := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule").Args["copy_commands"] 7466 ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so") 7467} 7468 7469func TestPrebuiltStubLibDep(t *testing.T) { 7470 bpBase := ` 7471 apex { 7472 name: "myapex", 7473 key: "myapex.key", 7474 native_shared_libs: ["mylib"], 7475 updatable: false, 7476 } 7477 apex_key { 7478 name: "myapex.key", 7479 public_key: "testkey.avbpubkey", 7480 private_key: "testkey.pem", 7481 } 7482 cc_library { 7483 name: "mylib", 7484 srcs: ["mylib.cpp"], 7485 apex_available: ["myapex"], 7486 shared_libs: ["stublib"], 7487 system_shared_libs: [], 7488 } 7489 apex { 7490 name: "otherapex", 7491 enabled: %s, 7492 key: "myapex.key", 7493 native_shared_libs: ["stublib"], 7494 updatable: false, 7495 } 7496 ` 7497 7498 stublibSourceBp := ` 7499 cc_library { 7500 name: "stublib", 7501 srcs: ["mylib.cpp"], 7502 apex_available: ["otherapex"], 7503 system_shared_libs: [], 7504 stl: "none", 7505 stubs: { 7506 versions: ["1"], 7507 }, 7508 } 7509 ` 7510 7511 stublibPrebuiltBp := ` 7512 cc_prebuilt_library_shared { 7513 name: "stublib", 7514 srcs: ["prebuilt.so"], 7515 apex_available: ["otherapex"], 7516 stubs: { 7517 versions: ["1"], 7518 }, 7519 %s 7520 } 7521 ` 7522 7523 tests := []struct { 7524 name string 7525 stublibBp string 7526 usePrebuilt bool 7527 modNames []string // Modules to collect AndroidMkEntries for 7528 otherApexEnabled []string 7529 }{ 7530 { 7531 name: "only_source", 7532 stublibBp: stublibSourceBp, 7533 usePrebuilt: false, 7534 modNames: []string{"stublib"}, 7535 otherApexEnabled: []string{"true", "false"}, 7536 }, 7537 { 7538 name: "source_preferred", 7539 stublibBp: stublibSourceBp + fmt.Sprintf(stublibPrebuiltBp, ""), 7540 usePrebuilt: false, 7541 modNames: []string{"stublib", "prebuilt_stublib"}, 7542 otherApexEnabled: []string{"true", "false"}, 7543 }, 7544 { 7545 name: "prebuilt_preferred", 7546 stublibBp: stublibSourceBp + fmt.Sprintf(stublibPrebuiltBp, "prefer: true,"), 7547 usePrebuilt: true, 7548 modNames: []string{"stublib", "prebuilt_stublib"}, 7549 otherApexEnabled: []string{"false"}, // No "true" since APEX cannot depend on prebuilt. 7550 }, 7551 { 7552 name: "only_prebuilt", 7553 stublibBp: fmt.Sprintf(stublibPrebuiltBp, ""), 7554 usePrebuilt: true, 7555 modNames: []string{"stublib"}, 7556 otherApexEnabled: []string{"false"}, // No "true" since APEX cannot depend on prebuilt. 7557 }, 7558 } 7559 7560 for _, test := range tests { 7561 t.Run(test.name, func(t *testing.T) { 7562 for _, otherApexEnabled := range test.otherApexEnabled { 7563 t.Run("otherapex_enabled_"+otherApexEnabled, func(t *testing.T) { 7564 ctx := testApex(t, fmt.Sprintf(bpBase, otherApexEnabled)+test.stublibBp) 7565 7566 type modAndMkEntries struct { 7567 mod *cc.Module 7568 mkEntries android.AndroidMkEntries 7569 } 7570 entries := []*modAndMkEntries{} 7571 7572 // Gather shared lib modules that are installable 7573 for _, modName := range test.modNames { 7574 for _, variant := range ctx.ModuleVariantsForTests(modName) { 7575 if !strings.HasPrefix(variant, "android_arm64_armv8-a_shared") { 7576 continue 7577 } 7578 mod := ctx.ModuleForTests(modName, variant).Module().(*cc.Module) 7579 if !mod.Enabled() || mod.IsHideFromMake() { 7580 continue 7581 } 7582 for _, ent := range android.AndroidMkEntriesForTest(t, ctx, mod) { 7583 if ent.Disabled { 7584 continue 7585 } 7586 entries = append(entries, &modAndMkEntries{ 7587 mod: mod, 7588 mkEntries: ent, 7589 }) 7590 } 7591 } 7592 } 7593 7594 var entry *modAndMkEntries = nil 7595 for _, ent := range entries { 7596 if strings.Join(ent.mkEntries.EntryMap["LOCAL_MODULE"], ",") == "stublib" { 7597 if entry != nil { 7598 t.Errorf("More than one AndroidMk entry for \"stublib\": %s and %s", entry.mod, ent.mod) 7599 } else { 7600 entry = ent 7601 } 7602 } 7603 } 7604 7605 if entry == nil { 7606 t.Errorf("AndroidMk entry for \"stublib\" missing") 7607 } else { 7608 isPrebuilt := entry.mod.Prebuilt() != nil 7609 if isPrebuilt != test.usePrebuilt { 7610 t.Errorf("Wrong module for \"stublib\" AndroidMk entry: got prebuilt %t, want prebuilt %t", isPrebuilt, test.usePrebuilt) 7611 } 7612 if !entry.mod.IsStubs() { 7613 t.Errorf("Module for \"stublib\" AndroidMk entry isn't a stub: %s", entry.mod) 7614 } 7615 if entry.mkEntries.EntryMap["LOCAL_NOT_AVAILABLE_FOR_PLATFORM"] != nil { 7616 t.Errorf("AndroidMk entry for \"stublib\" has LOCAL_NOT_AVAILABLE_FOR_PLATFORM set: %+v", entry.mkEntries) 7617 } 7618 cflags := entry.mkEntries.EntryMap["LOCAL_EXPORT_CFLAGS"] 7619 expected := "-D__STUBLIB_API__=10000" 7620 if !android.InList(expected, cflags) { 7621 t.Errorf("LOCAL_EXPORT_CFLAGS expected to have %q, but got %q", expected, cflags) 7622 } 7623 } 7624 }) 7625 } 7626 }) 7627 } 7628} 7629 7630func TestApexJavaCoverage(t *testing.T) { 7631 bp := ` 7632 apex { 7633 name: "myapex", 7634 key: "myapex.key", 7635 java_libs: ["mylib"], 7636 bootclasspath_fragments: ["mybootclasspathfragment"], 7637 systemserverclasspath_fragments: ["mysystemserverclasspathfragment"], 7638 updatable: false, 7639 } 7640 7641 apex_key { 7642 name: "myapex.key", 7643 public_key: "testkey.avbpubkey", 7644 private_key: "testkey.pem", 7645 } 7646 7647 java_library { 7648 name: "mylib", 7649 srcs: ["mylib.java"], 7650 apex_available: ["myapex"], 7651 compile_dex: true, 7652 } 7653 7654 bootclasspath_fragment { 7655 name: "mybootclasspathfragment", 7656 contents: ["mybootclasspathlib"], 7657 apex_available: ["myapex"], 7658 } 7659 7660 java_library { 7661 name: "mybootclasspathlib", 7662 srcs: ["mybootclasspathlib.java"], 7663 apex_available: ["myapex"], 7664 compile_dex: true, 7665 } 7666 7667 systemserverclasspath_fragment { 7668 name: "mysystemserverclasspathfragment", 7669 contents: ["mysystemserverclasspathlib"], 7670 apex_available: ["myapex"], 7671 } 7672 7673 java_library { 7674 name: "mysystemserverclasspathlib", 7675 srcs: ["mysystemserverclasspathlib.java"], 7676 apex_available: ["myapex"], 7677 compile_dex: true, 7678 } 7679 ` 7680 7681 result := android.GroupFixturePreparers( 7682 PrepareForTestWithApexBuildComponents, 7683 prepareForTestWithMyapex, 7684 java.PrepareForTestWithJavaDefaultModules, 7685 android.PrepareForTestWithAndroidBuildComponents, 7686 android.FixtureWithRootAndroidBp(bp), 7687 android.FixtureMergeEnv(map[string]string{ 7688 "EMMA_INSTRUMENT": "true", 7689 }), 7690 ).RunTest(t) 7691 7692 // Make sure jacoco ran on both mylib and mybootclasspathlib 7693 if result.ModuleForTests("mylib", "android_common_apex10000").MaybeRule("jacoco").Rule == nil { 7694 t.Errorf("Failed to find jacoco rule for mylib") 7695 } 7696 if result.ModuleForTests("mybootclasspathlib", "android_common_apex10000").MaybeRule("jacoco").Rule == nil { 7697 t.Errorf("Failed to find jacoco rule for mybootclasspathlib") 7698 } 7699 if result.ModuleForTests("mysystemserverclasspathlib", "android_common_apex10000").MaybeRule("jacoco").Rule == nil { 7700 t.Errorf("Failed to find jacoco rule for mysystemserverclasspathlib") 7701 } 7702} 7703 7704func TestMain(m *testing.M) { 7705 os.Exit(m.Run()) 7706} 7707