summaryrefslogtreecommitdiff
path: root/android/vintf_data.go
blob: 2909817d39f0cb91035abbd14160449185c89f9b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
// 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"
	vendorManifestType    = "vendor_manifest"
	odmManifestType       = "odm_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 Path
	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...)
		}
	case vendorManifestType:
		assembleVintfEnvs = append(assembleVintfEnvs, fmt.Sprintf("BOARD_SEPOLICY_VERS=\"%s\"", ctx.DeviceConfig().BoardSepolicyVers()))
		assembleVintfEnvs = append(assembleVintfEnvs, fmt.Sprintf("PRODUCT_ENFORCE_VINTF_MANIFEST=%t", *ctx.Config().productVariables.Enforce_vintf_manifest))
		deviceManifestFiles := PathsForSource(ctx, ctx.Config().DeviceManifestFiles())
		// Only need to generate the manifest if DEVICE_MANIFEST_FILE is defined.
		if len(deviceManifestFiles) == 0 {
			m.noAction = true
			return
		}

		inputPaths = append(inputPaths, deviceManifestFiles...)
	case odmManifestType:
		assembleVintfEnvs = append(assembleVintfEnvs, "VINTF_IGNORE_TARGET_FCM_VERSION=true")
		odmManifestFiles := PathsForSource(ctx, ctx.Config().OdmManifestFiles())
		// Only need to generate the manifest if ODM_MANIFEST_FILES is defined.
		if len(odmManifestFiles) == 0 {
			m.noAction = true
			return
		}

		inputPaths = append(inputPaths, odmManifestFiles...)
	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().
		Implicits(inputPaths).
		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

	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),
	}}
}