blob: 8cc6f8f23ba33dc7fad0507877bfd5fbae61b8bd [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
36// Avoid having to make stubs content explicitly visible to dependent modules.
37//
38// This is a temporary workaround to make it easier to migrate to bootclasspath_fragment modules
39// with proper dependencies.
40// TODO(b/177892522): Remove this and add needed visibility.
41func (b hiddenAPIStubsDependencyTag) ExcludeFromVisibilityEnforcement() {
42}
43
44var _ android.ExcludeFromVisibilityEnforcementTag = hiddenAPIStubsDependencyTag{}
45var _ android.ReplaceSourceWithPrebuilt = hiddenAPIStubsDependencyTag{}
46var _ android.ExcludeFromApexContentsTag = hiddenAPIStubsDependencyTag{}
47
Paul Duffin3e7fcc32021-04-15 13:31:38 +010048// hiddenAPIRelevantSdkKinds lists all the android.SdkKind instances that are needed by the hidden
49// API processing.
50var hiddenAPIRelevantSdkKinds = []android.SdkKind{
51 android.SdkPublic,
52 android.SdkSystem,
53 android.SdkTest,
54 android.SdkCorePlatform,
55}
56
Paul Duffin74431d52021-04-21 14:10:42 +010057// hiddenAPIComputeMonolithicStubLibModules computes the set of module names that provide stubs
58// needed to produce the hidden API monolithic stub flags file.
59func hiddenAPIComputeMonolithicStubLibModules(config android.Config) map[android.SdkKind][]string {
60 var publicStubModules []string
61 var systemStubModules []string
62 var testStubModules []string
63 var corePlatformStubModules []string
64
65 if config.AlwaysUsePrebuiltSdks() {
66 // Build configuration mandates using prebuilt stub modules
67 publicStubModules = append(publicStubModules, "sdk_public_current_android")
68 systemStubModules = append(systemStubModules, "sdk_system_current_android")
69 testStubModules = append(testStubModules, "sdk_test_current_android")
70 } else {
71 // Use stub modules built from source
72 publicStubModules = append(publicStubModules, "android_stubs_current")
73 systemStubModules = append(systemStubModules, "android_system_stubs_current")
74 testStubModules = append(testStubModules, "android_test_stubs_current")
75 }
76 // We do not have prebuilts of the core platform api yet
77 corePlatformStubModules = append(corePlatformStubModules, "legacy.core.platform.api.stubs")
78
79 // Allow products to define their own stubs for custom product jars that apps can use.
80 publicStubModules = append(publicStubModules, config.ProductHiddenAPIStubs()...)
81 systemStubModules = append(systemStubModules, config.ProductHiddenAPIStubsSystem()...)
82 testStubModules = append(testStubModules, config.ProductHiddenAPIStubsTest()...)
83 if config.IsEnvTrue("EMMA_INSTRUMENT") {
84 publicStubModules = append(publicStubModules, "jacoco-stubs")
85 }
86
87 m := map[android.SdkKind][]string{}
88 m[android.SdkPublic] = publicStubModules
89 m[android.SdkSystem] = systemStubModules
90 m[android.SdkTest] = testStubModules
91 m[android.SdkCorePlatform] = corePlatformStubModules
92 return m
93}
94
95// hiddenAPIAddStubLibDependencies adds dependencies onto the modules specified in
96// sdkKindToStubLibModules. It adds them in a well known order and uses an SdkKind specific tag to
97// identify the source of the dependency.
98func hiddenAPIAddStubLibDependencies(ctx android.BottomUpMutatorContext, sdkKindToStubLibModules map[android.SdkKind][]string) {
99 module := ctx.Module()
100 for _, sdkKind := range hiddenAPIRelevantSdkKinds {
101 modules := sdkKindToStubLibModules[sdkKind]
102 ctx.AddDependency(module, hiddenAPIStubsDependencyTag{sdkKind: sdkKind}, modules...)
103 }
104}
105
106// hiddenAPIGatherStubLibDexJarPaths gathers the paths to the dex jars from the dependencies added
107// in hiddenAPIAddStubLibDependencies.
108func hiddenAPIGatherStubLibDexJarPaths(ctx android.ModuleContext) map[android.SdkKind]android.Paths {
109 m := map[android.SdkKind]android.Paths{}
110 ctx.VisitDirectDepsIf(isActiveModule, func(module android.Module) {
111 tag := ctx.OtherModuleDependencyTag(module)
112 if hiddenAPIStubsTag, ok := tag.(hiddenAPIStubsDependencyTag); ok {
113 kind := hiddenAPIStubsTag.sdkKind
114 dexJar := hiddenAPIRetrieveDexJarBuildPath(ctx, module)
115 if dexJar != nil {
116 m[kind] = append(m[kind], dexJar)
117 }
118 }
119 })
120 return m
121}
122
123// hiddenAPIRetrieveDexJarBuildPath retrieves the DexJarBuildPath from the specified module, if
124// available, or reports an error.
125func hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android.Module) android.Path {
126 if j, ok := module.(UsesLibraryDependency); ok {
127 dexJar := j.DexJarBuildPath()
128 if dexJar != nil {
129 return dexJar
130 }
131 ctx.ModuleErrorf("dependency %s does not provide a dex jar, consider setting compile_dex: true", module)
132 } else {
133 ctx.ModuleErrorf("dependency %s of module type %s does not support providing a dex jar", module, ctx.OtherModuleType(module))
134 }
135 return nil
136}
137
138var sdkKindToHiddenapiListOption = map[android.SdkKind]string{
139 android.SdkPublic: "public-stub-classpath",
140 android.SdkSystem: "system-stub-classpath",
141 android.SdkTest: "test-stub-classpath",
142 android.SdkCorePlatform: "core-platform-stub-classpath",
143}
144
145// ruleToGenerateHiddenAPIStubFlagsFile creates a rule to create a hidden API stub flags file.
146//
147// The rule is initialized but not built so that the caller can modify it and select an appropriate
148// name.
149func ruleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, outputPath android.OutputPath, bootDexJars android.Paths, sdkKindToPathList map[android.SdkKind]android.Paths) *android.RuleBuilder {
150 // Singleton rule which applies hiddenapi on all boot class path dex files.
151 rule := android.NewRuleBuilder(pctx, ctx)
152
153 tempPath := tempPathForRestat(ctx, outputPath)
154
155 command := rule.Command().
156 Tool(ctx.Config().HostToolPath(ctx, "hiddenapi")).
157 Text("list").
158 FlagForEachInput("--boot-dex=", bootDexJars)
159
160 // Iterate over the sdk kinds in a fixed order.
161 for _, sdkKind := range hiddenAPIRelevantSdkKinds {
162 paths := sdkKindToPathList[sdkKind]
163 if len(paths) > 0 {
164 option := sdkKindToHiddenapiListOption[sdkKind]
165 command.FlagWithInputList("--"+option+"=", paths, ":")
166 }
167 }
168
169 // Add the output path.
170 command.FlagWithOutput("--out-api-flags=", tempPath)
171
172 commitChangeForRestat(rule, tempPath, outputPath)
173 return rule
174}
175
Paul Duffin46169772021-04-14 15:01:56 +0100176// HiddenAPIFlagFileProperties contains paths to the flag files that can be used to augment the
177// information obtained from annotations within the source code in order to create the complete set
178// of flags that should be applied to the dex implementation jars on the bootclasspath.
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100179//
180// Each property contains a list of paths. With the exception of the Unsupported_packages the paths
181// of each property reference a plain text file that contains a java signature per line. The flags
182// for each of those signatures will be updated in a property specific way.
183//
184// The Unsupported_packages property contains a list of paths, each of which is a plain text file
185// with one Java package per line. All members of all classes within that package (but not nested
186// packages) will be updated in a property specific way.
Paul Duffin46169772021-04-14 15:01:56 +0100187type HiddenAPIFlagFileProperties struct {
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100188 // Marks each signature in the referenced files as being unsupported.
Paul Duffin702210b2021-04-08 20:12:41 +0100189 Unsupported []string `android:"path"`
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100190
191 // Marks each signature in the referenced files as being unsupported because it has been removed.
192 // Any conflicts with other flags are ignored.
Paul Duffin702210b2021-04-08 20:12:41 +0100193 Removed []string `android:"path"`
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100194
195 // Marks each signature in the referenced files as being supported only for targetSdkVersion <= R
196 // and low priority.
Paul Duffin702210b2021-04-08 20:12:41 +0100197 Max_target_r_low_priority []string `android:"path"`
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100198
199 // Marks each signature in the referenced files as being supported only for targetSdkVersion <= Q.
Paul Duffin702210b2021-04-08 20:12:41 +0100200 Max_target_q []string `android:"path"`
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100201
202 // Marks each signature in the referenced files as being supported only for targetSdkVersion <= P.
Paul Duffin702210b2021-04-08 20:12:41 +0100203 Max_target_p []string `android:"path"`
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100204
205 // Marks each signature in the referenced files as being supported only for targetSdkVersion <= O
206 // and low priority. Any conflicts with other flags are ignored.
Paul Duffin702210b2021-04-08 20:12:41 +0100207 Max_target_o_low_priority []string `android:"path"`
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100208
209 // Marks each signature in the referenced files as being blocked.
Paul Duffin702210b2021-04-08 20:12:41 +0100210 Blocked []string `android:"path"`
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100211
212 // Marks each signature in every package in the referenced files as being unsupported.
Paul Duffin702210b2021-04-08 20:12:41 +0100213 Unsupported_packages []string `android:"path"`
214}
215
Paul Duffin46169772021-04-14 15:01:56 +0100216func (p *HiddenAPIFlagFileProperties) hiddenAPIFlagFileInfo(ctx android.ModuleContext) hiddenAPIFlagFileInfo {
217 info := hiddenAPIFlagFileInfo{categoryToPaths: map[*hiddenAPIFlagFileCategory]android.Paths{}}
Paul Duffine3dc6602021-04-14 09:50:43 +0100218 for _, category := range hiddenAPIFlagFileCategories {
Paul Duffincc17bfe2021-04-19 13:21:20 +0100219 paths := android.PathsForModuleSrc(ctx, category.propertyValueReader(p))
Paul Duffine3dc6602021-04-14 09:50:43 +0100220 info.categoryToPaths[category] = paths
Paul Duffin702210b2021-04-08 20:12:41 +0100221 }
Paul Duffine3dc6602021-04-14 09:50:43 +0100222 return info
223}
224
225type hiddenAPIFlagFileCategory struct {
226 // propertyName is the name of the property for this category.
227 propertyName string
228
Paul Duffincc17bfe2021-04-19 13:21:20 +0100229 // propertyValueReader retrieves the value of the property for this category from the set of
Paul Duffine3dc6602021-04-14 09:50:43 +0100230 // properties.
Paul Duffincc17bfe2021-04-19 13:21:20 +0100231 propertyValueReader func(properties *HiddenAPIFlagFileProperties) []string
Paul Duffine3dc6602021-04-14 09:50:43 +0100232
233 // commandMutator adds the appropriate command line options for this category to the supplied
234 // command
235 commandMutator func(command *android.RuleBuilderCommand, path android.Path)
236}
237
238var hiddenAPIFlagFileCategories = []*hiddenAPIFlagFileCategory{
Paul Duffin46169772021-04-14 15:01:56 +0100239 // See HiddenAPIFlagFileProperties.Unsupported
Paul Duffine3dc6602021-04-14 09:50:43 +0100240 {
241 propertyName: "unsupported",
Paul Duffincc17bfe2021-04-19 13:21:20 +0100242 propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
Paul Duffine3dc6602021-04-14 09:50:43 +0100243 return properties.Unsupported
244 },
245 commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
246 command.FlagWithInput("--unsupported ", path)
247 },
248 },
Paul Duffin46169772021-04-14 15:01:56 +0100249 // See HiddenAPIFlagFileProperties.Removed
Paul Duffine3dc6602021-04-14 09:50:43 +0100250 {
251 propertyName: "removed",
Paul Duffincc17bfe2021-04-19 13:21:20 +0100252 propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
Paul Duffine3dc6602021-04-14 09:50:43 +0100253 return properties.Removed
254 },
255 commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
256 command.FlagWithInput("--unsupported ", path).Flag("--ignore-conflicts ").FlagWithArg("--tag ", "removed")
257 },
258 },
Paul Duffin46169772021-04-14 15:01:56 +0100259 // See HiddenAPIFlagFileProperties.Max_target_r_low_priority
Paul Duffine3dc6602021-04-14 09:50:43 +0100260 {
261 propertyName: "max_target_r_low_priority",
Paul Duffincc17bfe2021-04-19 13:21:20 +0100262 propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
Paul Duffine3dc6602021-04-14 09:50:43 +0100263 return properties.Max_target_r_low_priority
264 },
265 commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
266 command.FlagWithInput("--max-target-r ", path).FlagWithArg("--tag ", "lo-prio")
267 },
268 },
Paul Duffin46169772021-04-14 15:01:56 +0100269 // See HiddenAPIFlagFileProperties.Max_target_q
Paul Duffine3dc6602021-04-14 09:50:43 +0100270 {
271 propertyName: "max_target_q",
Paul Duffincc17bfe2021-04-19 13:21:20 +0100272 propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
Paul Duffine3dc6602021-04-14 09:50:43 +0100273 return properties.Max_target_q
274 },
275 commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
276 command.FlagWithInput("--max-target-q ", path)
277 },
278 },
Paul Duffin46169772021-04-14 15:01:56 +0100279 // See HiddenAPIFlagFileProperties.Max_target_p
Paul Duffine3dc6602021-04-14 09:50:43 +0100280 {
281 propertyName: "max_target_p",
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_p
284 },
285 commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
286 command.FlagWithInput("--max-target-p ", path)
287 },
288 },
Paul Duffin46169772021-04-14 15:01:56 +0100289 // See HiddenAPIFlagFileProperties.Max_target_o_low_priority
Paul Duffine3dc6602021-04-14 09:50:43 +0100290 {
291 propertyName: "max_target_o_low_priority",
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_o_low_priority
294 },
295 commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
296 command.FlagWithInput("--max-target-o ", path).Flag("--ignore-conflicts ").FlagWithArg("--tag ", "lo-prio")
297 },
298 },
Paul Duffin46169772021-04-14 15:01:56 +0100299 // See HiddenAPIFlagFileProperties.Blocked
Paul Duffine3dc6602021-04-14 09:50:43 +0100300 {
301 propertyName: "blocked",
Paul Duffincc17bfe2021-04-19 13:21:20 +0100302 propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
Paul Duffine3dc6602021-04-14 09:50:43 +0100303 return properties.Blocked
304 },
305 commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
306 command.FlagWithInput("--blocked ", path)
307 },
308 },
Paul Duffin46169772021-04-14 15:01:56 +0100309 // See HiddenAPIFlagFileProperties.Unsupported_packages
Paul Duffine3dc6602021-04-14 09:50:43 +0100310 {
311 propertyName: "unsupported_packages",
Paul Duffincc17bfe2021-04-19 13:21:20 +0100312 propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
Paul Duffine3dc6602021-04-14 09:50:43 +0100313 return properties.Unsupported_packages
314 },
315 commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
316 command.FlagWithInput("--unsupported ", path).Flag("--packages ")
317 },
318 },
Paul Duffin702210b2021-04-08 20:12:41 +0100319}
320
Paul Duffin46169772021-04-14 15:01:56 +0100321// hiddenAPIFlagFileInfo contains paths resolved from HiddenAPIFlagFileProperties
322type hiddenAPIFlagFileInfo struct {
Paul Duffine3dc6602021-04-14 09:50:43 +0100323 // categoryToPaths maps from the flag file category to the paths containing information for that
324 // category.
325 categoryToPaths map[*hiddenAPIFlagFileCategory]android.Paths
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100326}
Paul Duffin702210b2021-04-08 20:12:41 +0100327
Paul Duffin9b381ef2021-04-08 23:01:37 +0100328func (i *hiddenAPIFlagFileInfo) append(other hiddenAPIFlagFileInfo) {
329 for _, category := range hiddenAPIFlagFileCategories {
330 i.categoryToPaths[category] = append(i.categoryToPaths[category], other.categoryToPaths[category]...)
331 }
332}
333
334var hiddenAPIFlagFileInfoProvider = blueprint.NewProvider(hiddenAPIFlagFileInfo{})
335
Paul Duffin702210b2021-04-08 20:12:41 +0100336// ruleToGenerateHiddenApiFlags creates a rule to create the monolithic hidden API flags from the
337// flags from all the modules, the stub flags, augmented with some additional configuration files.
338//
339// baseFlagsPath is the path to the flags file containing all the information from the stubs plus
340// an entry for every single member in the dex implementation jars of the individual modules. Every
341// signature in any of the other files MUST be included in this file.
342//
343// moduleSpecificFlagsPaths are the paths to the flags files generated by each module using
344// information from the baseFlagsPath as well as from annotations within the source.
345//
346// augmentationInfo is a struct containing paths to files that augment the information provided by
347// the moduleSpecificFlagsPaths.
348// ruleToGenerateHiddenApiFlags creates a rule to create the monolithic hidden API flags from the
349// flags from all the modules, the stub flags, augmented with some additional configuration files.
350//
351// baseFlagsPath is the path to the flags file containing all the information from the stubs plus
352// an entry for every single member in the dex implementation jars of the individual modules. Every
353// signature in any of the other files MUST be included in this file.
354//
355// moduleSpecificFlagsPaths are the paths to the flags files generated by each module using
356// information from the baseFlagsPath as well as from annotations within the source.
357//
358// augmentationInfo is a struct containing paths to files that augment the information provided by
359// the moduleSpecificFlagsPaths.
Paul Duffin46169772021-04-14 15:01:56 +0100360func ruleToGenerateHiddenApiFlags(ctx android.BuilderContext, outputPath android.WritablePath, baseFlagsPath android.Path, moduleSpecificFlagsPaths android.Paths, augmentationInfo hiddenAPIFlagFileInfo) {
Paul Duffind3c15132021-04-21 22:12:35 +0100361 tempPath := tempPathForRestat(ctx, outputPath)
Paul Duffin702210b2021-04-08 20:12:41 +0100362 rule := android.NewRuleBuilder(pctx, ctx)
363 command := rule.Command().
364 BuiltTool("generate_hiddenapi_lists").
365 FlagWithInput("--csv ", baseFlagsPath).
366 Inputs(moduleSpecificFlagsPaths).
367 FlagWithOutput("--output ", tempPath)
368
Paul Duffine3dc6602021-04-14 09:50:43 +0100369 // Add the options for the different categories of flag files.
370 for _, category := range hiddenAPIFlagFileCategories {
371 paths := augmentationInfo.categoryToPaths[category]
372 for _, path := range paths {
373 category.commandMutator(command, path)
374 }
Paul Duffin702210b2021-04-08 20:12:41 +0100375 }
376
377 commitChangeForRestat(rule, tempPath, outputPath)
378
379 rule.Build("hiddenAPIFlagsFile", "hiddenapi flags")
380}