aboutsummaryrefslogtreecommitdiff
path: root/systemfeatures/system_features.go
diff options
context:
space:
mode:
Diffstat (limited to 'systemfeatures/system_features.go')
-rw-r--r--systemfeatures/system_features.go57
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)
+}