diff options
Diffstat (limited to 'java')
-rw-r--r-- | java/bootclasspath_fragment.go | 89 | ||||
-rw-r--r-- | java/hiddenapi_modular.go | 11 |
2 files changed, 96 insertions, 4 deletions
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index ced004850..8f18790ea 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -139,6 +139,74 @@ type bootclasspathFragmentProperties struct { BootclasspathFragmentsDepsProperties } +type SourceOnlyBootclasspathProperties struct { + Hidden_api struct { + // Contains prefixes of a package hierarchy that is provided solely by this + // bootclasspath_fragment. + // + // This affects the signature patterns file that is used to select the subset of monolithic + // hidden API flags. See split_packages property for more details. + Package_prefixes []string + + // The list of split packages provided by this bootclasspath_fragment. + // + // A split package is one that contains classes which are provided by multiple + // bootclasspath_fragment modules. + // + // This defaults to "*" - which treats all packages as being split. A module that has no split + // packages must specify an empty list. + // + // This affects the signature patterns file that is generated by a bootclasspath_fragment and + // used to select the subset of monolithic hidden API flags against which the flags generated + // by the bootclasspath_fragment are compared. + // + // The signature patterns file selects the subset of monolithic hidden API flags using a number + // of patterns, i.e.: + // * The qualified name (including package) of an outermost class, e.g. java/lang/Character. + // This selects all the flags for all the members of this class and any nested classes. + // * A package wildcard, e.g. java/lang/*. This selects all the flags for all the members of all + // the classes in this package (but not in sub-packages). + // * A recursive package wildcard, e.g. java/**. This selects all the flags for all the members + // of all the classes in this package and sub-packages. + // + // The signature patterns file is constructed as follows: + // * All the signatures are retrieved from the all-flags.csv file. + // * The member and inner class names are removed. + // * If a class is in a split package then that is kept, otherwise the class part is removed + // and replaced with a wildcard, i.e. *. + // * If a package matches a package prefix then the package is removed. + // * All the package prefixes are added with a recursive wildcard appended to each, i.e. **. + // * The resulting patterns are sorted. + // + // So, by default (i.e. without specifying any package_prefixes or split_packages) the signature + // patterns is a list of class names, because there are no package packages and all packages are + // assumed to be split. + // + // If any split packages are specified then only those packages are treated as split and all + // other packages are treated as belonging solely to the bootclasspath_fragment and so they use + // wildcard package patterns. + // + // So, if an empty list of split packages is specified then the signature patterns file just + // includes a wildcard package pattern for every package provided by the bootclasspath_fragment. + // + // If split_packages are specified and a package that is split is not listed then it could lead + // to build failures as it will select monolithic flags that are generated by another + // bootclasspath_fragment to compare against the flags provided by this fragment. The latter + // will obviously not contain those flags and that can cause the comparison and build to fail. + // + // If any package prefixes are specified then any matching packages are removed from the + // signature patterns and replaced with a single recursive package pattern. + // + // It is not strictly necessary to specify either package_prefixes or split_packages as the + // defaults will produce a valid set of signature patterns. However, those patterns may include + // implementation details, e.g. names of implementation classes or packages, which will be + // exported to the sdk snapshot in the signature patterns file. That is something that should be + // avoided where possible. Specifying package_prefixes and split_packages allows those + // implementation details to be excluded from the snapshot. + Split_packages []string + } +} + type BootclasspathFragmentModule struct { android.ModuleBase android.ApexModuleBase @@ -147,6 +215,8 @@ type BootclasspathFragmentModule struct { properties bootclasspathFragmentProperties + sourceOnlyProperties SourceOnlyBootclasspathProperties + // Collect the module directory for IDE info in java/jdeps.go. modulePaths []string } @@ -180,7 +250,7 @@ type bootImageFilesByArch map[android.ArchType]android.Paths func bootclasspathFragmentFactory() android.Module { m := &BootclasspathFragmentModule{} - m.AddProperties(&m.properties) + m.AddProperties(&m.properties, &m.sourceOnlyProperties) android.InitApexModule(m) android.InitSdkAwareModule(m) initClasspathFragment(m, BOOTCLASSPATH) @@ -590,7 +660,7 @@ func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android. // TODO(b/192868581): Remove once the source and prebuilts provide a signature patterns file of // their own. if output.SignaturePatternsPath == nil { - output.SignaturePatternsPath = buildRuleSignaturePatternsFile(ctx, output.AllFlagsPath) + output.SignaturePatternsPath = buildRuleSignaturePatternsFile(ctx, output.AllFlagsPath, []string{"*"}, nil) } // Initialize a HiddenAPIInfo structure. @@ -659,7 +729,20 @@ func (b *BootclasspathFragmentModule) createHiddenAPIFlagInput(ctx android.Modul func (b *BootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput { // Generate the rules to create the hidden API flags and update the supplied hiddenAPIInfo with the // paths to the created files. - return hiddenAPIRulesForBootclasspathFragment(ctx, contents, input) + output := hiddenAPIRulesForBootclasspathFragment(ctx, contents, input) + + // If the module specifies split_packages or package_prefixes then use those to generate the + // signature patterns. + splitPackages := b.sourceOnlyProperties.Hidden_api.Split_packages + packagePrefixes := b.sourceOnlyProperties.Hidden_api.Package_prefixes + if splitPackages != nil || packagePrefixes != nil { + if splitPackages == nil { + splitPackages = []string{"*"} + } + output.SignaturePatternsPath = buildRuleSignaturePatternsFile(ctx, output.AllFlagsPath, splitPackages, packagePrefixes) + } + + return output } // produceBootImageFiles builds the boot image files from the source if it is required. diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go index f1e30f320..0cc960d5c 100644 --- a/java/hiddenapi_modular.go +++ b/java/hiddenapi_modular.go @@ -943,13 +943,22 @@ func (s SignatureCsvSubsets) RelativeToTop() []string { // buildRuleSignaturePatternsFile creates a rule to generate a file containing the set of signature // patterns that will select a subset of the monolithic flags. -func buildRuleSignaturePatternsFile(ctx android.ModuleContext, flagsPath android.Path) android.Path { +func buildRuleSignaturePatternsFile(ctx android.ModuleContext, flagsPath android.Path, splitPackages []string, packagePrefixes []string) android.Path { patternsFile := android.PathForModuleOut(ctx, "modular-hiddenapi", "signature-patterns.csv") // Create a rule to validate the output from the following rule. rule := android.NewRuleBuilder(pctx, ctx) + + // Quote any * in the packages to avoid them being expanded by the shell. + quotedSplitPackages := []string{} + for _, pkg := range splitPackages { + quotedSplitPackages = append(quotedSplitPackages, strings.ReplaceAll(pkg, "*", "\\*")) + } + rule.Command(). BuiltTool("signature_patterns"). FlagWithInput("--flags ", flagsPath). + FlagForEachArg("--split-package ", quotedSplitPackages). + FlagForEachArg("--package-prefix ", packagePrefixes). FlagWithOutput("--output ", patternsFile) rule.Build("hiddenAPISignaturePatterns", "hidden API signature patterns") |