add apex_available_name property to apexBundle

This property allows developers to create multiple modules that provide
the same APEX implemenation with some differences. For example, an APEX
that targets the current SDK can be developed alongside an APEX that
targets a pre-S SDK. Common dependencies of these APEX modules can both
use the value of the apex_available_name property in their
apex_available lists and be packaged in either APEX module.

Bug: 285138555
(cherry picked from https://android-review.googlesource.com/q/commit:ca8165373070b45919e6a1879ebc11705b6c425c)
Merged-In: Ia2cb027e2f19bd6d3d1c02e3d3742a0122a43c97
Change-Id: Ia2cb027e2f19bd6d3d1c02e3d3742a0122a43c97
This commit is contained in:
Sam Delmerico
2023-06-02 14:09:50 -04:00
committed by Cherrypicker Worker
parent cfd1d64321
commit 1dc63117f2
2 changed files with 188 additions and 0 deletions

View File

@@ -220,6 +220,10 @@ type apexBundleProperties struct {
// imageApex or flattenedApex depending on Config.FlattenApex(). When payload_type is zip,
// this becomes zipApex.
ApexType apexPackaging `blueprint:"mutated"`
// Name that dependencies can specify in their apex_available properties to refer to this module.
// If not specified, this defaults to Soong module name.
Apex_available_name *string
}
type ApexNativeDependencies struct {
@@ -3095,6 +3099,13 @@ func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
}
apexName := ctx.ModuleName()
for _, props := range ctx.Module().GetProperties() {
if apexProps, ok := props.(*apexBundleProperties); ok {
if apexProps.Apex_available_name != nil {
apexName = *apexProps.Apex_available_name
}
}
}
fromName := ctx.OtherModuleName(from)
toName := ctx.OtherModuleName(to)

View File

@@ -6556,6 +6556,183 @@ func TestApexAvailable_InvalidApexName(t *testing.T) {
}`)
}
func TestApexAvailable_ApexAvailableName(t *testing.T) {
t.Run("using name of apex that sets apex_available_name is not allowed", func(t *testing.T) {
testApexError(t, "Consider adding \"myapex\" to 'apex_available' property of \"AppFoo\"", `
apex {
name: "myapex_sminus",
key: "myapex.key",
apps: ["AppFoo"],
apex_available_name: "myapex",
updatable: false,
}
apex {
name: "myapex",
key: "myapex.key",
apps: ["AppFoo"],
updatable: false,
}
apex_key {
name: "myapex.key",
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
android_app {
name: "AppFoo",
srcs: ["foo/bar/MyClass.java"],
sdk_version: "none",
system_modules: "none",
apex_available: [ "myapex_sminus" ],
}`,
android.FixtureMergeMockFs(android.MockFS{
"system/sepolicy/apex/myapex_sminus-file_contexts": nil,
}),
)
})
t.Run("apex_available_name allows module to be used in two different apexes", func(t *testing.T) {
testApex(t, `
apex {
name: "myapex_sminus",
key: "myapex.key",
apps: ["AppFoo"],
apex_available_name: "myapex",
updatable: false,
}
apex {
name: "myapex",
key: "myapex.key",
apps: ["AppFoo"],
updatable: false,
}
apex_key {
name: "myapex.key",
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
android_app {
name: "AppFoo",
srcs: ["foo/bar/MyClass.java"],
sdk_version: "none",
system_modules: "none",
apex_available: [ "myapex" ],
}`,
android.FixtureMergeMockFs(android.MockFS{
"system/sepolicy/apex/myapex_sminus-file_contexts": nil,
}),
)
})
t.Run("override_apexes work with apex_available_name", func(t *testing.T) {
testApex(t, `
override_apex {
name: "myoverrideapex_sminus",
base: "myapex_sminus",
key: "myapex.key",
apps: ["AppFooOverride"],
}
override_apex {
name: "myoverrideapex",
base: "myapex",
key: "myapex.key",
apps: ["AppFooOverride"],
}
apex {
name: "myapex_sminus",
key: "myapex.key",
apps: ["AppFoo"],
apex_available_name: "myapex",
updatable: false,
}
apex {
name: "myapex",
key: "myapex.key",
apps: ["AppFoo"],
updatable: false,
}
apex_key {
name: "myapex.key",
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
android_app {
name: "AppFooOverride",
srcs: ["foo/bar/MyClass.java"],
sdk_version: "none",
system_modules: "none",
apex_available: [ "myapex" ],
}
android_app {
name: "AppFoo",
srcs: ["foo/bar/MyClass.java"],
sdk_version: "none",
system_modules: "none",
apex_available: [ "myapex" ],
}`,
android.FixtureMergeMockFs(android.MockFS{
"system/sepolicy/apex/myapex_sminus-file_contexts": nil,
}),
)
})
}
func TestApexAvailable_ApexAvailableNameWithOverrides(t *testing.T) {
context := android.GroupFixturePreparers(
android.PrepareForIntegrationTestWithAndroid,
PrepareForTestWithApexBuildComponents,
java.PrepareForTestWithDexpreopt,
android.FixtureMergeMockFs(android.MockFS{
"system/sepolicy/apex/myapex-file_contexts": nil,
"system/sepolicy/apex/myapex_sminus-file_contexts": nil,
}),
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.BuildId = proptools.StringPtr("buildid")
}),
)
context.RunTestWithBp(t, `
override_apex {
name: "myoverrideapex_sminus",
base: "myapex_sminus",
}
override_apex {
name: "myoverrideapex",
base: "myapex",
}
apex {
name: "myapex",
key: "myapex.key",
apps: ["AppFoo"],
updatable: false,
}
apex {
name: "myapex_sminus",
apex_available_name: "myapex",
key: "myapex.key",
apps: ["AppFoo_sminus"],
updatable: false,
}
apex_key {
name: "myapex.key",
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
android_app {
name: "AppFoo",
srcs: ["foo/bar/MyClass.java"],
sdk_version: "none",
system_modules: "none",
apex_available: [ "myapex" ],
}
android_app {
name: "AppFoo_sminus",
srcs: ["foo/bar/MyClass.java"],
sdk_version: "none",
min_sdk_version: "29",
system_modules: "none",
apex_available: [ "myapex" ],
}`)
}
func TestApexAvailable_CheckForPlatform(t *testing.T) {
ctx := testApex(t, `
apex {