diff options
Diffstat (limited to 'systemfeatures/system_features.go')
| -rw-r--r-- | systemfeatures/system_features.go | 57 |
1 files changed, 53 insertions, 4 deletions
diff --git a/systemfeatures/system_features.go b/systemfeatures/system_features.go index b8dacfb1f..51f69bbe4 100644 --- a/systemfeatures/system_features.go +++ b/systemfeatures/system_features.go @@ -15,6 +15,7 @@ package systemfeatures import ( "fmt" + "path/filepath" "sort" "strings" @@ -44,7 +45,6 @@ type javaSystemFeaturesSrcs struct { // Whether to generate only a simple metadata class with details about the full API surface. // This is useful for tools that rely on the mapping from feature names to their generated // method names, but don't want the fully generated API class (e.g., for linting). - Metadata_only *bool } outputFiles android.WritablePaths @@ -74,13 +74,20 @@ func (m *javaSystemFeaturesSrcs) GenerateAndroidBuildActions(ctx android.ModuleC rule := android.NewRuleBuilder(pctx, ctx) rule.Command().Text("rm -rf").Text(outputDir.String()) rule.Command().Text("mkdir -p").Text(outputDir.String()) - rule.Command(). + ruleCmd := rule.Command(). BuiltTool("systemfeatures-gen-tool"). Flag(m.properties.Full_class_name). FlagForEachArg("--feature=", features). FlagWithArg("--readonly=", fmt.Sprint(ctx.Config().ReleaseUseSystemFeatureBuildFlags())). - FlagWithArg("--metadata-only=", fmt.Sprint(proptools.Bool(m.properties.Metadata_only))). - FlagWithOutput(" > ", outputFile) + FlagWithArg("--metadata-only=", fmt.Sprint(proptools.Bool(m.properties.Metadata_only))) + + if ctx.Config().ReleaseUseSystemFeatureXmlForUnavailableFeatures() { + if featureXmlFiles := uniquePossibleFeatureXmlPaths(ctx); len(featureXmlFiles) > 0 { + ruleCmd.FlagWithInputList("--unavailable-feature-xml-files=", featureXmlFiles, ",") + } + } + + ruleCmd.FlagWithOutput(" > ", outputFile) rule.Build(ctx.ModuleName(), "Generating systemfeatures srcs filegroup") m.outputFiles = append(m.outputFiles, outputFile) @@ -109,3 +116,45 @@ func JavaSystemFeaturesSrcsFactory() android.Module { android.InitAndroidModule(module) return module } + +// Generates a list of unique, existent src paths for potential feature XML +// files, as contained in the configured PRODUCT_COPY_FILES listing. +func uniquePossibleFeatureXmlPaths(ctx android.ModuleContext) android.Paths { + dstPathSeen := make(map[string]bool) + var possibleSrcPaths []android.Path + for _, copyFilePair := range ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.ProductCopyFiles { + srcDstList := strings.Split(copyFilePair, ":") + // The length may be >2 (e.g., "$src:$dst:$owner"), but we only care + // that it has at least "$src:$dst". + if len(srcDstList) < 2 { + ctx.ModuleErrorf("PRODUCT_COPY_FILES must follow the format \"src:dest\", got: %s", copyFilePair) + continue + } + src, dst := srcDstList[0], srcDstList[1] + + // We're only interested in `.xml` files (case-insensitive). + if !strings.EqualFold(filepath.Ext(dst), ".xml") { + continue + } + + // We only care about files directly in `*/etc/permissions/` or + // `*/etc/sysconfig` dirs, not any nested subdirs. + normalizedDstDir := filepath.ToSlash(filepath.Dir(filepath.Clean(dst))) + if !strings.HasSuffix(normalizedDstDir, "/etc/permissions") && + !strings.HasSuffix(normalizedDstDir, "/etc/sysconfig") { + continue + } + + // The first `dst` entry in the PRODUCT_COPY_FILES `src:dst` pairings + // always takes precedence over latter entries. + if _, ok := dstPathSeen[dst]; !ok { + relSrc := android.ToRelativeSourcePath(ctx, src) + if optionalPath := android.ExistentPathForSource(ctx, relSrc); optionalPath.Valid() { + dstPathSeen[dst] = true + possibleSrcPaths = append(possibleSrcPaths, optionalPath.Path()) + } + } + } + // A sorted, unique list ensures stability of ninja build command outputs. + return android.SortedUniquePaths(possibleSrcPaths) +} |
