Introduce vintf_data module type
Introduce a new vintf_data module type which handles vintf_data
of four different types: device_cm, system_manifest, product_manifest,
and system_ext_manifest.
Bug: 340427295
Test: m vendor_compatibility_matrix.xml system_manifest.xml \
product_manifest.xml system_ext_manifest.xml
Change-Id: I32f270cb0e227104b6b7298327a74f123c18dc0c
diff --git a/android/vintf_data.go b/android/vintf_data.go
new file mode 100644
index 0000000..cd5f096
--- /dev/null
+++ b/android/vintf_data.go
@@ -0,0 +1,148 @@
+// Copyright 2024 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/google/blueprint/proptools"
+)
+
+const (
+ deviceCmType = "device_cm"
+ systemManifestType = "system_manifest"
+ productManifestType = "product_manifest"
+ systemExtManifestType = "system_ext_manifest"
+
+ defaultDcm = "system/libhidl/vintfdata/device_compatibility_matrix.default.xml"
+ defaultSystemManifest = "system/libhidl/vintfdata/manifest.xml"
+ defaultSystemExtManifest = "system/libhidl/vintfdata/system_ext_manifest.default.xml"
+)
+
+type vintfDataProperties struct {
+ // Optional name for the installed file. If unspecified it will be manifest.xml by default.
+ Filename *string
+
+ // Type of the vintf data type, the allowed type are device_compatibility_matrix, system_manifest,
+ // product_manifest, and system_ext_manifest.
+ Type *string
+}
+
+type vintfDataRule struct {
+ ModuleBase
+
+ properties vintfDataProperties
+
+ installDirPath InstallPath
+ outputFilePath OutputPath
+ noAction bool
+}
+
+func init() {
+ registerVintfDataComponents(InitRegistrationContext)
+}
+
+func registerVintfDataComponents(ctx RegistrationContext) {
+ ctx.RegisterModuleType("vintf_data", vintfDataFactory)
+}
+
+// vintf_fragment module processes vintf fragment file and installs under etc/vintf/manifest.
+func vintfDataFactory() Module {
+ m := &vintfDataRule{}
+ m.AddProperties(
+ &m.properties,
+ )
+ InitAndroidArchModule(m, DeviceSupported, MultilibFirst)
+
+ return m
+}
+
+func (m *vintfDataRule) GenerateAndroidBuildActions(ctx ModuleContext) {
+ builder := NewRuleBuilder(pctx, ctx)
+ gensrc := PathForModuleOut(ctx, "manifest.xml")
+ assembleVintfEnvs := []string{}
+ inputPaths := make(Paths, 0)
+
+ switch proptools.String(m.properties.Type) {
+ case deviceCmType:
+ assembleVintfEnvs = append(assembleVintfEnvs, fmt.Sprintf("BOARD_SYSTEMSDK_VERSIONS=\"%s\"", strings.Join(ctx.DeviceConfig().SystemSdkVersions(), " ")))
+
+ deviceMatrixs := PathsForSource(ctx, ctx.Config().DeviceMatrixFile())
+ if len(deviceMatrixs) > 0 {
+ inputPaths = append(inputPaths, deviceMatrixs...)
+ } else {
+ inputPaths = append(inputPaths, PathForSource(ctx, defaultDcm))
+ }
+ case systemManifestType:
+ assembleVintfEnvs = append(assembleVintfEnvs, fmt.Sprintf("PLATFORM_SYSTEMSDK_VERSIONS=\"%s\"", strings.Join(ctx.DeviceConfig().PlatformSystemSdkVersions(), " ")))
+
+ inputPaths = append(inputPaths, PathForSource(ctx, defaultSystemManifest))
+ systemManifestFiles := PathsForSource(ctx, ctx.Config().SystemManifestFile())
+ if len(systemManifestFiles) > 0 {
+ inputPaths = append(inputPaths, systemManifestFiles...)
+ }
+ case productManifestType:
+ productManifestFiles := PathsForSource(ctx, ctx.Config().ProductManifestFiles())
+ // Only need to generate the manifest if PRODUCT_MANIFEST_FILES not defined.
+ if len(productManifestFiles) == 0 {
+ m.noAction = true
+ return
+ }
+
+ inputPaths = append(inputPaths, productManifestFiles...)
+ case systemExtManifestType:
+ assembleVintfEnvs = append(assembleVintfEnvs, fmt.Sprintf("PROVIDED_VNDK_VERSIONS=\"%s\"", strings.Join(ctx.DeviceConfig().ExtraVndkVersions(), " ")))
+
+ inputPaths = append(inputPaths, PathForSource(ctx, defaultSystemExtManifest))
+ systemExtManifestFiles := PathsForSource(ctx, ctx.Config().SystemExtManifestFiles())
+ if len(systemExtManifestFiles) > 0 {
+ inputPaths = append(inputPaths, systemExtManifestFiles...)
+ }
+ default:
+ panic(fmt.Errorf("For %s: The attribute 'type' value only allowed device_cm, system_manifest, product_manifest, system_ext_manifest!", ctx.Module().Name()))
+ }
+
+ // Process vintf fragment source file with assemble_vintf tool
+ builder.Command().
+ Flags(assembleVintfEnvs).
+ BuiltTool("assemble_vintf").
+ FlagWithArg("-i ", strings.Join(inputPaths.Strings(), ":")).
+ FlagWithOutput("-o ", gensrc)
+
+ builder.Build("assemble_vintf", "Process vintf data "+gensrc.String())
+
+ m.installDirPath = PathForModuleInstall(ctx, "etc", "vintf")
+ m.outputFilePath = gensrc.OutputPath
+
+ installFileName := "manifest.xml"
+ if filename := proptools.String(m.properties.Filename); filename != "" {
+ installFileName = filename
+ }
+
+ ctx.InstallFile(m.installDirPath, installFileName, gensrc)
+}
+
+// Make this module visible to AndroidMK so it can be referenced from modules defined from Android.mk files
+func (m *vintfDataRule) AndroidMkEntries() []AndroidMkEntries {
+ if m.noAction {
+ return []AndroidMkEntries{}
+ }
+
+ return []AndroidMkEntries{{
+ Class: "ETC",
+ OutputFile: OptionalPathForPath(m.outputFilePath),
+ }}
+}