blob: 817452499488821e4b3361c5d7e67b6c9707a93a [file] [log] [blame]
Paul Duffinc6bb7cf2021-04-08 17:49:27 +01001// Copyright (C) 2021 The Android Open Source Project
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 java
16
17import (
18 "android/soong/android"
Paul Duffin9b381ef2021-04-08 23:01:37 +010019 "github.com/google/blueprint"
Paul Duffinc6bb7cf2021-04-08 17:49:27 +010020)
21
22// Contains support for processing hiddenAPI in a modular fashion.
23
Paul Duffin74431d52021-04-21 14:10:42 +010024type hiddenAPIStubsDependencyTag struct {
25 blueprint.BaseDependencyTag
26 sdkKind android.SdkKind
27}
28
29func (b hiddenAPIStubsDependencyTag) ExcludeFromApexContents() {
30}
31
32func (b hiddenAPIStubsDependencyTag) ReplaceSourceWithPrebuilt() bool {
33 return false
34}
35
Paul Duffin976b0e52021-04-27 23:20:26 +010036func (b hiddenAPIStubsDependencyTag) SdkMemberType(child android.Module) android.SdkMemberType {
37 // If the module is a java_sdk_library then treat it as if it was specific in the java_sdk_libs
38 // property, otherwise treat if it was specified in the java_header_libs property.
39 if javaSdkLibrarySdkMemberType.IsInstance(child) {
40 return javaSdkLibrarySdkMemberType
41 }
42
43 return javaHeaderLibsSdkMemberType
44}
45
46func (b hiddenAPIStubsDependencyTag) ExportMember() bool {
47 // Export the module added via this dependency tag from the sdk.
48 return true
49}
50
Paul Duffin74431d52021-04-21 14:10:42 +010051// Avoid having to make stubs content explicitly visible to dependent modules.
52//
53// This is a temporary workaround to make it easier to migrate to bootclasspath_fragment modules
54// with proper dependencies.
55// TODO(b/177892522): Remove this and add needed visibility.
56func (b hiddenAPIStubsDependencyTag) ExcludeFromVisibilityEnforcement() {
57}
58
59var _ android.ExcludeFromVisibilityEnforcementTag = hiddenAPIStubsDependencyTag{}
60var _ android.ReplaceSourceWithPrebuilt = hiddenAPIStubsDependencyTag{}
61var _ android.ExcludeFromApexContentsTag = hiddenAPIStubsDependencyTag{}
Paul Duffin976b0e52021-04-27 23:20:26 +010062var _ android.SdkMemberTypeDependencyTag = hiddenAPIStubsDependencyTag{}
Paul Duffin74431d52021-04-21 14:10:42 +010063
Paul Duffin3e7fcc32021-04-15 13:31:38 +010064// hiddenAPIRelevantSdkKinds lists all the android.SdkKind instances that are needed by the hidden
65// API processing.
66var hiddenAPIRelevantSdkKinds = []android.SdkKind{
67 android.SdkPublic,
68 android.SdkSystem,
69 android.SdkTest,
70 android.SdkCorePlatform,
71}
72
Paul Duffin74431d52021-04-21 14:10:42 +010073// hiddenAPIComputeMonolithicStubLibModules computes the set of module names that provide stubs
74// needed to produce the hidden API monolithic stub flags file.
75func hiddenAPIComputeMonolithicStubLibModules(config android.Config) map[android.SdkKind][]string {
76 var publicStubModules []string
77 var systemStubModules []string
78 var testStubModules []string
79 var corePlatformStubModules []string
80
81 if config.AlwaysUsePrebuiltSdks() {
82 // Build configuration mandates using prebuilt stub modules
83 publicStubModules = append(publicStubModules, "sdk_public_current_android")
84 systemStubModules = append(systemStubModules, "sdk_system_current_android")
85 testStubModules = append(testStubModules, "sdk_test_current_android")
86 } else {
87 // Use stub modules built from source
88 publicStubModules = append(publicStubModules, "android_stubs_current")
89 systemStubModules = append(systemStubModules, "android_system_stubs_current")
90 testStubModules = append(testStubModules, "android_test_stubs_current")
91 }
92 // We do not have prebuilts of the core platform api yet
93 corePlatformStubModules = append(corePlatformStubModules, "legacy.core.platform.api.stubs")
94
95 // Allow products to define their own stubs for custom product jars that apps can use.
96 publicStubModules = append(publicStubModules, config.ProductHiddenAPIStubs()...)
97 systemStubModules = append(systemStubModules, config.ProductHiddenAPIStubsSystem()...)
98 testStubModules = append(testStubModules, config.ProductHiddenAPIStubsTest()...)
99 if config.IsEnvTrue("EMMA_INSTRUMENT") {
100 publicStubModules = append(publicStubModules, "jacoco-stubs")
101 }
102
103 m := map[android.SdkKind][]string{}
104 m[android.SdkPublic] = publicStubModules
105 m[android.SdkSystem] = systemStubModules
106 m[android.SdkTest] = testStubModules
107 m[android.SdkCorePlatform] = corePlatformStubModules
108 return m
109}
110
111// hiddenAPIAddStubLibDependencies adds dependencies onto the modules specified in
112// sdkKindToStubLibModules. It adds them in a well known order and uses an SdkKind specific tag to
113// identify the source of the dependency.
114func hiddenAPIAddStubLibDependencies(ctx android.BottomUpMutatorContext, sdkKindToStubLibModules map[android.SdkKind][]string) {
115 module := ctx.Module()
116 for _, sdkKind := range hiddenAPIRelevantSdkKinds {
117 modules := sdkKindToStubLibModules[sdkKind]
118 ctx.AddDependency(module, hiddenAPIStubsDependencyTag{sdkKind: sdkKind}, modules...)
119 }
120}
121
122// hiddenAPIGatherStubLibDexJarPaths gathers the paths to the dex jars from the dependencies added
123// in hiddenAPIAddStubLibDependencies.
124func hiddenAPIGatherStubLibDexJarPaths(ctx android.ModuleContext) map[android.SdkKind]android.Paths {
125 m := map[android.SdkKind]android.Paths{}
126 ctx.VisitDirectDepsIf(isActiveModule, func(module android.Module) {
127 tag := ctx.OtherModuleDependencyTag(module)
128 if hiddenAPIStubsTag, ok := tag.(hiddenAPIStubsDependencyTag); ok {
129 kind := hiddenAPIStubsTag.sdkKind
Paul Duffin10931582021-04-25 10:13:54 +0100130 dexJar := hiddenAPIRetrieveDexJarBuildPath(ctx, module, kind)
Paul Duffin74431d52021-04-21 14:10:42 +0100131 if dexJar != nil {
132 m[kind] = append(m[kind], dexJar)
133 }
134 }
135 })
136 return m
137}
138
139// hiddenAPIRetrieveDexJarBuildPath retrieves the DexJarBuildPath from the specified module, if
140// available, or reports an error.
Paul Duffin10931582021-04-25 10:13:54 +0100141func hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android.Module, kind android.SdkKind) android.Path {
142 var dexJar android.Path
143 if sdkLibrary, ok := module.(SdkLibraryDependency); ok {
144 dexJar = sdkLibrary.SdkApiStubDexJar(ctx, kind)
145 } else if j, ok := module.(UsesLibraryDependency); ok {
146 dexJar = j.DexJarBuildPath()
Paul Duffin74431d52021-04-21 14:10:42 +0100147 } else {
148 ctx.ModuleErrorf("dependency %s of module type %s does not support providing a dex jar", module, ctx.OtherModuleType(module))
Paul Duffin10931582021-04-25 10:13:54 +0100149 return nil
Paul Duffin74431d52021-04-21 14:10:42 +0100150 }
Paul Duffin10931582021-04-25 10:13:54 +0100151
152 if dexJar == nil {
153 ctx.ModuleErrorf("dependency %s does not provide a dex jar, consider setting compile_dex: true", module)
154 }
155 return dexJar
Paul Duffin74431d52021-04-21 14:10:42 +0100156}
157
158var sdkKindToHiddenapiListOption = map[android.SdkKind]string{
159 android.SdkPublic: "public-stub-classpath",
160 android.SdkSystem: "system-stub-classpath",
161 android.SdkTest: "test-stub-classpath",
162 android.SdkCorePlatform: "core-platform-stub-classpath",
163}
164
165// ruleToGenerateHiddenAPIStubFlagsFile creates a rule to create a hidden API stub flags file.
166//
167// The rule is initialized but not built so that the caller can modify it and select an appropriate
168// name.
Paul Duffin2fef1362021-04-15 13:32:00 +0100169func ruleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, outputPath android.WritablePath, bootDexJars android.Paths, sdkKindToPathList map[android.SdkKind]android.Paths) *android.RuleBuilder {
Paul Duffin74431d52021-04-21 14:10:42 +0100170 // Singleton rule which applies hiddenapi on all boot class path dex files.
171 rule := android.NewRuleBuilder(pctx, ctx)
172
173 tempPath := tempPathForRestat(ctx, outputPath)
174
175 command := rule.Command().
176 Tool(ctx.Config().HostToolPath(ctx, "hiddenapi")).
177 Text("list").
178 FlagForEachInput("--boot-dex=", bootDexJars)
179
180 // Iterate over the sdk kinds in a fixed order.
181 for _, sdkKind := range hiddenAPIRelevantSdkKinds {
182 paths := sdkKindToPathList[sdkKind]
183 if len(paths) > 0 {
184 option := sdkKindToHiddenapiListOption[sdkKind]
185 command.FlagWithInputList("--"+option+"=", paths, ":")
186 }
187 }
188
189 // Add the output path.
190 command.FlagWithOutput("--out-api-flags=", tempPath)
191
192 commitChangeForRestat(rule, tempPath, outputPath)
193 return rule
194}
195
Paul Duffin46169772021-04-14 15:01:56 +0100196// HiddenAPIFlagFileProperties contains paths to the flag files that can be used to augment the
197// information obtained from annotations within the source code in order to create the complete set
198// of flags that should be applied to the dex implementation jars on the bootclasspath.
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100199//
200// Each property contains a list of paths. With the exception of the Unsupported_packages the paths
201// of each property reference a plain text file that contains a java signature per line. The flags
202// for each of those signatures will be updated in a property specific way.
203//
204// The Unsupported_packages property contains a list of paths, each of which is a plain text file
205// with one Java package per line. All members of all classes within that package (but not nested
206// packages) will be updated in a property specific way.
Paul Duffin46169772021-04-14 15:01:56 +0100207type HiddenAPIFlagFileProperties struct {
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100208 // Marks each signature in the referenced files as being unsupported.
Paul Duffin702210b2021-04-08 20:12:41 +0100209 Unsupported []string `android:"path"`
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100210
211 // Marks each signature in the referenced files as being unsupported because it has been removed.
212 // Any conflicts with other flags are ignored.
Paul Duffin702210b2021-04-08 20:12:41 +0100213 Removed []string `android:"path"`
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100214
215 // Marks each signature in the referenced files as being supported only for targetSdkVersion <= R
216 // and low priority.
Paul Duffin702210b2021-04-08 20:12:41 +0100217 Max_target_r_low_priority []string `android:"path"`
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100218
219 // Marks each signature in the referenced files as being supported only for targetSdkVersion <= Q.
Paul Duffin702210b2021-04-08 20:12:41 +0100220 Max_target_q []string `android:"path"`
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100221
222 // Marks each signature in the referenced files as being supported only for targetSdkVersion <= P.
Paul Duffin702210b2021-04-08 20:12:41 +0100223 Max_target_p []string `android:"path"`
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100224
225 // Marks each signature in the referenced files as being supported only for targetSdkVersion <= O
226 // and low priority. Any conflicts with other flags are ignored.
Paul Duffin702210b2021-04-08 20:12:41 +0100227 Max_target_o_low_priority []string `android:"path"`
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100228
229 // Marks each signature in the referenced files as being blocked.
Paul Duffin702210b2021-04-08 20:12:41 +0100230 Blocked []string `android:"path"`
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100231
232 // Marks each signature in every package in the referenced files as being unsupported.
Paul Duffin702210b2021-04-08 20:12:41 +0100233 Unsupported_packages []string `android:"path"`
234}
235
Paul Duffin46169772021-04-14 15:01:56 +0100236func (p *HiddenAPIFlagFileProperties) hiddenAPIFlagFileInfo(ctx android.ModuleContext) hiddenAPIFlagFileInfo {
237 info := hiddenAPIFlagFileInfo{categoryToPaths: map[*hiddenAPIFlagFileCategory]android.Paths{}}
Paul Duffine3dc6602021-04-14 09:50:43 +0100238 for _, category := range hiddenAPIFlagFileCategories {
Paul Duffincc17bfe2021-04-19 13:21:20 +0100239 paths := android.PathsForModuleSrc(ctx, category.propertyValueReader(p))
Paul Duffine3dc6602021-04-14 09:50:43 +0100240 info.categoryToPaths[category] = paths
Paul Duffin702210b2021-04-08 20:12:41 +0100241 }
Paul Duffine3dc6602021-04-14 09:50:43 +0100242 return info
243}
244
245type hiddenAPIFlagFileCategory struct {
246 // propertyName is the name of the property for this category.
247 propertyName string
248
Paul Duffincc17bfe2021-04-19 13:21:20 +0100249 // propertyValueReader retrieves the value of the property for this category from the set of
Paul Duffine3dc6602021-04-14 09:50:43 +0100250 // properties.
Paul Duffincc17bfe2021-04-19 13:21:20 +0100251 propertyValueReader func(properties *HiddenAPIFlagFileProperties) []string
Paul Duffine3dc6602021-04-14 09:50:43 +0100252
253 // commandMutator adds the appropriate command line options for this category to the supplied
254 // command
255 commandMutator func(command *android.RuleBuilderCommand, path android.Path)
256}
257
258var hiddenAPIFlagFileCategories = []*hiddenAPIFlagFileCategory{
Paul Duffin46169772021-04-14 15:01:56 +0100259 // See HiddenAPIFlagFileProperties.Unsupported
Paul Duffine3dc6602021-04-14 09:50:43 +0100260 {
261 propertyName: "unsupported",
Paul Duffincc17bfe2021-04-19 13:21:20 +0100262 propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
Paul Duffine3dc6602021-04-14 09:50:43 +0100263 return properties.Unsupported
264 },
265 commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
266 command.FlagWithInput("--unsupported ", path)
267 },
268 },
Paul Duffin46169772021-04-14 15:01:56 +0100269 // See HiddenAPIFlagFileProperties.Removed
Paul Duffine3dc6602021-04-14 09:50:43 +0100270 {
271 propertyName: "removed",
Paul Duffincc17bfe2021-04-19 13:21:20 +0100272 propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
Paul Duffine3dc6602021-04-14 09:50:43 +0100273 return properties.Removed
274 },
275 commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
276 command.FlagWithInput("--unsupported ", path).Flag("--ignore-conflicts ").FlagWithArg("--tag ", "removed")
277 },
278 },
Paul Duffin46169772021-04-14 15:01:56 +0100279 // See HiddenAPIFlagFileProperties.Max_target_r_low_priority
Paul Duffine3dc6602021-04-14 09:50:43 +0100280 {
281 propertyName: "max_target_r_low_priority",
Paul Duffincc17bfe2021-04-19 13:21:20 +0100282 propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
Paul Duffine3dc6602021-04-14 09:50:43 +0100283 return properties.Max_target_r_low_priority
284 },
285 commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
286 command.FlagWithInput("--max-target-r ", path).FlagWithArg("--tag ", "lo-prio")
287 },
288 },
Paul Duffin46169772021-04-14 15:01:56 +0100289 // See HiddenAPIFlagFileProperties.Max_target_q
Paul Duffine3dc6602021-04-14 09:50:43 +0100290 {
291 propertyName: "max_target_q",
Paul Duffincc17bfe2021-04-19 13:21:20 +0100292 propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
Paul Duffine3dc6602021-04-14 09:50:43 +0100293 return properties.Max_target_q
294 },
295 commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
296 command.FlagWithInput("--max-target-q ", path)
297 },
298 },
Paul Duffin46169772021-04-14 15:01:56 +0100299 // See HiddenAPIFlagFileProperties.Max_target_p
Paul Duffine3dc6602021-04-14 09:50:43 +0100300 {
301 propertyName: "max_target_p",
Paul Duffincc17bfe2021-04-19 13:21:20 +0100302 propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
Paul Duffine3dc6602021-04-14 09:50:43 +0100303 return properties.Max_target_p
304 },
305 commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
306 command.FlagWithInput("--max-target-p ", path)
307 },
308 },
Paul Duffin46169772021-04-14 15:01:56 +0100309 // See HiddenAPIFlagFileProperties.Max_target_o_low_priority
Paul Duffine3dc6602021-04-14 09:50:43 +0100310 {
311 propertyName: "max_target_o_low_priority",
Paul Duffincc17bfe2021-04-19 13:21:20 +0100312 propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
Paul Duffine3dc6602021-04-14 09:50:43 +0100313 return properties.Max_target_o_low_priority
314 },
315 commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
316 command.FlagWithInput("--max-target-o ", path).Flag("--ignore-conflicts ").FlagWithArg("--tag ", "lo-prio")
317 },
318 },
Paul Duffin46169772021-04-14 15:01:56 +0100319 // See HiddenAPIFlagFileProperties.Blocked
Paul Duffine3dc6602021-04-14 09:50:43 +0100320 {
321 propertyName: "blocked",
Paul Duffincc17bfe2021-04-19 13:21:20 +0100322 propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
Paul Duffine3dc6602021-04-14 09:50:43 +0100323 return properties.Blocked
324 },
325 commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
326 command.FlagWithInput("--blocked ", path)
327 },
328 },
Paul Duffin46169772021-04-14 15:01:56 +0100329 // See HiddenAPIFlagFileProperties.Unsupported_packages
Paul Duffine3dc6602021-04-14 09:50:43 +0100330 {
331 propertyName: "unsupported_packages",
Paul Duffincc17bfe2021-04-19 13:21:20 +0100332 propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
Paul Duffine3dc6602021-04-14 09:50:43 +0100333 return properties.Unsupported_packages
334 },
335 commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
336 command.FlagWithInput("--unsupported ", path).Flag("--packages ")
337 },
338 },
Paul Duffin702210b2021-04-08 20:12:41 +0100339}
340
Paul Duffin2fef1362021-04-15 13:32:00 +0100341// hiddenAPIFlagFileInfo contains paths resolved from HiddenAPIFlagFileProperties and also generated
342// by hidden API processing.
343//
344// This is used both for an individual bootclasspath_fragment to provide it to other modules and
345// for a module to collate the files from the fragments it depends upon. That is why the fields are
346// all Paths even though they are initialized with a single path.
Paul Duffin46169772021-04-14 15:01:56 +0100347type hiddenAPIFlagFileInfo struct {
Paul Duffine3dc6602021-04-14 09:50:43 +0100348 // categoryToPaths maps from the flag file category to the paths containing information for that
349 // category.
350 categoryToPaths map[*hiddenAPIFlagFileCategory]android.Paths
Paul Duffin2fef1362021-04-15 13:32:00 +0100351
352 // The paths to the generated stub-flags.csv files.
353 StubFlagsPaths android.Paths
354
355 // The paths to the generated annotation-flags.csv files.
356 AnnotationFlagsPaths android.Paths
357
358 // The paths to the generated metadata.csv files.
359 MetadataPaths android.Paths
360
361 // The paths to the generated index.csv files.
362 IndexPaths android.Paths
363
364 // The paths to the generated all-flags.csv files.
365 AllFlagsPaths android.Paths
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100366}
Paul Duffin702210b2021-04-08 20:12:41 +0100367
Paul Duffin9b381ef2021-04-08 23:01:37 +0100368func (i *hiddenAPIFlagFileInfo) append(other hiddenAPIFlagFileInfo) {
369 for _, category := range hiddenAPIFlagFileCategories {
370 i.categoryToPaths[category] = append(i.categoryToPaths[category], other.categoryToPaths[category]...)
371 }
Paul Duffin2fef1362021-04-15 13:32:00 +0100372 i.StubFlagsPaths = append(i.StubFlagsPaths, other.StubFlagsPaths...)
373 i.AnnotationFlagsPaths = append(i.AnnotationFlagsPaths, other.AnnotationFlagsPaths...)
374 i.MetadataPaths = append(i.MetadataPaths, other.MetadataPaths...)
375 i.IndexPaths = append(i.IndexPaths, other.IndexPaths...)
376 i.AllFlagsPaths = append(i.AllFlagsPaths, other.AllFlagsPaths...)
Paul Duffin9b381ef2021-04-08 23:01:37 +0100377}
378
379var hiddenAPIFlagFileInfoProvider = blueprint.NewProvider(hiddenAPIFlagFileInfo{})
380
Paul Duffin2fef1362021-04-15 13:32:00 +0100381// buildRuleToGenerateHiddenApiFlags creates a rule to create the monolithic hidden API flags from
382// the flags from all the modules, the stub flags, augmented with some additional configuration
383// files.
Paul Duffin702210b2021-04-08 20:12:41 +0100384//
385// baseFlagsPath is the path to the flags file containing all the information from the stubs plus
386// an entry for every single member in the dex implementation jars of the individual modules. Every
387// signature in any of the other files MUST be included in this file.
388//
389// moduleSpecificFlagsPaths are the paths to the flags files generated by each module using
390// information from the baseFlagsPath as well as from annotations within the source.
391//
392// augmentationInfo is a struct containing paths to files that augment the information provided by
393// the moduleSpecificFlagsPaths.
Paul Duffin2fef1362021-04-15 13:32:00 +0100394func buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc string, outputPath android.WritablePath, baseFlagsPath android.Path, moduleSpecificFlagsPaths android.Paths, flagFileInfo *hiddenAPIFlagFileInfo) {
Paul Duffind3c15132021-04-21 22:12:35 +0100395 tempPath := tempPathForRestat(ctx, outputPath)
Paul Duffin702210b2021-04-08 20:12:41 +0100396 rule := android.NewRuleBuilder(pctx, ctx)
397 command := rule.Command().
398 BuiltTool("generate_hiddenapi_lists").
399 FlagWithInput("--csv ", baseFlagsPath).
400 Inputs(moduleSpecificFlagsPaths).
401 FlagWithOutput("--output ", tempPath)
402
Paul Duffine3dc6602021-04-14 09:50:43 +0100403 // Add the options for the different categories of flag files.
404 for _, category := range hiddenAPIFlagFileCategories {
Paul Duffin2fef1362021-04-15 13:32:00 +0100405 paths := flagFileInfo.categoryToPaths[category]
Paul Duffine3dc6602021-04-14 09:50:43 +0100406 for _, path := range paths {
407 category.commandMutator(command, path)
408 }
Paul Duffin702210b2021-04-08 20:12:41 +0100409 }
410
411 commitChangeForRestat(rule, tempPath, outputPath)
412
Paul Duffin2fef1362021-04-15 13:32:00 +0100413 rule.Build(name, desc)
414}
415
416// hiddenAPIGenerateAllFlagsForBootclasspathFragment will generate all the flags for a fragment
417// of the bootclasspath.
418//
419// It takes:
420// * Map from android.SdkKind to stub dex jar paths defining the API for that sdk kind.
421// * The list of modules that are the contents of the fragment.
422// * The additional manually curated flag files to use.
423//
424// It generates:
425// * stub-flags.csv
426// * annotation-flags.csv
427// * metadata.csv
428// * index.csv
429// * all-flags.csv
430func hiddenAPIGenerateAllFlagsForBootclasspathFragment(ctx android.ModuleContext, contents []android.Module, stubJarsByKind map[android.SdkKind]android.Paths, flagFileInfo *hiddenAPIFlagFileInfo) {
431
432 hiddenApiSubDir := "modular-hiddenapi"
433
434 bootDexJars := android.Paths{}
435 classesJars := android.Paths{}
436 for _, module := range contents {
437 if hiddenAPI, ok := module.(hiddenAPIIntf); ok {
438 classesJars = append(classesJars, hiddenAPI.classesJars()...)
439 bootDexJar := hiddenAPI.bootDexJar()
440 if bootDexJar == nil {
441 ctx.ModuleErrorf("module %s does not provide a dex jar", module)
442 } else {
443 bootDexJars = append(bootDexJars, bootDexJar)
444 }
445 } else {
446 ctx.ModuleErrorf("module %s does not implement hiddenAPIIntf", module)
447 }
448 }
449
450 // Generate the stub-flags.csv.
451 stubFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "stub-flags.csv")
452 rule := ruleToGenerateHiddenAPIStubFlagsFile(ctx, stubFlagsCSV, bootDexJars, stubJarsByKind)
453 rule.Build("modularHiddenAPIStubFlagsFile", "modular hiddenapi stub flags")
454
455 // Generate the set of flags from the annotations in the source code.
456 annotationFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "annotation-flags.csv")
457 ctx.Build(pctx, android.BuildParams{
458 Rule: hiddenAPIGenerateCSVRule,
459 Description: "modular hiddenapi annotation flags",
460 Inputs: classesJars,
461 Output: annotationFlagsCSV,
462 Implicit: stubFlagsCSV,
463 Args: map[string]string{
464 "outFlag": "--write-flags-csv",
465 "stubAPIFlags": stubFlagsCSV.String(),
466 },
467 })
468
469 // Generate the metadata from the annotations in the source code.
470 metadataCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "metadata.csv")
471 ctx.Build(pctx, android.BuildParams{
472 Rule: hiddenAPIGenerateCSVRule,
473 Description: "modular hiddenapi metadata",
474 Inputs: classesJars,
475 Output: metadataCSV,
476 Implicit: stubFlagsCSV,
477 Args: map[string]string{
478 "outFlag": "--write-metadata-csv",
479 "stubAPIFlags": stubFlagsCSV.String(),
480 },
481 })
482
483 // Generate the index file from the annotations in the source code.
484 indexCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "index.csv")
485 rule = android.NewRuleBuilder(pctx, ctx)
486 rule.Command().
487 BuiltTool("merge_csv").
488 Flag("--zip_input").
489 Flag("--key_field signature").
490 FlagWithOutput("--output=", indexCSV).
491 Inputs(classesJars)
492 rule.Build("modular-hiddenapi-index", "modular hiddenapi index")
493
494 // Removed APIs need to be marked and in order to do that the flagFileInfo needs to specify files
495 // containing dex signatures of all the removed APIs. In the monolithic files that is done by
496 // manually combining all the removed.txt files for each API and then converting them to dex
497 // signatures, see the combined-removed-dex module. That will all be done automatically in future.
498 // For now removed APIs are ignored.
499 // TODO(b/179354495): handle removed apis automatically.
500
501 // Generate the all-flags.csv which are the flags that will, in future, be encoded into the dex
502 // files.
503 outputPath := android.PathForModuleOut(ctx, hiddenApiSubDir, "all-flags.csv")
504 buildRuleToGenerateHiddenApiFlags(ctx, "modularHiddenApiAllFlags", "modular hiddenapi all flags", outputPath, stubFlagsCSV, android.Paths{annotationFlagsCSV}, flagFileInfo)
505
506 // Store the paths in the info for use by other modules and sdk snapshot generation.
507 flagFileInfo.StubFlagsPaths = android.Paths{stubFlagsCSV}
508 flagFileInfo.AnnotationFlagsPaths = android.Paths{annotationFlagsCSV}
509 flagFileInfo.MetadataPaths = android.Paths{metadataCSV}
510 flagFileInfo.IndexPaths = android.Paths{indexCSV}
511 flagFileInfo.AllFlagsPaths = android.Paths{outputPath}
Paul Duffin702210b2021-04-08 20:12:41 +0100512}