xref: /aosp_15_r20/build/soong/android/vintf_data.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1// Copyright 2024 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package android
16
17import (
18	"fmt"
19	"strings"
20
21	"github.com/google/blueprint/proptools"
22)
23
24const (
25	deviceCmType          = "device_cm"
26	systemManifestType    = "system_manifest"
27	productManifestType   = "product_manifest"
28	systemExtManifestType = "system_ext_manifest"
29	vendorManifestType    = "vendor_manifest"
30	odmManifestType       = "odm_manifest"
31
32	defaultDcm               = "system/libhidl/vintfdata/device_compatibility_matrix.default.xml"
33	defaultSystemManifest    = "system/libhidl/vintfdata/manifest.xml"
34	defaultSystemExtManifest = "system/libhidl/vintfdata/system_ext_manifest.default.xml"
35)
36
37type vintfDataProperties struct {
38	// Optional name for the installed file. If unspecified it will be manifest.xml by default.
39	Filename *string
40
41	// Type of the vintf data type, the allowed type are device_compatibility_matrix, system_manifest,
42	// product_manifest, and system_ext_manifest.
43	Type *string
44}
45
46type vintfDataRule struct {
47	ModuleBase
48
49	properties vintfDataProperties
50
51	installDirPath InstallPath
52	outputFilePath Path
53	noAction       bool
54}
55
56func init() {
57	registerVintfDataComponents(InitRegistrationContext)
58}
59
60func registerVintfDataComponents(ctx RegistrationContext) {
61	ctx.RegisterModuleType("vintf_data", vintfDataFactory)
62}
63
64// vintf_fragment module processes vintf fragment file and installs under etc/vintf/manifest.
65func vintfDataFactory() Module {
66	m := &vintfDataRule{}
67	m.AddProperties(
68		&m.properties,
69	)
70	InitAndroidArchModule(m, DeviceSupported, MultilibFirst)
71
72	return m
73}
74
75func (m *vintfDataRule) GenerateAndroidBuildActions(ctx ModuleContext) {
76	builder := NewRuleBuilder(pctx, ctx)
77	gensrc := PathForModuleOut(ctx, "manifest.xml")
78	assembleVintfEnvs := []string{}
79	inputPaths := make(Paths, 0)
80
81	switch proptools.String(m.properties.Type) {
82	case deviceCmType:
83		assembleVintfEnvs = append(assembleVintfEnvs, fmt.Sprintf("BOARD_SYSTEMSDK_VERSIONS=\"%s\"", strings.Join(ctx.DeviceConfig().SystemSdkVersions(), " ")))
84
85		deviceMatrixs := PathsForSource(ctx, ctx.Config().DeviceMatrixFile())
86		if len(deviceMatrixs) > 0 {
87			inputPaths = append(inputPaths, deviceMatrixs...)
88		} else {
89			inputPaths = append(inputPaths, PathForSource(ctx, defaultDcm))
90		}
91	case systemManifestType:
92		assembleVintfEnvs = append(assembleVintfEnvs, fmt.Sprintf("PLATFORM_SYSTEMSDK_VERSIONS=\"%s\"", strings.Join(ctx.DeviceConfig().PlatformSystemSdkVersions(), " ")))
93
94		inputPaths = append(inputPaths, PathForSource(ctx, defaultSystemManifest))
95		systemManifestFiles := PathsForSource(ctx, ctx.Config().SystemManifestFile())
96		if len(systemManifestFiles) > 0 {
97			inputPaths = append(inputPaths, systemManifestFiles...)
98		}
99	case productManifestType:
100		productManifestFiles := PathsForSource(ctx, ctx.Config().ProductManifestFiles())
101		// Only need to generate the manifest if PRODUCT_MANIFEST_FILES not defined.
102		if len(productManifestFiles) == 0 {
103			m.noAction = true
104			return
105		}
106
107		inputPaths = append(inputPaths, productManifestFiles...)
108	case systemExtManifestType:
109		assembleVintfEnvs = append(assembleVintfEnvs, fmt.Sprintf("PROVIDED_VNDK_VERSIONS=\"%s\"", strings.Join(ctx.DeviceConfig().ExtraVndkVersions(), " ")))
110
111		inputPaths = append(inputPaths, PathForSource(ctx, defaultSystemExtManifest))
112		systemExtManifestFiles := PathsForSource(ctx, ctx.Config().SystemExtManifestFiles())
113		if len(systemExtManifestFiles) > 0 {
114			inputPaths = append(inputPaths, systemExtManifestFiles...)
115		}
116	case vendorManifestType:
117		assembleVintfEnvs = append(assembleVintfEnvs, fmt.Sprintf("BOARD_SEPOLICY_VERS=\"%s\"", ctx.DeviceConfig().BoardSepolicyVers()))
118		assembleVintfEnvs = append(assembleVintfEnvs, fmt.Sprintf("PRODUCT_ENFORCE_VINTF_MANIFEST=%t", *ctx.Config().productVariables.Enforce_vintf_manifest))
119		deviceManifestFiles := PathsForSource(ctx, ctx.Config().DeviceManifestFiles())
120		// Only need to generate the manifest if DEVICE_MANIFEST_FILE is defined.
121		if len(deviceManifestFiles) == 0 {
122			m.noAction = true
123			return
124		}
125
126		inputPaths = append(inputPaths, deviceManifestFiles...)
127	case odmManifestType:
128		assembleVintfEnvs = append(assembleVintfEnvs, "VINTF_IGNORE_TARGET_FCM_VERSION=true")
129		odmManifestFiles := PathsForSource(ctx, ctx.Config().OdmManifestFiles())
130		// Only need to generate the manifest if ODM_MANIFEST_FILES is defined.
131		if len(odmManifestFiles) == 0 {
132			m.noAction = true
133			return
134		}
135
136		inputPaths = append(inputPaths, odmManifestFiles...)
137	default:
138		panic(fmt.Errorf("For %s: The attribute 'type' value only allowed device_cm, system_manifest, product_manifest, system_ext_manifest!", ctx.Module().Name()))
139	}
140
141	// Process vintf fragment source file with assemble_vintf tool
142	builder.Command().
143		Flags(assembleVintfEnvs).
144		BuiltTool("assemble_vintf").
145		FlagWithArg("-i ", strings.Join(inputPaths.Strings(), ":")).
146		FlagWithOutput("-o ", gensrc)
147
148	builder.Build("assemble_vintf", "Process vintf data "+gensrc.String())
149
150	m.installDirPath = PathForModuleInstall(ctx, "etc", "vintf")
151	m.outputFilePath = gensrc
152
153	installFileName := "manifest.xml"
154	if filename := proptools.String(m.properties.Filename); filename != "" {
155		installFileName = filename
156	}
157
158	ctx.InstallFile(m.installDirPath, installFileName, gensrc)
159}
160
161// Make this module visible to AndroidMK so it can be referenced from modules defined from Android.mk files
162func (m *vintfDataRule) AndroidMkEntries() []AndroidMkEntries {
163	if m.noAction {
164		return []AndroidMkEntries{}
165	}
166
167	return []AndroidMkEntries{{
168		Class:      "ETC",
169		OutputFile: OptionalPathForPath(m.outputFilePath),
170	}}
171}
172