Install VINTF fragment modules in the APEX
Currently APEX ignores vintf_fragments modules within the APEX, and all
VINTF fragments are installed with prebuilt_etc modules. This change
installs vintf_fragment modules in the APEX, so any additional
prebuilt_etc modules are not required as long as binaries define
vintf_fragment_modules references.
Bug: 363105686
Test: AOSP CF x86_64 build succeeded
Change-Id: I33b58178cd51dc2c4bb9226fdd68e7990dccd6a2
Merged-In: I33b58178cd51dc2c4bb9226fdd68e7990dccd6a2
diff --git a/android/module.go b/android/module.go
index 80275a3..3295e93 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1091,6 +1091,10 @@
InstallAlwaysNeededDependencyTag
}{}
+func IsVintfDepTag(depTag blueprint.DependencyTag) bool {
+ return depTag == vintfDepTag
+}
+
func addVintfFragmentDeps(ctx BottomUpMutatorContext) {
// Vintf manifests in the recovery partition will be ignored.
if !ctx.Device() || ctx.Module().InstallInRecovery() {
@@ -1109,7 +1113,7 @@
// of nil pointer dereference errors, but we should resolve the missing dependencies.
continue
}
- if vintfModule, ok := vintf.(*vintfFragmentModule); ok {
+ if vintfModule, ok := vintf.(*VintfFragmentModule); ok {
vintfPartition := vintfModule.PartitionTag(deviceConfig)
if modPartition != vintfPartition {
ctx.ModuleErrorf("Module %q(%q) and Vintf_fragment %q(%q) are installed to different partitions.",
diff --git a/android/vintf_fragment.go b/android/vintf_fragment.go
index a3343fd..85beb72 100644
--- a/android/vintf_fragment.go
+++ b/android/vintf_fragment.go
@@ -19,8 +19,9 @@
Src string `android:"path"`
}
-type vintfFragmentModule struct {
+type VintfFragmentModule struct {
ModuleBase
+ ApexModuleBase
properties vintfFragmentProperties
@@ -40,7 +41,7 @@
// Vintf fragment files formerly listed in vintf_fragment property would be transformed into
// this module type.
func vintfLibraryFactory() Module {
- m := &vintfFragmentModule{}
+ m := &VintfFragmentModule{}
m.AddProperties(
&m.properties,
)
@@ -49,7 +50,7 @@
return m
}
-func (m *vintfFragmentModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+func (m *VintfFragmentModule) GenerateAndroidBuildActions(ctx ModuleContext) {
builder := NewRuleBuilder(pctx, ctx)
srcVintfFragment := PathForModuleSrc(ctx, m.properties.Src)
processedVintfFragment := PathForModuleOut(ctx, srcVintfFragment.Base())
@@ -69,8 +70,12 @@
ctx.InstallFile(m.installDirPath, processedVintfFragment.Base(), processedVintfFragment)
}
+func (m *VintfFragmentModule) OutputFile() Path {
+ return m.outputFilePath
+}
+
// Make this module visible to AndroidMK so it can be referenced from modules defined from Android.mk files
-func (m *vintfFragmentModule) AndroidMkEntries() []AndroidMkEntries {
+func (m *VintfFragmentModule) AndroidMkEntries() []AndroidMkEntries {
return []AndroidMkEntries{{
Class: "ETC",
OutputFile: OptionalPathForPath(m.outputFilePath),
@@ -82,3 +87,11 @@
},
}}
}
+
+var _ ApexModule = (*VintfFragmentModule)(nil)
+
+// Implements android.ApexModule
+func (m *VintfFragmentModule) ShouldSupportSdkVersion(ctx BaseModuleContext, sdkVersion ApiLevel) error {
+ // VintfFragmetModule is independent from the SDK version.
+ return nil
+}
diff --git a/apex/apex.go b/apex/apex.go
index fa796e5..cb9dc49 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1505,6 +1505,12 @@
return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, config)
}
+func apexFileForVintfFragment(ctx android.BaseModuleContext, vintfFragment *android.VintfFragmentModule) apexFile {
+ dirInApex := filepath.Join("etc", "vintf")
+
+ return newApexFile(ctx, vintfFragment.OutputFile(), vintfFragment.BaseModuleName(), dirInApex, etc, vintfFragment)
+}
+
// javaModule is an interface to handle all Java modules (java_library, dex_import, etc) in the same
// way.
type javaModule interface {
@@ -2196,7 +2202,13 @@
// nothing
} else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
+ } else if android.IsVintfDepTag(depTag) {
+ if vf, ok := child.(*android.VintfFragmentModule); ok {
+ apexFile := apexFileForVintfFragment(ctx, vf)
+ vctx.filesInfo = append(vctx.filesInfo, apexFile)
+ }
}
+
return false
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 987cb69..8515792 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -12208,3 +12208,35 @@
fileList := android.ContentFromFileRuleForTests(t, result, partition.Output("fileList"))
android.AssertDeepEquals(t, "filesystem with apex", "apex/myapex.apex\n", fileList)
}
+
+func TestVintfFragmentInApex(t *testing.T) {
+ t.Parallel()
+ ctx := testApex(t, apex_default_bp+`
+ apex {
+ name: "myapex",
+ manifest: ":myapex.manifest",
+ androidManifest: ":myapex.androidmanifest",
+ key: "myapex.key",
+ binaries: [ "mybin" ],
+ updatable: false,
+ }
+
+ cc_binary {
+ name: "mybin",
+ srcs: ["mybin.cpp"],
+ vintf_fragment_modules: ["my_vintf_fragment.xml"],
+ apex_available: [ "myapex" ],
+ }
+
+ vintf_fragment {
+ name: "my_vintf_fragment.xml",
+ src: "my_vintf_fragment.xml",
+ }
+ `)
+
+ generateFsRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("generateFsConfig")
+ cmd := generateFsRule.RuleParams.Command
+
+ // Ensure that vintf fragment file is being installed
+ ensureContains(t, cmd, "/etc/vintf/my_vintf_fragment.xml ")
+}
diff --git a/apex/builder.go b/apex/builder.go
index b40fd09..63efa63 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -528,9 +528,10 @@
})
}
-func isVintfFragment(fi apexFile) bool {
+func shouldApplyAssembleVintf(fi apexFile) bool {
isVintfFragment, _ := path.Match("etc/vintf/*", fi.path())
- return isVintfFragment
+ _, fromVintfFragmentModule := fi.module.(*android.VintfFragmentModule)
+ return isVintfFragment && !fromVintfFragmentModule
}
func runAssembleVintf(ctx android.ModuleContext, vintfFragment android.Path) android.Path {
@@ -639,7 +640,7 @@
copyCommands = append(copyCommands, "ln -sfn "+pathOnDevice+" "+destPath)
} else {
// Copy the file into APEX
- if !a.testApex && isVintfFragment(fi) {
+ if !a.testApex && shouldApplyAssembleVintf(fi) {
// copy the output of assemble_vintf instead of the original
vintfFragment := runAssembleVintf(ctx, fi.builtFile)
copyCommands = append(copyCommands, "cp -f "+vintfFragment.String()+" "+destPath)