blob: 793d63ae760c5d4064cee2df60d21159122d8633 [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
130 dexJar := hiddenAPIRetrieveDexJarBuildPath(ctx, module)
131 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.
141func hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android.Module) android.Path {
142 if j, ok := module.(UsesLibraryDependency); ok {
143 dexJar := j.DexJarBuildPath()
144 if dexJar != nil {
145 return dexJar
146 }
147 ctx.ModuleErrorf("dependency %s does not provide a dex jar, consider setting compile_dex: true", module)
148 } else {
149 ctx.ModuleErrorf("dependency %s of module type %s does not support providing a dex jar", module, ctx.OtherModuleType(module))
150 }
151 return nil
152}
153
154var sdkKindToHiddenapiListOption = map[android.SdkKind]string{
155 android.SdkPublic: "public-stub-classpath",
156 android.SdkSystem: "system-stub-classpath",
157 android.SdkTest: "test-stub-classpath",
158 android.SdkCorePlatform: "core-platform-stub-classpath",
159}
160
161// ruleToGenerateHiddenAPIStubFlagsFile creates a rule to create a hidden API stub flags file.
162//
163// The rule is initialized but not built so that the caller can modify it and select an appropriate
164// name.
165func ruleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, outputPath android.OutputPath, bootDexJars android.Paths, sdkKindToPathList map[android.SdkKind]android.Paths) *android.RuleBuilder {
166 // Singleton rule which applies hiddenapi on all boot class path dex files.
167 rule := android.NewRuleBuilder(pctx, ctx)
168
169 tempPath := tempPathForRestat(ctx, outputPath)
170
171 command := rule.Command().
172 Tool(ctx.Config().HostToolPath(ctx, "hiddenapi")).
173 Text("list").
174 FlagForEachInput("--boot-dex=", bootDexJars)
175
176 // Iterate over the sdk kinds in a fixed order.
177 for _, sdkKind := range hiddenAPIRelevantSdkKinds {
178 paths := sdkKindToPathList[sdkKind]
179 if len(paths) > 0 {
180 option := sdkKindToHiddenapiListOption[sdkKind]
181 command.FlagWithInputList("--"+option+"=", paths, ":")
182 }
183 }
184
185 // Add the output path.
186 command.FlagWithOutput("--out-api-flags=", tempPath)
187
188 commitChangeForRestat(rule, tempPath, outputPath)
189 return rule
190}
191
Paul Duffin46169772021-04-14 15:01:56 +0100192// HiddenAPIFlagFileProperties contains paths to the flag files that can be used to augment the
193// information obtained from annotations within the source code in order to create the complete set
194// of flags that should be applied to the dex implementation jars on the bootclasspath.
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100195//
196// Each property contains a list of paths. With the exception of the Unsupported_packages the paths
197// of each property reference a plain text file that contains a java signature per line. The flags
198// for each of those signatures will be updated in a property specific way.
199//
200// The Unsupported_packages property contains a list of paths, each of which is a plain text file
201// with one Java package per line. All members of all classes within that package (but not nested
202// packages) will be updated in a property specific way.
Paul Duffin46169772021-04-14 15:01:56 +0100203type HiddenAPIFlagFileProperties struct {
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100204 // Marks each signature in the referenced files as being unsupported.
Paul Duffin702210b2021-04-08 20:12:41 +0100205 Unsupported []string `android:"path"`
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100206
207 // Marks each signature in the referenced files as being unsupported because it has been removed.
208 // Any conflicts with other flags are ignored.
Paul Duffin702210b2021-04-08 20:12:41 +0100209 Removed []string `android:"path"`
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100210
211 // Marks each signature in the referenced files as being supported only for targetSdkVersion <= R
212 // and low priority.
Paul Duffin702210b2021-04-08 20:12:41 +0100213 Max_target_r_low_priority []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 <= Q.
Paul Duffin702210b2021-04-08 20:12:41 +0100216 Max_target_q []string `android:"path"`
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100217
218 // Marks each signature in the referenced files as being supported only for targetSdkVersion <= P.
Paul Duffin702210b2021-04-08 20:12:41 +0100219 Max_target_p []string `android:"path"`
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100220
221 // Marks each signature in the referenced files as being supported only for targetSdkVersion <= O
222 // and low priority. Any conflicts with other flags are ignored.
Paul Duffin702210b2021-04-08 20:12:41 +0100223 Max_target_o_low_priority []string `android:"path"`
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100224
225 // Marks each signature in the referenced files as being blocked.
Paul Duffin702210b2021-04-08 20:12:41 +0100226 Blocked []string `android:"path"`
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100227
228 // Marks each signature in every package in the referenced files as being unsupported.
Paul Duffin702210b2021-04-08 20:12:41 +0100229 Unsupported_packages []string `android:"path"`
230}
231
Paul Duffin46169772021-04-14 15:01:56 +0100232func (p *HiddenAPIFlagFileProperties) hiddenAPIFlagFileInfo(ctx android.ModuleContext) hiddenAPIFlagFileInfo {
233 info := hiddenAPIFlagFileInfo{categoryToPaths: map[*hiddenAPIFlagFileCategory]android.Paths{}}
Paul Duffine3dc6602021-04-14 09:50:43 +0100234 for _, category := range hiddenAPIFlagFileCategories {
Paul Duffincc17bfe2021-04-19 13:21:20 +0100235 paths := android.PathsForModuleSrc(ctx, category.propertyValueReader(p))
Paul Duffine3dc6602021-04-14 09:50:43 +0100236 info.categoryToPaths[category] = paths
Paul Duffin702210b2021-04-08 20:12:41 +0100237 }
Paul Duffine3dc6602021-04-14 09:50:43 +0100238 return info
239}
240
241type hiddenAPIFlagFileCategory struct {
242 // propertyName is the name of the property for this category.
243 propertyName string
244
Paul Duffincc17bfe2021-04-19 13:21:20 +0100245 // propertyValueReader retrieves the value of the property for this category from the set of
Paul Duffine3dc6602021-04-14 09:50:43 +0100246 // properties.
Paul Duffincc17bfe2021-04-19 13:21:20 +0100247 propertyValueReader func(properties *HiddenAPIFlagFileProperties) []string
Paul Duffine3dc6602021-04-14 09:50:43 +0100248
249 // commandMutator adds the appropriate command line options for this category to the supplied
250 // command
251 commandMutator func(command *android.RuleBuilderCommand, path android.Path)
252}
253
254var hiddenAPIFlagFileCategories = []*hiddenAPIFlagFileCategory{
Paul Duffin46169772021-04-14 15:01:56 +0100255 // See HiddenAPIFlagFileProperties.Unsupported
Paul Duffine3dc6602021-04-14 09:50:43 +0100256 {
257 propertyName: "unsupported",
Paul Duffincc17bfe2021-04-19 13:21:20 +0100258 propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
Paul Duffine3dc6602021-04-14 09:50:43 +0100259 return properties.Unsupported
260 },
261 commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
262 command.FlagWithInput("--unsupported ", path)
263 },
264 },
Paul Duffin46169772021-04-14 15:01:56 +0100265 // See HiddenAPIFlagFileProperties.Removed
Paul Duffine3dc6602021-04-14 09:50:43 +0100266 {
267 propertyName: "removed",
Paul Duffincc17bfe2021-04-19 13:21:20 +0100268 propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
Paul Duffine3dc6602021-04-14 09:50:43 +0100269 return properties.Removed
270 },
271 commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
272 command.FlagWithInput("--unsupported ", path).Flag("--ignore-conflicts ").FlagWithArg("--tag ", "removed")
273 },
274 },
Paul Duffin46169772021-04-14 15:01:56 +0100275 // See HiddenAPIFlagFileProperties.Max_target_r_low_priority
Paul Duffine3dc6602021-04-14 09:50:43 +0100276 {
277 propertyName: "max_target_r_low_priority",
Paul Duffincc17bfe2021-04-19 13:21:20 +0100278 propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
Paul Duffine3dc6602021-04-14 09:50:43 +0100279 return properties.Max_target_r_low_priority
280 },
281 commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
282 command.FlagWithInput("--max-target-r ", path).FlagWithArg("--tag ", "lo-prio")
283 },
284 },
Paul Duffin46169772021-04-14 15:01:56 +0100285 // See HiddenAPIFlagFileProperties.Max_target_q
Paul Duffine3dc6602021-04-14 09:50:43 +0100286 {
287 propertyName: "max_target_q",
Paul Duffincc17bfe2021-04-19 13:21:20 +0100288 propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
Paul Duffine3dc6602021-04-14 09:50:43 +0100289 return properties.Max_target_q
290 },
291 commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
292 command.FlagWithInput("--max-target-q ", path)
293 },
294 },
Paul Duffin46169772021-04-14 15:01:56 +0100295 // See HiddenAPIFlagFileProperties.Max_target_p
Paul Duffine3dc6602021-04-14 09:50:43 +0100296 {
297 propertyName: "max_target_p",
Paul Duffincc17bfe2021-04-19 13:21:20 +0100298 propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
Paul Duffine3dc6602021-04-14 09:50:43 +0100299 return properties.Max_target_p
300 },
301 commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
302 command.FlagWithInput("--max-target-p ", path)
303 },
304 },
Paul Duffin46169772021-04-14 15:01:56 +0100305 // See HiddenAPIFlagFileProperties.Max_target_o_low_priority
Paul Duffine3dc6602021-04-14 09:50:43 +0100306 {
307 propertyName: "max_target_o_low_priority",
Paul Duffincc17bfe2021-04-19 13:21:20 +0100308 propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
Paul Duffine3dc6602021-04-14 09:50:43 +0100309 return properties.Max_target_o_low_priority
310 },
311 commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
312 command.FlagWithInput("--max-target-o ", path).Flag("--ignore-conflicts ").FlagWithArg("--tag ", "lo-prio")
313 },
314 },
Paul Duffin46169772021-04-14 15:01:56 +0100315 // See HiddenAPIFlagFileProperties.Blocked
Paul Duffine3dc6602021-04-14 09:50:43 +0100316 {
317 propertyName: "blocked",
Paul Duffincc17bfe2021-04-19 13:21:20 +0100318 propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
Paul Duffine3dc6602021-04-14 09:50:43 +0100319 return properties.Blocked
320 },
321 commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
322 command.FlagWithInput("--blocked ", path)
323 },
324 },
Paul Duffin46169772021-04-14 15:01:56 +0100325 // See HiddenAPIFlagFileProperties.Unsupported_packages
Paul Duffine3dc6602021-04-14 09:50:43 +0100326 {
327 propertyName: "unsupported_packages",
Paul Duffincc17bfe2021-04-19 13:21:20 +0100328 propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string {
Paul Duffine3dc6602021-04-14 09:50:43 +0100329 return properties.Unsupported_packages
330 },
331 commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
332 command.FlagWithInput("--unsupported ", path).Flag("--packages ")
333 },
334 },
Paul Duffin702210b2021-04-08 20:12:41 +0100335}
336
Paul Duffin46169772021-04-14 15:01:56 +0100337// hiddenAPIFlagFileInfo contains paths resolved from HiddenAPIFlagFileProperties
338type hiddenAPIFlagFileInfo struct {
Paul Duffine3dc6602021-04-14 09:50:43 +0100339 // categoryToPaths maps from the flag file category to the paths containing information for that
340 // category.
341 categoryToPaths map[*hiddenAPIFlagFileCategory]android.Paths
Paul Duffinc6bb7cf2021-04-08 17:49:27 +0100342}
Paul Duffin702210b2021-04-08 20:12:41 +0100343
Paul Duffin9b381ef2021-04-08 23:01:37 +0100344func (i *hiddenAPIFlagFileInfo) append(other hiddenAPIFlagFileInfo) {
345 for _, category := range hiddenAPIFlagFileCategories {
346 i.categoryToPaths[category] = append(i.categoryToPaths[category], other.categoryToPaths[category]...)
347 }
348}
349
350var hiddenAPIFlagFileInfoProvider = blueprint.NewProvider(hiddenAPIFlagFileInfo{})
351
Paul Duffin702210b2021-04-08 20:12:41 +0100352// ruleToGenerateHiddenApiFlags creates a rule to create the monolithic hidden API flags from the
353// flags from all the modules, the stub flags, augmented with some additional configuration files.
354//
355// baseFlagsPath is the path to the flags file containing all the information from the stubs plus
356// an entry for every single member in the dex implementation jars of the individual modules. Every
357// signature in any of the other files MUST be included in this file.
358//
359// moduleSpecificFlagsPaths are the paths to the flags files generated by each module using
360// information from the baseFlagsPath as well as from annotations within the source.
361//
362// augmentationInfo is a struct containing paths to files that augment the information provided by
363// the moduleSpecificFlagsPaths.
364// ruleToGenerateHiddenApiFlags creates a rule to create the monolithic hidden API flags from the
365// flags from all the modules, the stub flags, augmented with some additional configuration files.
366//
367// baseFlagsPath is the path to the flags file containing all the information from the stubs plus
368// an entry for every single member in the dex implementation jars of the individual modules. Every
369// signature in any of the other files MUST be included in this file.
370//
371// moduleSpecificFlagsPaths are the paths to the flags files generated by each module using
372// information from the baseFlagsPath as well as from annotations within the source.
373//
374// augmentationInfo is a struct containing paths to files that augment the information provided by
375// the moduleSpecificFlagsPaths.
Paul Duffin46169772021-04-14 15:01:56 +0100376func ruleToGenerateHiddenApiFlags(ctx android.BuilderContext, outputPath android.WritablePath, baseFlagsPath android.Path, moduleSpecificFlagsPaths android.Paths, augmentationInfo hiddenAPIFlagFileInfo) {
Paul Duffind3c15132021-04-21 22:12:35 +0100377 tempPath := tempPathForRestat(ctx, outputPath)
Paul Duffin702210b2021-04-08 20:12:41 +0100378 rule := android.NewRuleBuilder(pctx, ctx)
379 command := rule.Command().
380 BuiltTool("generate_hiddenapi_lists").
381 FlagWithInput("--csv ", baseFlagsPath).
382 Inputs(moduleSpecificFlagsPaths).
383 FlagWithOutput("--output ", tempPath)
384
Paul Duffine3dc6602021-04-14 09:50:43 +0100385 // Add the options for the different categories of flag files.
386 for _, category := range hiddenAPIFlagFileCategories {
387 paths := augmentationInfo.categoryToPaths[category]
388 for _, path := range paths {
389 category.commandMutator(command, path)
390 }
Paul Duffin702210b2021-04-08 20:12:41 +0100391 }
392
393 commitChangeForRestat(rule, tempPath, outputPath)
394
395 rule.Build("hiddenAPIFlagsFile", "hiddenapi flags")
396}