summaryrefslogtreecommitdiff
path: root/apex
diff options
context:
space:
mode:
Diffstat (limited to 'apex')
-rw-r--r--apex/apex.go54
-rw-r--r--apex/apex_test.go333
-rw-r--r--apex/bootclasspath_fragment_test.go498
-rw-r--r--apex/platform_bootclasspath_test.go59
-rw-r--r--apex/prebuilt.go19
5 files changed, 884 insertions, 79 deletions
diff --git a/apex/apex.go b/apex/apex.go
index 7ffa6cc81..baaf87475 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -130,6 +130,10 @@ type apexBundleProperties struct {
// symlinking to the system libs. Default is true.
Updatable *bool
+ // Whether this APEX can use platform APIs or not. Can be set to true only when `updatable:
+ // false`. Default is false.
+ Platform_apis *bool
+
// Whether this APEX is installable to one of the partitions like system, vendor, etc.
// Default: true.
Installable *bool
@@ -182,6 +186,12 @@ type apexBundleProperties struct {
// used in tests.
Test_only_force_compression *bool
+ // Canonical name of this APEX bundle. Used to determine the path to the
+ // activated APEX on device (i.e. /apex/<apexVariationName>), and used for the
+ // apex mutator variations. For override_apex modules, this is the name of the
+ // overridden base module.
+ ApexVariationName string `blueprint:"mutated"`
+
IsCoverageVariant bool `blueprint:"mutated"`
// List of sanitizer names that this APEX is enabled for
@@ -824,6 +834,10 @@ var ApexBundleInfoProvider = blueprint.NewMutatorProvider(ApexBundleInfo{}, "ape
var _ ApexInfoMutator = (*apexBundle)(nil)
+func (a *apexBundle) ApexVariationName() string {
+ return a.properties.ApexVariationName
+}
+
// ApexInfoMutator is responsible for collecting modules that need to have apex variants. They are
// identified by doing a graph walk starting from an apexBundle. Basically, all the (direct and
// indirect) dependencies are collected. But a few types of modules that shouldn't be included in
@@ -912,15 +926,16 @@ func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) {
// This is the main part of this mutator. Mark the collected dependencies that they need to
// be built for this apexBundle.
- // Note that there are many different names.
- // ApexVariationName: this is the name of the apex variation
+ apexVariationName := proptools.StringDefault(a.properties.Apex_name, mctx.ModuleName()) // could be com.android.foo
+ a.properties.ApexVariationName = apexVariationName
apexInfo := android.ApexInfo{
- ApexVariationName: mctx.ModuleName(), // could be com.android.foo
+ ApexVariationName: apexVariationName,
MinSdkVersion: minSdkVersion,
RequiredSdks: a.RequiredSdks(),
Updatable: a.Updatable(),
- InApexVariants: []string{mctx.ModuleName()}, // could be com.android.foo
- InApexModules: []string{a.Name()}, // could be com.mycompany.android.foo
+ UsePlatformApis: a.UsePlatformApis(),
+ InApexVariants: []string{apexVariationName},
+ InApexModules: []string{a.Name()}, // could be com.mycompany.android.foo
ApexContents: []*android.ApexContents{apexContents},
}
mctx.WalkDeps(func(child, parent android.Module) bool {
@@ -933,6 +948,10 @@ func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) {
}
type ApexInfoMutator interface {
+ // ApexVariationName returns the name of the APEX variation to use in the apex
+ // mutator etc. It is the same name as ApexInfo.ApexVariationName.
+ ApexVariationName() string
+
// ApexInfoMutator implementations must call BuildForApex(ApexInfo) on any modules that are
// depended upon by an apex and which require an apex specific variant.
ApexInfoMutator(android.TopDownMutatorContext)
@@ -1058,10 +1077,8 @@ func apexMutator(mctx android.BottomUpMutatorContext) {
}
// apexBundle itself is mutated so that it and its dependencies have the same apex variant.
- // TODO(jiyong): document the reason why the VNDK APEX is an exception here.
- unprefixedModuleName := android.RemoveOptionalPrebuiltPrefix(mctx.ModuleName())
- if apexModuleTypeRequiresVariant(mctx.Module()) {
- apexBundleName := unprefixedModuleName
+ if ai, ok := mctx.Module().(ApexInfoMutator); ok && apexModuleTypeRequiresVariant(ai) {
+ apexBundleName := ai.ApexVariationName()
mctx.CreateVariations(apexBundleName)
if strings.HasPrefix(apexBundleName, "com.android.art") {
// Create an alias from the platform variant. This is done to make
@@ -1084,6 +1101,7 @@ func apexMutator(mctx android.BottomUpMutatorContext) {
// apex variant name. This name matches the name used to create the variations of modules for
// which apexModuleTypeRequiresVariant return true.
// TODO(b/191269918): Remove this workaround.
+ unprefixedModuleName := android.RemoveOptionalPrebuiltPrefix(mctx.ModuleName())
mctx.SetDefaultDependencyVariation(&unprefixedModuleName)
mctx.CreateVariations(apexBundleName)
if strings.HasPrefix(apexBundleName, "com.android.art") {
@@ -1095,18 +1113,13 @@ func apexMutator(mctx android.BottomUpMutatorContext) {
// apexModuleTypeRequiresVariant determines whether the module supplied requires an apex specific
// variant.
-func apexModuleTypeRequiresVariant(module android.Module) bool {
+func apexModuleTypeRequiresVariant(module ApexInfoMutator) bool {
if a, ok := module.(*apexBundle); ok {
+ // TODO(jiyong): document the reason why the VNDK APEX is an exception here.
return !a.vndkApex
}
- // Match apex_set and prebuilt_apex. Would also match apexBundle but that is handled specially
- // above.
- if _, ok := module.(ApexInfoMutator); ok {
- return true
- }
-
- return false
+ return true
}
// See android.UpdateDirectlyInAnyApex
@@ -1321,6 +1334,10 @@ func (a *apexBundle) Updatable() bool {
return proptools.BoolDefault(a.properties.Updatable, true)
}
+func (a *apexBundle) UsePlatformApis() bool {
+ return proptools.BoolDefault(a.properties.Platform_apis, false)
+}
+
// getCertString returns the name of the cert that should be used to sign this APEX. This is
// basically from the "certificate" property, but could be overridden by the device config.
func (a *apexBundle) getCertString(ctx android.BaseModuleContext) string {
@@ -2374,6 +2391,9 @@ func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
if String(a.properties.Min_sdk_version) == "" {
ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
}
+ if a.UsePlatformApis() {
+ ctx.PropertyErrorf("updatable", "updatable APEXes can't use platform APIs")
+ }
a.checkJavaStableSdkVersion(ctx)
a.checkClasspathFragments(ctx)
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 88da21bdc..b5b1d4401 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -839,6 +839,7 @@ func TestApexWithStubs(t *testing.T) {
name: "myapex",
key: "myapex.key",
native_shared_libs: ["mylib", "mylib3"],
+ binaries: ["foo.rust"],
updatable: false,
}
@@ -887,6 +888,25 @@ func TestApexWithStubs(t *testing.T) {
stl: "none",
apex_available: [ "myapex" ],
}
+
+ rust_binary {
+ name: "foo.rust",
+ srcs: ["foo.rs"],
+ shared_libs: ["libfoo.shared_from_rust"],
+ prefer_rlib: true,
+ apex_available: ["myapex"],
+ }
+
+ cc_library_shared {
+ name: "libfoo.shared_from_rust",
+ srcs: ["mylib.cpp"],
+ system_shared_libs: [],
+ stl: "none",
+ stubs: {
+ versions: ["10", "11", "12"],
+ },
+ }
+
`)
apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
@@ -924,7 +944,90 @@ func TestApexWithStubs(t *testing.T) {
"lib64/mylib.so",
"lib64/mylib3.so",
"lib64/mylib4.so",
+ "bin/foo.rust",
+ "lib64/libc++.so", // by the implicit dependency from foo.rust
+ "lib64/liblog.so", // by the implicit dependency from foo.rust
})
+
+ // Ensure that stub dependency from a rust module is not included
+ ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.shared_from_rust.so")
+ // The rust module is linked to the stub cc library
+ rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustc").Args["linkFlags"]
+ ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so")
+ ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so")
+}
+
+func TestApexCanUsePrivateApis(t *testing.T) {
+ ctx := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ native_shared_libs: ["mylib"],
+ binaries: ["foo.rust"],
+ updatable: false,
+ platform_apis: true,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library {
+ name: "mylib",
+ srcs: ["mylib.cpp"],
+ shared_libs: ["mylib2"],
+ system_shared_libs: [],
+ stl: "none",
+ apex_available: [ "myapex" ],
+ }
+
+ cc_library {
+ name: "mylib2",
+ srcs: ["mylib.cpp"],
+ cflags: ["-include mylib.h"],
+ system_shared_libs: [],
+ stl: "none",
+ stubs: {
+ versions: ["1", "2", "3"],
+ },
+ }
+
+ rust_binary {
+ name: "foo.rust",
+ srcs: ["foo.rs"],
+ shared_libs: ["libfoo.shared_from_rust"],
+ prefer_rlib: true,
+ apex_available: ["myapex"],
+ }
+
+ cc_library_shared {
+ name: "libfoo.shared_from_rust",
+ srcs: ["mylib.cpp"],
+ system_shared_libs: [],
+ stl: "none",
+ stubs: {
+ versions: ["10", "11", "12"],
+ },
+ }
+ `)
+
+ apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
+ copyCmds := apexRule.Args["copy_commands"]
+
+ // Ensure that indirect stubs dep is not included
+ ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so")
+ ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.shared_from_rust.so")
+
+ // Ensure that we are using non-stub variants of mylib2 and libfoo.shared_from_rust (because
+ // of the platform_apis: true)
+ mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000_private").Rule("ld").Args["libFlags"]
+ ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_current/mylib2.so")
+ ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so")
+ rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000_private").Rule("rustc").Args["linkFlags"]
+ ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so")
+ ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so")
}
func TestApexWithStubsWithMinSdkVersion(t *testing.T) {
@@ -1695,6 +1798,36 @@ func TestApexMinSdkVersion_SupportsCodeNames(t *testing.T) {
expectNoLink("libx", "shared_apex10000", "libz", "shared")
}
+func TestApexMinSdkVersion_SupportsCodeNames_JavaLibs(t *testing.T) {
+ testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ java_libs: ["libx"],
+ min_sdk_version: "S",
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ java_library {
+ name: "libx",
+ srcs: ["a.java"],
+ apex_available: [ "myapex" ],
+ sdk_version: "current",
+ min_sdk_version: "S", // should be okay
+ }
+ `,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.Platform_version_active_codenames = []string{"S"}
+ variables.Platform_sdk_codename = proptools.StringPtr("S")
+ }),
+ )
+}
+
func TestApexMinSdkVersion_DefaultsToLatest(t *testing.T) {
ctx := testApex(t, `
apex {
@@ -3338,60 +3471,109 @@ func ensureExactContents(t *testing.T, ctx *android.TestContext, moduleName, var
}
func TestVndkApexCurrent(t *testing.T) {
- ctx := testApex(t, `
- apex_vndk {
- name: "com.android.vndk.current",
- key: "com.android.vndk.current.key",
- updatable: false,
- }
-
- apex_key {
- name: "com.android.vndk.current.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
-
- cc_library {
- name: "libvndk",
- srcs: ["mylib.cpp"],
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "com.android.vndk.current" ],
- }
-
- cc_library {
- name: "libvndksp",
- srcs: ["mylib.cpp"],
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "com.android.vndk.current" ],
- }
- `+vndkLibrariesTxtFiles("current"))
-
- ensureExactContents(t, ctx, "com.android.vndk.current", "android_common_image", []string{
- "lib/libvndk.so",
- "lib/libvndksp.so",
+ commonFiles := []string{
"lib/libc++.so",
- "lib64/libvndk.so",
- "lib64/libvndksp.so",
"lib64/libc++.so",
"etc/llndk.libraries.29.txt",
"etc/vndkcore.libraries.29.txt",
"etc/vndksp.libraries.29.txt",
"etc/vndkprivate.libraries.29.txt",
"etc/vndkproduct.libraries.29.txt",
- })
+ }
+ testCases := []struct {
+ vndkVersion string
+ expectedFiles []string
+ }{
+ {
+ vndkVersion: "current",
+ expectedFiles: append(commonFiles,
+ "lib/libvndk.so",
+ "lib/libvndksp.so",
+ "lib64/libvndk.so",
+ "lib64/libvndksp.so"),
+ },
+ {
+ vndkVersion: "",
+ expectedFiles: append(commonFiles,
+ // Legacy VNDK APEX contains only VNDK-SP files (of core variant)
+ "lib/libvndksp.so",
+ "lib64/libvndksp.so"),
+ },
+ }
+ for _, tc := range testCases {
+ t.Run("VNDK.current with DeviceVndkVersion="+tc.vndkVersion, func(t *testing.T) {
+ ctx := testApex(t, `
+ apex_vndk {
+ name: "com.android.vndk.current",
+ key: "com.android.vndk.current.key",
+ updatable: false,
+ }
+
+ apex_key {
+ name: "com.android.vndk.current.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library {
+ name: "libvndk",
+ srcs: ["mylib.cpp"],
+ vendor_available: true,
+ product_available: true,
+ vndk: {
+ enabled: true,
+ },
+ system_shared_libs: [],
+ stl: "none",
+ apex_available: [ "com.android.vndk.current" ],
+ }
+
+ cc_library {
+ name: "libvndksp",
+ srcs: ["mylib.cpp"],
+ vendor_available: true,
+ product_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
+ system_shared_libs: [],
+ stl: "none",
+ apex_available: [ "com.android.vndk.current" ],
+ }
+
+ // VNDK-Ext should not cause any problems
+
+ cc_library {
+ name: "libvndk.ext",
+ srcs: ["mylib2.cpp"],
+ vendor: true,
+ vndk: {
+ enabled: true,
+ extends: "libvndk",
+ },
+ system_shared_libs: [],
+ stl: "none",
+ }
+
+ cc_library {
+ name: "libvndksp.ext",
+ srcs: ["mylib2.cpp"],
+ vendor: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ extends: "libvndksp",
+ },
+ system_shared_libs: [],
+ stl: "none",
+ }
+ `+vndkLibrariesTxtFiles("current"), android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.DeviceVndkVersion = proptools.StringPtr(tc.vndkVersion)
+ }))
+ ensureExactContents(t, ctx, "com.android.vndk.current", "android_common_image", tc.expectedFiles)
+ })
+ }
}
func TestVndkApexWithPrebuilt(t *testing.T) {
@@ -3893,13 +4075,13 @@ func TestApexName(t *testing.T) {
}
`)
- module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
+ module := ctx.ModuleForTests("myapex", "android_common_com.android.myapex_image")
apexManifestRule := module.Rule("apexManifestRule")
ensureContains(t, apexManifestRule.Args["opt"], "-v name com.android.myapex")
apexRule := module.Rule("apexRule")
ensureContains(t, apexRule.Args["opt_flags"], "--do_not_check_keyname")
- apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
+ apexBundle := module.Module().(*apexBundle)
data := android.AndroidMkDataForTest(t, ctx, apexBundle)
name := apexBundle.BaseModuleName()
prefix := "TARGET_"
@@ -4442,6 +4624,59 @@ func TestPrebuiltOverrides(t *testing.T) {
}
}
+func TestPrebuiltApexName(t *testing.T) {
+ testApex(t, `
+ prebuilt_apex {
+ name: "com.company.android.myapex",
+ apex_name: "com.android.myapex",
+ src: "company-myapex-arm.apex",
+ }
+ `).ModuleForTests("com.company.android.myapex", "android_common_com.android.myapex")
+
+ testApex(t, `
+ apex_set {
+ name: "com.company.android.myapex",
+ apex_name: "com.android.myapex",
+ set: "company-myapex.apks",
+ }
+ `).ModuleForTests("com.company.android.myapex", "android_common_com.android.myapex")
+}
+
+func TestPrebuiltApexNameWithPlatformBootclasspath(t *testing.T) {
+ _ = android.GroupFixturePreparers(
+ java.PrepareForTestWithJavaDefaultModules,
+ PrepareForTestWithApexBuildComponents,
+ android.FixtureWithRootAndroidBp(`
+ platform_bootclasspath {
+ name: "platform-bootclasspath",
+ fragments: [
+ {
+ apex: "com.android.art",
+ module: "art-bootclasspath-fragment",
+ },
+ ],
+ }
+
+ prebuilt_apex {
+ name: "com.company.android.art",
+ apex_name: "com.android.art",
+ src: "com.company.android.art-arm.apex",
+ exported_bootclasspath_fragments: ["art-bootclasspath-fragment"],
+ }
+
+ prebuilt_bootclasspath_fragment {
+ name: "art-bootclasspath-fragment",
+ contents: ["core-oj"],
+ }
+
+ java_import {
+ name: "core-oj",
+ jars: ["prebuilt.jar"],
+ }
+ `),
+ ).RunTest(t)
+}
+
// These tests verify that the prebuilt_apex/deapexer to java_import wiring allows for the
// propagation of paths to dex implementation jars from the former to the latter.
func TestPrebuiltExportDexImplementationJars(t *testing.T) {
diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go
index 66bc9e069..4b1600e1c 100644
--- a/apex/bootclasspath_fragment_test.go
+++ b/apex/bootclasspath_fragment_test.go
@@ -22,6 +22,7 @@ import (
"android/soong/android"
"android/soong/java"
+ "github.com/google/blueprint/proptools"
)
// Contains tests for bootclasspath_fragment logic from java/bootclasspath_fragment.go as the ART
@@ -216,9 +217,10 @@ func TestBootclasspathFragments_FragmentDependency(t *testing.T) {
`,
)
- checkSdkKindStubs := func(message string, info java.HiddenAPIInfo, kind android.SdkKind, expectedPaths ...string) {
+ checkAPIScopeStubs := func(message string, info java.HiddenAPIInfo, apiScope *java.HiddenAPIScope, expectedPaths ...string) {
t.Helper()
- android.AssertPathsRelativeToTopEquals(t, fmt.Sprintf("%s %s", message, kind), expectedPaths, info.TransitiveStubDexJarsByKind[kind])
+ paths := info.TransitiveStubDexJarsByScope.StubDexJarsForScope(apiScope)
+ android.AssertPathsRelativeToTopEquals(t, fmt.Sprintf("%s %s", message, apiScope), expectedPaths, paths)
}
// Check stub dex paths exported by art.
@@ -229,10 +231,10 @@ func TestBootclasspathFragments_FragmentDependency(t *testing.T) {
bazSystemStubs := "out/soong/.intermediates/baz.stubs.system/android_common/dex/baz.stubs.system.jar"
bazTestStubs := "out/soong/.intermediates/baz.stubs.test/android_common/dex/baz.stubs.test.jar"
- checkSdkKindStubs("art", artInfo, android.SdkPublic, bazPublicStubs)
- checkSdkKindStubs("art", artInfo, android.SdkSystem, bazSystemStubs)
- checkSdkKindStubs("art", artInfo, android.SdkTest, bazTestStubs)
- checkSdkKindStubs("art", artInfo, android.SdkCorePlatform)
+ checkAPIScopeStubs("art", artInfo, java.PublicHiddenAPIScope, bazPublicStubs)
+ checkAPIScopeStubs("art", artInfo, java.SystemHiddenAPIScope, bazSystemStubs)
+ checkAPIScopeStubs("art", artInfo, java.TestHiddenAPIScope, bazTestStubs)
+ checkAPIScopeStubs("art", artInfo, java.CorePlatformHiddenAPIScope)
// Check stub dex paths exported by other.
otherFragment := result.Module("other-bootclasspath-fragment", "android_common")
@@ -241,10 +243,10 @@ func TestBootclasspathFragments_FragmentDependency(t *testing.T) {
fooPublicStubs := "out/soong/.intermediates/foo.stubs/android_common/dex/foo.stubs.jar"
fooSystemStubs := "out/soong/.intermediates/foo.stubs.system/android_common/dex/foo.stubs.system.jar"
- checkSdkKindStubs("other", otherInfo, android.SdkPublic, bazPublicStubs, fooPublicStubs)
- checkSdkKindStubs("other", otherInfo, android.SdkSystem, bazSystemStubs, fooSystemStubs)
- checkSdkKindStubs("other", otherInfo, android.SdkTest, bazTestStubs, fooSystemStubs)
- checkSdkKindStubs("other", otherInfo, android.SdkCorePlatform)
+ checkAPIScopeStubs("other", otherInfo, java.PublicHiddenAPIScope, bazPublicStubs, fooPublicStubs)
+ checkAPIScopeStubs("other", otherInfo, java.SystemHiddenAPIScope, bazSystemStubs, fooSystemStubs)
+ checkAPIScopeStubs("other", otherInfo, java.TestHiddenAPIScope, bazTestStubs, fooSystemStubs)
+ checkAPIScopeStubs("other", otherInfo, java.CorePlatformHiddenAPIScope)
}
func checkBootclasspathFragment(t *testing.T, result *android.TestResult, moduleName, variantName string, expectedConfiguredModules string, expectedBootclasspathFragmentFiles string) {
@@ -718,4 +720,480 @@ func TestBootclasspathFragmentContentsNoName(t *testing.T) {
checkFragmentExportedDexJar("bar", "out/soong/.intermediates/mybootclasspathfragment/android_common_apex10000/hiddenapi-modular/encoded/bar.jar")
}
+func getDexJarPath(result *android.TestResult, name string) string {
+ module := result.Module(name, "android_common")
+ return module.(java.UsesLibraryDependency).DexJarBuildPath().RelativeToTop().String()
+}
+
+// TestBootclasspathFragment_HiddenAPIList checks to make sure that the correct parameters are
+// passed to the hiddenapi list tool.
+func TestBootclasspathFragment_HiddenAPIList(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForTestWithBootclasspathFragment,
+ prepareForTestWithArtApex,
+ prepareForTestWithMyapex,
+ // Configure bootclasspath jars to ensure that hidden API encoding is performed on them.
+ java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz"),
+ java.FixtureConfigureUpdatableBootJars("myapex:foo", "myapex:bar"),
+ // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
+ // is disabled.
+ android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
+
+ java.PrepareForTestWithJavaSdkLibraryFiles,
+ java.FixtureWithLastReleaseApis("foo", "quuz"),
+ ).RunTestWithBp(t, `
+ apex {
+ name: "com.android.art",
+ key: "com.android.art.key",
+ bootclasspath_fragments: ["art-bootclasspath-fragment"],
+ updatable: false,
+ }
+
+ apex_key {
+ name: "com.android.art.key",
+ public_key: "com.android.art.avbpubkey",
+ private_key: "com.android.art.pem",
+ }
+
+ java_library {
+ name: "baz",
+ apex_available: [
+ "com.android.art",
+ ],
+ srcs: ["b.java"],
+ compile_dex: true,
+ }
+
+ java_sdk_library {
+ name: "quuz",
+ apex_available: [
+ "com.android.art",
+ ],
+ srcs: ["b.java"],
+ compile_dex: true,
+ public: {enabled: true},
+ system: {enabled: true},
+ test: {enabled: true},
+ module_lib: {enabled: true},
+ }
+
+ bootclasspath_fragment {
+ name: "art-bootclasspath-fragment",
+ image_name: "art",
+ // Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above.
+ contents: ["baz", "quuz"],
+ apex_available: [
+ "com.android.art",
+ ],
+ }
+
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ bootclasspath_fragments: [
+ "mybootclasspathfragment",
+ ],
+ updatable: false,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ java_sdk_library {
+ name: "foo",
+ srcs: ["b.java"],
+ shared_library: false,
+ public: {enabled: true},
+ apex_available: [
+ "myapex",
+ ],
+ }
+
+ java_library {
+ name: "bar",
+ srcs: ["b.java"],
+ installable: true,
+ apex_available: [
+ "myapex",
+ ],
+ }
+
+ bootclasspath_fragment {
+ name: "mybootclasspathfragment",
+ contents: [
+ "foo",
+ "bar",
+ ],
+ apex_available: [
+ "myapex",
+ ],
+ fragments: [
+ {
+ apex: "com.android.art",
+ module: "art-bootclasspath-fragment",
+ },
+ ],
+ }
+ `)
+
+ java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_apex10000", []string{
+ "art-bootclasspath-fragment",
+ "bar",
+ "dex2oatd",
+ "foo",
+ })
+
+ fooStubs := getDexJarPath(result, "foo.stubs")
+ quuzPublicStubs := getDexJarPath(result, "quuz.stubs")
+ quuzSystemStubs := getDexJarPath(result, "quuz.stubs.system")
+ quuzTestStubs := getDexJarPath(result, "quuz.stubs.test")
+ quuzModuleLibStubs := getDexJarPath(result, "quuz.stubs.module_lib")
+
+ // Make sure that the fragment uses the quuz stub dex jars when generating the hidden API flags.
+ fragment := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000")
+
+ rule := fragment.Rule("modularHiddenAPIStubFlagsFile")
+ command := rule.RuleParams.Command
+ android.AssertStringDoesContain(t, "check correct rule", command, "hiddenapi list")
+
+ // Make sure that the quuz stubs are available for resolving references from the implementation
+ // boot dex jars provided by this module.
+ android.AssertStringDoesContain(t, "quuz widest", command, "--dependency-stub-dex="+quuzModuleLibStubs)
+
+ // Make sure that the quuz stubs are available for resolving references from the different API
+ // stubs provided by this module.
+ android.AssertStringDoesContain(t, "public", command, "--public-stub-classpath="+quuzPublicStubs+":"+fooStubs)
+ android.AssertStringDoesContain(t, "system", command, "--system-stub-classpath="+quuzSystemStubs+":"+fooStubs)
+ android.AssertStringDoesContain(t, "test", command, "--test-stub-classpath="+quuzTestStubs+":"+fooStubs)
+}
+
+// TestBootclasspathFragment_AndroidNonUpdatable checks to make sure that setting
+// additional_stubs: ["android-non-updatable"] causes the source android-non-updatable modules to be
+// added to the hiddenapi list tool.
+func TestBootclasspathFragment_AndroidNonUpdatable(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForTestWithBootclasspathFragment,
+ prepareForTestWithArtApex,
+ prepareForTestWithMyapex,
+ // Configure bootclasspath jars to ensure that hidden API encoding is performed on them.
+ java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz", "myapex:foo", "myapex:bar"),
+ // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
+ // is disabled.
+ android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
+
+ java.PrepareForTestWithJavaSdkLibraryFiles,
+ java.FixtureWithLastReleaseApis("foo", "android-non-updatable"),
+ ).RunTestWithBp(t, `
+ java_sdk_library {
+ name: "android-non-updatable",
+ srcs: ["b.java"],
+ compile_dex: true,
+ public: {
+ enabled: true,
+ },
+ system: {
+ enabled: true,
+ },
+ test: {
+ enabled: true,
+ },
+ module_lib: {
+ enabled: true,
+ },
+ }
+
+ apex {
+ name: "com.android.art",
+ key: "com.android.art.key",
+ bootclasspath_fragments: ["art-bootclasspath-fragment"],
+ java_libs: [
+ "baz",
+ "quuz",
+ ],
+ updatable: false,
+ }
+
+ apex_key {
+ name: "com.android.art.key",
+ public_key: "com.android.art.avbpubkey",
+ private_key: "com.android.art.pem",
+ }
+
+ java_library {
+ name: "baz",
+ apex_available: [
+ "com.android.art",
+ ],
+ srcs: ["b.java"],
+ compile_dex: true,
+ }
+
+ java_library {
+ name: "quuz",
+ apex_available: [
+ "com.android.art",
+ ],
+ srcs: ["b.java"],
+ compile_dex: true,
+ }
+
+ bootclasspath_fragment {
+ name: "art-bootclasspath-fragment",
+ image_name: "art",
+ // Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above.
+ contents: ["baz", "quuz"],
+ apex_available: [
+ "com.android.art",
+ ],
+ }
+
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ bootclasspath_fragments: [
+ "mybootclasspathfragment",
+ ],
+ updatable: false,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ java_sdk_library {
+ name: "foo",
+ srcs: ["b.java"],
+ shared_library: false,
+ public: {enabled: true},
+ apex_available: [
+ "myapex",
+ ],
+ }
+
+ java_library {
+ name: "bar",
+ srcs: ["b.java"],
+ installable: true,
+ apex_available: [
+ "myapex",
+ ],
+ }
+
+ bootclasspath_fragment {
+ name: "mybootclasspathfragment",
+ contents: [
+ "foo",
+ "bar",
+ ],
+ apex_available: [
+ "myapex",
+ ],
+ additional_stubs: ["android-non-updatable"],
+ fragments: [
+ {
+ apex: "com.android.art",
+ module: "art-bootclasspath-fragment",
+ },
+ ],
+ }
+ `)
+
+ java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_apex10000", []string{
+ "android-non-updatable.stubs",
+ "android-non-updatable.stubs.module_lib",
+ "android-non-updatable.stubs.system",
+ "android-non-updatable.stubs.test",
+ "art-bootclasspath-fragment",
+ "bar",
+ "dex2oatd",
+ "foo",
+ })
+
+ nonUpdatablePublicStubs := getDexJarPath(result, "android-non-updatable.stubs")
+ nonUpdatableSystemStubs := getDexJarPath(result, "android-non-updatable.stubs.system")
+ nonUpdatableTestStubs := getDexJarPath(result, "android-non-updatable.stubs.test")
+ nonUpdatableModuleLibStubs := getDexJarPath(result, "android-non-updatable.stubs.module_lib")
+
+ // Make sure that the fragment uses the android-non-updatable modules when generating the hidden
+ // API flags.
+ fragment := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000")
+
+ rule := fragment.Rule("modularHiddenAPIStubFlagsFile")
+ command := rule.RuleParams.Command
+ android.AssertStringDoesContain(t, "check correct rule", command, "hiddenapi list")
+
+ // Make sure that the module_lib non-updatable stubs are available for resolving references from
+ // the implementation boot dex jars provided by this module.
+ android.AssertStringDoesContain(t, "android-non-updatable widest", command, "--dependency-stub-dex="+nonUpdatableModuleLibStubs)
+
+ // Make sure that the appropriate non-updatable stubs are available for resolving references from
+ // the different API stubs provided by this module.
+ android.AssertStringDoesContain(t, "public", command, "--public-stub-classpath="+nonUpdatablePublicStubs)
+ android.AssertStringDoesContain(t, "system", command, "--system-stub-classpath="+nonUpdatableSystemStubs)
+ android.AssertStringDoesContain(t, "test", command, "--test-stub-classpath="+nonUpdatableTestStubs)
+}
+
+// TestBootclasspathFragment_AndroidNonUpdatable_AlwaysUsePrebuiltSdks checks to make sure that
+// setting additional_stubs: ["android-non-updatable"] causes the prebuilt android-non-updatable
+// modules to be added to the hiddenapi list tool.
+func TestBootclasspathFragment_AndroidNonUpdatable_AlwaysUsePrebuiltSdks(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForTestWithBootclasspathFragment,
+ java.PrepareForTestWithJavaDefaultModules,
+ prepareForTestWithArtApex,
+ prepareForTestWithMyapex,
+ // Configure bootclasspath jars to ensure that hidden API encoding is performed on them.
+ java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz", "myapex:foo", "myapex:bar"),
+ // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
+ // is disabled.
+ android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
+
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
+ }),
+
+ java.PrepareForTestWithJavaSdkLibraryFiles,
+ java.FixtureWithPrebuiltApis(map[string][]string{
+ "current": {"android-non-updatable"},
+ "30": {"foo"},
+ }),
+ ).RunTestWithBp(t, `
+ apex {
+ name: "com.android.art",
+ key: "com.android.art.key",
+ bootclasspath_fragments: ["art-bootclasspath-fragment"],
+ java_libs: [
+ "baz",
+ "quuz",
+ ],
+ updatable: false,
+ }
+
+ apex_key {
+ name: "com.android.art.key",
+ public_key: "com.android.art.avbpubkey",
+ private_key: "com.android.art.pem",
+ }
+
+ java_library {
+ name: "baz",
+ apex_available: [
+ "com.android.art",
+ ],
+ srcs: ["b.java"],
+ compile_dex: true,
+ }
+
+ java_library {
+ name: "quuz",
+ apex_available: [
+ "com.android.art",
+ ],
+ srcs: ["b.java"],
+ compile_dex: true,
+ }
+
+ bootclasspath_fragment {
+ name: "art-bootclasspath-fragment",
+ image_name: "art",
+ // Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above.
+ contents: ["baz", "quuz"],
+ apex_available: [
+ "com.android.art",
+ ],
+ }
+
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ bootclasspath_fragments: [
+ "mybootclasspathfragment",
+ ],
+ updatable: false,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ java_sdk_library {
+ name: "foo",
+ srcs: ["b.java"],
+ shared_library: false,
+ public: {enabled: true},
+ apex_available: [
+ "myapex",
+ ],
+ }
+
+ java_library {
+ name: "bar",
+ srcs: ["b.java"],
+ installable: true,
+ apex_available: [
+ "myapex",
+ ],
+ }
+
+ bootclasspath_fragment {
+ name: "mybootclasspathfragment",
+ contents: [
+ "foo",
+ "bar",
+ ],
+ apex_available: [
+ "myapex",
+ ],
+ additional_stubs: ["android-non-updatable"],
+ fragments: [
+ {
+ apex: "com.android.art",
+ module: "art-bootclasspath-fragment",
+ },
+ ],
+ }
+ `)
+
+ java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_apex10000", []string{
+ "art-bootclasspath-fragment",
+ "bar",
+ "dex2oatd",
+ "foo",
+ "prebuilt_sdk_module-lib_current_android-non-updatable",
+ "prebuilt_sdk_public_current_android-non-updatable",
+ "prebuilt_sdk_system_current_android-non-updatable",
+ "prebuilt_sdk_test_current_android-non-updatable",
+ })
+
+ nonUpdatablePublicStubs := getDexJarPath(result, "sdk_public_current_android-non-updatable")
+ nonUpdatableSystemStubs := getDexJarPath(result, "sdk_system_current_android-non-updatable")
+ nonUpdatableTestStubs := getDexJarPath(result, "sdk_test_current_android-non-updatable")
+ nonUpdatableModuleLibStubs := getDexJarPath(result, "sdk_module-lib_current_android-non-updatable")
+
+ // Make sure that the fragment uses the android-non-updatable modules when generating the hidden
+ // API flags.
+ fragment := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000")
+
+ rule := fragment.Rule("modularHiddenAPIStubFlagsFile")
+ command := rule.RuleParams.Command
+ android.AssertStringDoesContain(t, "check correct rule", command, "hiddenapi list")
+
+ // Make sure that the module_lib non-updatable stubs are available for resolving references from
+ // the implementation boot dex jars provided by this module.
+ android.AssertStringDoesContain(t, "android-non-updatable widest", command, "--dependency-stub-dex="+nonUpdatableModuleLibStubs)
+
+ // Make sure that the appropriate non-updatable stubs are available for resolving references from
+ // the different API stubs provided by this module.
+ android.AssertStringDoesContain(t, "public", command, "--public-stub-classpath="+nonUpdatablePublicStubs)
+ android.AssertStringDoesContain(t, "system", command, "--system-stub-classpath="+nonUpdatableSystemStubs)
+ android.AssertStringDoesContain(t, "test", command, "--test-stub-classpath="+nonUpdatableTestStubs)
+}
+
// TODO(b/177892522) - add test for host apex.
diff --git a/apex/platform_bootclasspath_test.go b/apex/platform_bootclasspath_test.go
index bd4a9d599..279cf54de 100644
--- a/apex/platform_bootclasspath_test.go
+++ b/apex/platform_bootclasspath_test.go
@@ -481,3 +481,62 @@ func CheckModuleDependencies(t *testing.T, ctx *android.TestContext, name, varia
pairs := java.ApexNamePairsFromModules(ctx, modules)
android.AssertDeepEquals(t, "module dependencies", expected, pairs)
}
+
+// TestPlatformBootclasspath_IncludesRemainingApexJars verifies that any apex boot jar is present in
+// platform_bootclasspath's classpaths.proto config, if the apex does not generate its own config
+// by setting generate_classpaths_proto property to false.
+func TestPlatformBootclasspath_IncludesRemainingApexJars(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForTestWithPlatformBootclasspath,
+ prepareForTestWithMyapex,
+ java.FixtureConfigureUpdatableBootJars("myapex:foo"),
+ android.FixtureWithRootAndroidBp(`
+ platform_bootclasspath {
+ name: "platform-bootclasspath",
+ fragments: [
+ {
+ apex: "myapex",
+ module:"foo-fragment",
+ },
+ ],
+ }
+
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ bootclasspath_fragments: ["foo-fragment"],
+ updatable: false,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ bootclasspath_fragment {
+ name: "foo-fragment",
+ generate_classpaths_proto: false,
+ contents: ["foo"],
+ apex_available: ["myapex"],
+ }
+
+ java_library {
+ name: "foo",
+ srcs: ["a.java"],
+ system_modules: "none",
+ sdk_version: "none",
+ compile_dex: true,
+ apex_available: ["myapex"],
+ permitted_packages: ["foo"],
+ }
+ `),
+ ).RunTest(t)
+
+ java.CheckClasspathFragmentProtoContentInfoProvider(t, result,
+ true, // proto should be generated
+ "myapex:foo", // apex doesn't generate its own config, so must be in platform_bootclasspath
+ "bootclasspath.pb",
+ "out/soong/target/product/test_device/system/etc/classpaths",
+ )
+}
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index ea06d45cb..1bb0fb582 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -24,7 +24,6 @@ import (
"android/soong/java"
"github.com/google/blueprint"
-
"github.com/google/blueprint/proptools"
)
@@ -76,6 +75,10 @@ type sanitizedPrebuilt interface {
type PrebuiltCommonProperties struct {
SelectedApexProperties
+ // Canonical name of this APEX. Used to determine the path to the activated APEX on
+ // device (/apex/<apex_name>). If unspecified, follows the name property.
+ Apex_name *string
+
ForceDisable bool `blueprint:"mutated"`
// whether the extracted apex file is installable.
@@ -110,6 +113,10 @@ func (p *prebuiltCommon) initPrebuiltCommon(module android.Module, properties *P
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
}
+func (p *prebuiltCommon) ApexVariationName() string {
+ return proptools.StringDefault(p.prebuiltCommonProperties.Apex_name, p.ModuleBase.BaseModuleName())
+}
+
func (p *prebuiltCommon) Prebuilt() *android.Prebuilt {
return &p.prebuilt
}
@@ -369,6 +376,12 @@ func (p *prebuiltCommon) apexInfoMutator(mctx android.TopDownMutatorContext) {
}
}
+ // Ignore any modules that do not implement ApexModule as they cannot have an APEX specific
+ // variant.
+ if _, ok := child.(android.ApexModule); !ok {
+ return false
+ }
+
// Strip off the prebuilt_ prefix if present before storing content to ensure consistent
// behavior whether there is a corresponding source module present or not.
depName = android.RemoveOptionalPrebuiltPrefix(depName)
@@ -390,11 +403,11 @@ func (p *prebuiltCommon) apexInfoMutator(mctx android.TopDownMutatorContext) {
})
// Create an ApexInfo for the prebuilt_apex.
- apexVariationName := android.RemoveOptionalPrebuiltPrefix(mctx.ModuleName())
+ apexVariationName := p.ApexVariationName()
apexInfo := android.ApexInfo{
ApexVariationName: apexVariationName,
InApexVariants: []string{apexVariationName},
- InApexModules: []string{apexVariationName},
+ InApexModules: []string{p.ModuleBase.BaseModuleName()}, // BaseModuleName() to avoid the prebuilt_ prefix.
ApexContents: []*android.ApexContents{apexContents},
ForPrebuiltApex: true,
}