blob: 9a9e5686acafcd0cfab0d46d14ce515d9bed21ea [file] [log] [blame]
Joe Onoratofee845a2023-05-09 08:14:14 -07001// Copyright 2023 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
Joe Onorato981c9262023-06-21 15:16:23 -070015package aconfig
Joe Onoratofee845a2023-05-09 08:14:14 -070016
17import (
Oriol Prieto Gascó12887ba2024-12-02 22:43:29 +000018 "android/soong/android"
LaMont Jones21d04d92024-06-11 11:28:54 -070019 "path/filepath"
20 "slices"
Oriol Prieto Gascó12887ba2024-12-02 22:43:29 +000021 "strconv"
Joe Onoratofee845a2023-05-09 08:14:14 -070022 "strings"
Vinh Tran457ddef2023-08-02 13:50:26 -040023
24 "github.com/google/blueprint"
Joe Onoratofee845a2023-05-09 08:14:14 -070025)
26
LaMont Jones21d04d92024-06-11 11:28:54 -070027type AconfigReleaseConfigValue struct {
28 ReleaseConfig string
29 Values []string `blueprint:"mutated"`
30}
31
Joe Onorato981c9262023-06-21 15:16:23 -070032type DeclarationsModule struct {
Joe Onoratofee845a2023-05-09 08:14:14 -070033 android.ModuleBase
34 android.DefaultableModuleBase
Yu Liufa297642024-06-11 00:13:02 +000035 blueprint.IncrementalModule
Joe Onoratofee845a2023-05-09 08:14:14 -070036
Joe Onorato981c9262023-06-21 15:16:23 -070037 // Properties for "aconfig_declarations"
Joe Onoratofee845a2023-05-09 08:14:14 -070038 properties struct {
39 // aconfig files, relative to this Android.bp file
40 Srcs []string `android:"path"`
41
Joe Onorato81b25ed2023-06-21 13:49:37 -070042 // Release config flag package
43 Package string
Joe Onoratofee845a2023-05-09 08:14:14 -070044
LaMont Jones21d04d92024-06-11 11:28:54 -070045 // Values for release configs / RELEASE_ACONFIG_VALUE_SETS
46 // The current release config is `ReleaseConfig: ""`, others
47 // are from RELEASE_ACONFIG_EXTRA_RELEASE_CONFIGS.
48 ReleaseConfigValues []AconfigReleaseConfigValue
Yu Liueae7b362023-11-16 17:05:47 -080049
50 // Container(system/vendor/apex) that this module belongs to
51 Container string
Zi Wang0e5d16c2024-02-08 06:19:34 +000052
53 // The flags will only be repackaged if this prop is true.
54 Exportable bool
Joe Onoratofee845a2023-05-09 08:14:14 -070055 }
Joe Onoratofee845a2023-05-09 08:14:14 -070056}
57
Joe Onorato981c9262023-06-21 15:16:23 -070058func DeclarationsFactory() android.Module {
59 module := &DeclarationsModule{}
Joe Onoratofee845a2023-05-09 08:14:14 -070060
61 android.InitAndroidModule(module)
62 android.InitDefaultableModule(module)
63 module.AddProperties(&module.properties)
Joe Onoratofee845a2023-05-09 08:14:14 -070064
65 return module
66}
67
68type implicitValuesTagType struct {
69 blueprint.BaseDependencyTag
LaMont Jones21d04d92024-06-11 11:28:54 -070070
71 // The release config name for these values.
72 // Empty string for the actual current release config.
73 ReleaseConfig string
Joe Onoratofee845a2023-05-09 08:14:14 -070074}
75
76var implicitValuesTag = implicitValuesTagType{}
77
Joe Onorato981c9262023-06-21 15:16:23 -070078func (module *DeclarationsModule) DepsMutator(ctx android.BottomUpMutatorContext) {
Joe Onoratofee845a2023-05-09 08:14:14 -070079 // Validate Properties
80 if len(module.properties.Srcs) == 0 {
81 ctx.PropertyErrorf("srcs", "missing source files")
82 return
83 }
Joe Onorato81b25ed2023-06-21 13:49:37 -070084 if len(module.properties.Package) == 0 {
85 ctx.PropertyErrorf("package", "missing package property")
Joe Onoratofee845a2023-05-09 08:14:14 -070086 }
Yu Liu315a53c2024-04-24 16:41:57 +000087 if len(module.properties.Container) == 0 {
88 ctx.PropertyErrorf("container", "missing container property")
89 }
Joe Onoratofee845a2023-05-09 08:14:14 -070090
Dennis Shen01efb832024-09-12 22:05:08 +000091 // treating system_ext as system partition as we are combining them as one container
92 // TODO remove this logic once we start enforcing that system_ext cannot be specified as
93 // container in the container field.
94 if module.properties.Container == "system_ext" {
95 module.properties.Container = "system"
96 }
97
Joe Onorato981c9262023-06-21 15:16:23 -070098 // Add a dependency on the aconfig_value_sets defined in
99 // RELEASE_ACONFIG_VALUE_SETS, and add any aconfig_values that
Joe Onorato81b25ed2023-06-21 13:49:37 -0700100 // match our package.
Joe Onorato981c9262023-06-21 15:16:23 -0700101 valuesFromConfig := ctx.Config().ReleaseAconfigValueSets()
Yu Liueebb2592023-10-12 20:31:27 -0700102 if len(valuesFromConfig) > 0 {
103 ctx.AddDependency(ctx.Module(), implicitValuesTag, valuesFromConfig...)
Yu Liu2cc802a2023-09-05 17:19:45 -0700104 }
LaMont Jones21d04d92024-06-11 11:28:54 -0700105 for rcName, valueSets := range ctx.Config().ReleaseAconfigExtraReleaseConfigsValueSets() {
106 if len(valueSets) > 0 {
107 ctx.AddDependency(ctx.Module(), implicitValuesTagType{ReleaseConfig: rcName}, valueSets...)
108 }
109 }
Joe Onoratofee845a2023-05-09 08:14:14 -0700110}
111
Joe Onoratofee845a2023-05-09 08:14:14 -0700112func joinAndPrefix(prefix string, values []string) string {
113 var sb strings.Builder
114 for _, v := range values {
115 sb.WriteString(prefix)
116 sb.WriteString(v)
117 }
118 return sb.String()
119}
120
Zhi Dou3f65a412023-08-10 21:47:40 +0000121func optionalVariable(prefix string, value string) string {
122 var sb strings.Builder
123 if value != "" {
124 sb.WriteString(prefix)
125 sb.WriteString(value)
126 }
127 return sb.String()
128}
129
LaMont Jones21d04d92024-06-11 11:28:54 -0700130// Assemble the actual filename.
131// If `rcName` is not empty, then insert "-{rcName}" into the path before the
132// file extension.
133func assembleFileName(rcName, path string) string {
134 if rcName == "" {
135 return path
136 }
137 dir, file := filepath.Split(path)
138 rcName = "-" + rcName
139 ext := filepath.Ext(file)
140 base := file[:len(file)-len(ext)]
141 return dir + base + rcName + ext
142}
143
Joe Onorato981c9262023-06-21 15:16:23 -0700144func (module *DeclarationsModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
LaMont Jones21d04d92024-06-11 11:28:54 -0700145 // Determine which release configs we are processing.
146 //
147 // We always process the current release config (empty string).
148 // We may have been told to also create artifacts for some others.
149 configs := append([]string{""}, ctx.Config().ReleaseAconfigExtraReleaseConfigs()...)
150 slices.Sort(configs)
151
152 values := make(map[string][]string)
153 valuesFiles := make(map[string][]android.Path, 0)
154 providerData := android.AconfigReleaseDeclarationsProviderData{}
Joe Onoratofee845a2023-05-09 08:14:14 -0700155 ctx.VisitDirectDeps(func(dep android.Module) {
Colin Cross313aa542023-12-13 13:47:44 -0800156 if depData, ok := android.OtherModuleProvider(ctx, dep, valueSetProviderKey); ok {
LaMont Jones21d04d92024-06-11 11:28:54 -0700157 depTag := ctx.OtherModuleDependencyTag(dep)
158 for _, config := range configs {
159 tag := implicitValuesTagType{ReleaseConfig: config}
160 if depTag == tag {
161 paths, ok := depData.AvailablePackages[module.properties.Package]
162 if ok {
163 valuesFiles[config] = append(valuesFiles[config], paths...)
164 for _, path := range paths {
165 values[config] = append(values[config], path.String())
166 }
167 }
Colin Cross313aa542023-12-13 13:47:44 -0800168 }
Joe Onoratofee845a2023-05-09 08:14:14 -0700169 }
170 }
171 })
LaMont Jones21d04d92024-06-11 11:28:54 -0700172 for _, config := range configs {
173 module.properties.ReleaseConfigValues = append(module.properties.ReleaseConfigValues, AconfigReleaseConfigValue{
174 ReleaseConfig: config,
175 Values: values[config],
176 })
Joe Onoratofee845a2023-05-09 08:14:14 -0700177
LaMont Jones21d04d92024-06-11 11:28:54 -0700178 // Intermediate format
179 declarationFiles := android.PathsForModuleSrc(ctx, module.properties.Srcs)
180 intermediateCacheFilePath := android.PathForModuleOut(ctx, assembleFileName(config, "intermediate.pb"))
181 var defaultPermission string
182 defaultPermission = ctx.Config().ReleaseAconfigFlagDefaultPermission()
183 if config != "" {
184 if confPerm, ok := ctx.Config().GetBuildFlag("RELEASE_ACONFIG_FLAG_DEFAULT_PERMISSION_" + config); ok {
185 defaultPermission = confPerm
186 }
187 }
Oriol Prieto Gascó12887ba2024-12-02 22:43:29 +0000188 var allowReadWrite bool
189 if requireAllReadOnly, ok := ctx.Config().GetBuildFlag("RELEASE_ACONFIG_REQUIRE_ALL_READ_ONLY"); ok {
190 // The build flag (RELEASE_ACONFIG_REQUIRE_ALL_READ_ONLY) is the negation of the aconfig flag
191 // (allow-read-write) for historical reasons.
192 // Bool build flags are always "" for false, and generally "true" for true.
193 allowReadWrite = requireAllReadOnly == ""
194 }
LaMont Jones21d04d92024-06-11 11:28:54 -0700195 inputFiles := make([]android.Path, len(declarationFiles))
196 copy(inputFiles, declarationFiles)
197 inputFiles = append(inputFiles, valuesFiles[config]...)
198 args := map[string]string{
199 "release_version": ctx.Config().ReleaseVersion(),
200 "package": module.properties.Package,
201 "declarations": android.JoinPathsWithPrefix(declarationFiles, "--declarations "),
202 "values": joinAndPrefix(" --values ", values[config]),
203 "default-permission": optionalVariable(" --default-permission ", defaultPermission),
Oriol Prieto Gascó12887ba2024-12-02 22:43:29 +0000204 "allow-read-write": optionalVariable(" --allow-read-write ", strconv.FormatBool(allowReadWrite)),
LaMont Jones21d04d92024-06-11 11:28:54 -0700205 }
206 if len(module.properties.Container) > 0 {
207 args["container"] = "--container " + module.properties.Container
208 }
209 ctx.Build(pctx, android.BuildParams{
210 Rule: aconfigRule,
211 Output: intermediateCacheFilePath,
212 Inputs: inputFiles,
213 Description: "aconfig_declarations",
214 Args: args,
215 })
216
217 intermediateDumpFilePath := android.PathForModuleOut(ctx, assembleFileName(config, "intermediate.txt"))
218 ctx.Build(pctx, android.BuildParams{
219 Rule: aconfigTextRule,
220 Output: intermediateDumpFilePath,
221 Inputs: android.Paths{intermediateCacheFilePath},
222 Description: "aconfig_text",
223 })
224
225 providerData[config] = android.AconfigDeclarationsProviderData{
226 Package: module.properties.Package,
227 Container: module.properties.Container,
228 Exportable: module.properties.Exportable,
229 IntermediateCacheOutputPath: intermediateCacheFilePath,
230 IntermediateDumpOutputPath: intermediateDumpFilePath,
231 }
Yu Liueeff2222024-03-19 23:07:34 +0000232 }
LaMont Jones21d04d92024-06-11 11:28:54 -0700233 android.SetProvider(ctx, android.AconfigDeclarationsProviderKey, providerData[""])
234 android.SetProvider(ctx, android.AconfigReleaseDeclarationsProviderKey, providerData)
Joe Onoratofee845a2023-05-09 08:14:14 -0700235}
Yu Liufa297642024-06-11 00:13:02 +0000236
Yu Liufa297642024-06-11 00:13:02 +0000237var _ blueprint.Incremental = &DeclarationsModule{}