From 344d5439c145baddbe85297a5c435da28ee6fcff Mon Sep 17 00:00:00 2001 From: Jooyung Han Date: Fri, 23 Aug 2019 11:17:39 +0900 Subject: Add "apex_vndk" module type "apex_vndk" is a variant of "apex" module. apex_vndk { name: "com.android.vndk", .. } This rule is used to produce a VNDK APEX per vndk version. It supports automatic inclusion of vndk libs. If "vndk_version" property is set, the prebuilt vndk libs of the version will be included in the apex bundle. apex_vndk { name: "com.android.vndk.v29" vndk_version: "29", ... } Otherwise, platform's vndk version is used. This will replace /system/{lib}/vndk-{ver} and vndk-sp-{ver}. Bug: 134357236 Bug: 139772411 Test: m com.android.vndk Change-Id: Ib5c86e625839389670d13c683a7427198ef6852f --- apex/apex_test.go | 336 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 320 insertions(+), 16 deletions(-) (limited to 'apex/apex_test.go') diff --git a/apex/apex_test.go b/apex/apex_test.go index e2d85aea0..7f36f51e1 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -40,8 +40,9 @@ func names(s string) (ns []string) { return } -func testApexError(t *testing.T, pattern, bp string) { - ctx, config := testApexContext(t, bp) +func testApexError(t *testing.T, pattern, bp string, handlers ...testCustomizer) { + t.Helper() + ctx, config := testApexContext(t, bp, handlers...) _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) if len(errs) > 0 { android.FailIfNoMatchingErrors(t, pattern, errs) @@ -56,8 +57,9 @@ func testApexError(t *testing.T, pattern, bp string) { t.Fatalf("missing expected error %q (0 errors are returned)", pattern) } -func testApex(t *testing.T, bp string) (*android.TestContext, android.Config) { - ctx, config := testApexContext(t, bp) +func testApex(t *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) { + t.Helper() + ctx, config := testApexContext(t, bp, handlers...) _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) android.FailIfErrored(t, errs) _, errs = ctx.PrepareBuildActions(config) @@ -65,37 +67,52 @@ func testApex(t *testing.T, bp string) (*android.TestContext, android.Config) { return ctx, config } -func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Config) { +type testCustomizer func(fs map[string][]byte, config android.Config) + +func withFiles(files map[string][]byte) testCustomizer { + return func(fs map[string][]byte, config android.Config) { + for k, v := range files { + fs[k] = v + } + } +} + +func withTargets(targets map[android.OsType][]android.Target) testCustomizer { + return func(fs map[string][]byte, config android.Config) { + for k, v := range targets { + config.Targets[k] = v + } + } +} + +func testApexContext(t *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) { config := android.TestArchConfig(buildDir, nil) config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("current") config.TestProductVariables.DefaultAppCertificate = proptools.StringPtr("vendor/foo/devkeys/test") config.TestProductVariables.CertificateOverrides = []string{"myapex_keytest:myapex.certificate.override"} config.TestProductVariables.Platform_sdk_codename = proptools.StringPtr("Q") config.TestProductVariables.Platform_sdk_final = proptools.BoolPtr(false) + config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("current") + config.TestProductVariables.Platform_vndk_version = proptools.StringPtr("VER") ctx := android.NewTestArchContext() ctx.RegisterModuleType("apex", android.ModuleFactoryAdaptor(apexBundleFactory)) ctx.RegisterModuleType("apex_test", android.ModuleFactoryAdaptor(testApexBundleFactory)) + ctx.RegisterModuleType("apex_vndk", android.ModuleFactoryAdaptor(vndkApexBundleFactory)) ctx.RegisterModuleType("apex_key", android.ModuleFactoryAdaptor(apexKeyFactory)) ctx.RegisterModuleType("apex_defaults", android.ModuleFactoryAdaptor(defaultsFactory)) ctx.RegisterModuleType("prebuilt_apex", android.ModuleFactoryAdaptor(PrebuiltFactory)) - ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators) - - ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { - ctx.TopDown("apex_deps", apexDepsMutator) - ctx.BottomUp("apex", apexMutator) - ctx.BottomUp("apex_uses", apexUsesMutator) - ctx.TopDown("prebuilt_select", android.PrebuiltSelectModuleMutator).Parallel() - ctx.BottomUp("prebuilt_postdeps", android.PrebuiltPostDepsMutator).Parallel() - }) ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(cc.LibraryFactory)) ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(cc.LibrarySharedFactory)) ctx.RegisterModuleType("cc_library_headers", android.ModuleFactoryAdaptor(cc.LibraryHeaderFactory)) + ctx.RegisterModuleType("cc_prebuilt_library_shared", android.ModuleFactoryAdaptor(cc.PrebuiltSharedLibraryFactory)) + ctx.RegisterModuleType("cc_prebuilt_library_static", android.ModuleFactoryAdaptor(cc.PrebuiltStaticLibraryFactory)) ctx.RegisterModuleType("cc_binary", android.ModuleFactoryAdaptor(cc.BinaryFactory)) ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(cc.ObjectFactory)) ctx.RegisterModuleType("cc_test", android.ModuleFactoryAdaptor(cc.TestFactory)) ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(cc.LlndkLibraryFactory)) + ctx.RegisterModuleType("vndk_prebuilt_shared", android.ModuleFactoryAdaptor(cc.VndkPrebuiltSharedFactory)) ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(cc.ToolchainLibraryFactory)) ctx.RegisterModuleType("prebuilt_etc", android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory)) ctx.RegisterModuleType("sh_binary", android.ModuleFactoryAdaptor(android.ShBinaryFactory)) @@ -105,6 +122,7 @@ func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Con ctx.RegisterModuleType("java_import", android.ModuleFactoryAdaptor(java.ImportFactory)) ctx.RegisterModuleType("android_app", android.ModuleFactoryAdaptor(java.AndroidAppFactory)) + ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators) ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) { ctx.BottomUp("prebuilts", android.PrebuiltMutator).Parallel() }) @@ -115,6 +133,15 @@ func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Con ctx.BottomUp("test_per_src", cc.TestPerSrcMutator).Parallel() ctx.BottomUp("version", cc.VersionMutator).Parallel() ctx.BottomUp("begin", cc.BeginMutator).Parallel() + ctx.TopDown("apex_vndk_gather", apexVndkGatherMutator) + ctx.BottomUp("apex_vndk_add_deps", apexVndkAddDepsMutator) + }) + ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { + ctx.TopDown("apex_deps", apexDepsMutator) + ctx.BottomUp("apex", apexMutator) + ctx.BottomUp("apex_uses", apexUsesMutator) + ctx.TopDown("prebuilt_select", android.PrebuiltSelectModuleMutator).Parallel() + ctx.BottomUp("prebuilt_postdeps", android.PrebuiltPostDepsMutator).Parallel() }) ctx.Register() @@ -132,6 +159,7 @@ func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Con src: "", vendor_available: true, recovery_available: true, + native_bridge_supported: true, } toolchain_library { @@ -146,6 +174,7 @@ func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Con src: "", vendor_available: true, recovery_available: true, + native_bridge_supported: true, } toolchain_library { @@ -153,6 +182,7 @@ func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Con src: "", vendor_available: true, recovery_available: true, + native_bridge_supported: true, } toolchain_library { @@ -160,6 +190,23 @@ func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Con src: "", vendor_available: true, recovery_available: true, + native_bridge_supported: true, + } + + toolchain_library { + name: "libclang_rt.builtins-x86_64-android", + src: "", + vendor_available: true, + recovery_available: true, + native_bridge_supported: true, + } + + toolchain_library { + name: "libclang_rt.builtins-i686-android", + src: "", + vendor_available: true, + recovery_available: true, + native_bridge_supported: true, } cc_object { @@ -167,6 +214,7 @@ func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Con stl: "none", vendor_available: true, recovery_available: true, + native_bridge_supported: true, } cc_object { @@ -174,6 +222,7 @@ func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Con stl: "none", vendor_available: true, recovery_available: true, + native_bridge_supported: true, } cc_object { @@ -189,20 +238,23 @@ func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Con llndk_library { name: "libc", symbol_file: "", + native_bridge_supported: true, } llndk_library { name: "libm", symbol_file: "", + native_bridge_supported: true, } llndk_library { name: "libdl", symbol_file: "", + native_bridge_supported: true, } ` - ctx.MockFileSystem(map[string][]byte{ + fs := map[string][]byte{ "Android.bp": []byte(bp), "build/make/target/product/security": nil, "apex_manifest.json": nil, @@ -238,7 +290,13 @@ func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Con "frameworks/base/api/current.txt": nil, "build/make/core/proguard.flags": nil, "build/make/core/proguard_basic_keeps.flags": nil, - }) + } + + for _, handler := range handlers { + handler(fs, config) + } + + ctx.MockFileSystem(fs) return ctx, config } @@ -1210,6 +1268,252 @@ func TestHeaderLibsDependency(t *testing.T) { ensureContains(t, cFlags, "-Imy_include") } +func TestVndkApexCurrent(t *testing.T) { + ctx, _ := testApex(t, ` + apex_vndk { + name: "myapex", + key: "myapex.key", + file_contexts: "myapex", + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + cc_library { + name: "libvndk", + srcs: ["mylib.cpp"], + vendor_available: true, + vndk: { + enabled: true, + }, + system_shared_libs: [], + stl: "none", + } + + cc_library { + name: "libvndksp", + srcs: ["mylib.cpp"], + vendor_available: true, + vndk: { + enabled: true, + support_system_process: true, + }, + system_shared_libs: [], + stl: "none", + } + `) + + apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule") + copyCmds := apexRule.Args["copy_commands"] + ensureContains(t, copyCmds, "image.apex/lib/libvndk.so") + ensureContains(t, copyCmds, "image.apex/lib/libvndksp.so") + ensureContains(t, copyCmds, "image.apex/lib64/libvndk.so") + ensureContains(t, copyCmds, "image.apex/lib64/libvndksp.so") +} + +func TestVndkApexWithPrebuilt(t *testing.T) { + ctx, _ := testApex(t, ` + apex_vndk { + name: "myapex", + key: "myapex.key", + file_contexts: "myapex", + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + cc_prebuilt_library_shared { + name: "libvndkshared", + srcs: ["libvndkshared.so"], + vendor_available: true, + vndk: { + enabled: true, + }, + system_shared_libs: [], + stl: "none", + } + `, withFiles(map[string][]byte{ + "libvndkshared.so": nil, + })) + + apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule") + copyCmds := apexRule.Args["copy_commands"] + ensureContains(t, copyCmds, "image.apex/lib/libvndkshared.so") +} + +func TestVndkApexVersion(t *testing.T) { + ctx, _ := testApex(t, ` + apex_vndk { + name: "myapex_v27", + key: "myapex.key", + file_contexts: "myapex", + vndk_version: "27", + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + cc_library { + name: "libvndk", + srcs: ["mylib.cpp"], + vendor_available: true, + vndk: { + enabled: true, + }, + system_shared_libs: [], + stl: "none", + } + + vndk_prebuilt_shared { + name: "libvndk27", + version: "27", + vendor_available: true, + vndk: { + enabled: true, + }, + srcs: ["libvndk27.so"], + } + `, withFiles(map[string][]byte{ + "libvndk27.so": nil, + })) + + apexRule := ctx.ModuleForTests("myapex_v27", "android_common_myapex_v27").Rule("apexRule") + copyCmds := apexRule.Args["copy_commands"] + ensureContains(t, copyCmds, "image.apex/lib/libvndk27.so") + ensureContains(t, copyCmds, "image.apex/lib64/libvndk27.so") + ensureNotContains(t, copyCmds, "image.apex/lib/libvndk.so") +} + +func TestVndkApexErrorWithDuplicateVersion(t *testing.T) { + testApexError(t, `module "myapex_v27.*" .*: vndk_version: 27 is already defined in "myapex_v27.*"`, ` + apex_vndk { + name: "myapex_v27", + key: "myapex.key", + file_contexts: "myapex", + vndk_version: "27", + } + apex_vndk { + name: "myapex_v27_other", + key: "myapex.key", + file_contexts: "myapex", + vndk_version: "27", + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + cc_library { + name: "libvndk", + srcs: ["mylib.cpp"], + vendor_available: true, + vndk: { + enabled: true, + }, + system_shared_libs: [], + stl: "none", + } + + vndk_prebuilt_shared { + name: "libvndk", + version: "27", + vendor_available: true, + vndk: { + enabled: true, + }, + srcs: ["libvndk.so"], + } + `, withFiles(map[string][]byte{ + "libvndk.so": nil, + })) +} + +func TestVndkApexSkipsNativeBridgeSupportedModules(t *testing.T) { + ctx, _ := testApex(t, ` + apex_vndk { + name: "myapex", + key: "myapex.key", + file_contexts: "myapex", + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + cc_library { + name: "libvndk", + srcs: ["mylib.cpp"], + vendor_available: true, + native_bridge_supported: true, + host_supported: true, + vndk: { + enabled: true, + }, + system_shared_libs: [], + stl: "none", + } + `, withTargets(map[android.OsType][]android.Target{ + android.Android: []android.Target{ + {Os: android.Android, Arch: android.Arch{ArchType: android.Arm64, ArchVariant: "armv8-a", Native: true, Abi: []string{"arm64-v8a"}}, NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""}, + {Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Native: true, Abi: []string{"armeabi-v7a"}}, NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""}, + {Os: android.Android, Arch: android.Arch{ArchType: android.X86_64, ArchVariant: "silvermont", Native: true, Abi: []string{"arm64-v8a"}}, NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "arm64", NativeBridgeRelativePath: "x86_64"}, + {Os: android.Android, Arch: android.Arch{ArchType: android.X86, ArchVariant: "silvermont", Native: true, Abi: []string{"armeabi-v7a"}}, NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "arm", NativeBridgeRelativePath: "x86"}, + }, + })) + + apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule") + copyCmds := apexRule.Args["copy_commands"] + ensureContains(t, copyCmds, "image.apex/lib/libvndk.so") + ensureContains(t, copyCmds, "image.apex/lib64/libvndk.so") + + // apex + ensureNotContains(t, copyCmds, "image.apex/lib/x86/libvndk.so") + ensureNotContains(t, copyCmds, "image.apex/lib64/x86_64/libvndk.so") +} + +func TestVndkApexDoesntSupportNativeBridgeSupported(t *testing.T) { + testApexError(t, `module "myapex" .*: native_bridge_supported: .* doesn't support native bridge binary`, ` + apex_vndk { + name: "myapex", + key: "myapex.key", + file_contexts: "myapex", + native_bridge_supported: true, + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + cc_library { + name: "libvndk", + srcs: ["mylib.cpp"], + vendor_available: true, + native_bridge_supported: true, + host_supported: true, + vndk: { + enabled: true, + }, + system_shared_libs: [], + stl: "none", + } + `) +} + func TestDependenciesInApexManifest(t *testing.T) { ctx, _ := testApex(t, ` apex { -- cgit v1.2.3-59-g8ed1b