diff --git a/apex/platform_bootclasspath_test.go b/apex/platform_bootclasspath_test.go index eaee20dd0..3066c790e 100644 --- a/apex/platform_bootclasspath_test.go +++ b/apex/platform_bootclasspath_test.go @@ -159,11 +159,12 @@ func TestPlatformBootclasspath_Fragments(t *testing.T) { android.AssertPathsRelativeToTopEquals(t, message, expected, info.FlagsFilesByCategory[category]) } - android.AssertPathsRelativeToTopEquals(t, "stub flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/stub-flags.csv"}, info.StubFlagsPaths) android.AssertPathsRelativeToTopEquals(t, "annotation flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/annotation-flags.csv"}, info.AnnotationFlagsPaths) android.AssertPathsRelativeToTopEquals(t, "metadata flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/metadata.csv"}, info.MetadataPaths) android.AssertPathsRelativeToTopEquals(t, "index flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/index.csv"}, info.IndexPaths) - android.AssertPathsRelativeToTopEquals(t, "all flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/all-flags.csv"}, info.AllFlagsPaths) + + android.AssertArrayString(t, "stub flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/stub-flags.csv:out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/signature-patterns.csv"}, info.StubFlagSubsets.RelativeToTop()) + android.AssertArrayString(t, "all flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/all-flags.csv:out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/signature-patterns.csv"}, info.FlagSubsets.RelativeToTop()) } func TestPlatformBootclasspathDependencies(t *testing.T) { diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index 107d34a70..78b5f0ccd 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -579,6 +579,14 @@ func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android. common := ctx.Module().(commonBootclasspathFragment) output := common.produceHiddenAPIOutput(ctx, contents, input) + // If the source or prebuilts module does not provide a signature patterns file then generate one + // from the flags. + // 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) + } + // Initialize a HiddenAPIInfo structure. hiddenAPIInfo := HiddenAPIInfo{ // The monolithic hidden API processing needs access to the flag files that override the default @@ -744,9 +752,6 @@ type bootclasspathFragmentSdkMemberProperties struct { // Flag files by *hiddenAPIFlagFileCategory Flag_files_by_category FlagFilesByCategory - // The path to the generated stub-flags.csv file. - Stub_flags_path android.OptionalPath - // The path to the generated annotation-flags.csv file. Annotation_flags_path android.OptionalPath @@ -756,6 +761,9 @@ type bootclasspathFragmentSdkMemberProperties struct { // The path to the generated index.csv file. Index_path android.OptionalPath + // The path to the generated stub-flags.csv file. + Stub_flags_path android.OptionalPath + // The path to the generated all-flags.csv file. All_flags_path android.OptionalPath } @@ -772,10 +780,11 @@ func (b *bootclasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx andro b.Flag_files_by_category = hiddenAPIInfo.FlagFilesByCategory // Copy all the generated file paths. - b.Stub_flags_path = android.OptionalPathForPath(hiddenAPIInfo.StubFlagsPath) b.Annotation_flags_path = android.OptionalPathForPath(hiddenAPIInfo.AnnotationFlagsPath) b.Metadata_path = android.OptionalPathForPath(hiddenAPIInfo.MetadataPath) b.Index_path = android.OptionalPathForPath(hiddenAPIInfo.IndexPath) + + b.Stub_flags_path = android.OptionalPathForPath(hiddenAPIInfo.StubFlagsPath) b.All_flags_path = android.OptionalPathForPath(hiddenAPIInfo.AllFlagsPath) // Copy stub_libs properties. @@ -839,10 +848,10 @@ func (b *bootclasspathFragmentSdkMemberProperties) AddToPropertySet(ctx android. } // Copy all the generated files, if available. - copyOptionalPath(b.Stub_flags_path, "stub_flags") copyOptionalPath(b.Annotation_flags_path, "annotation_flags") copyOptionalPath(b.Metadata_path, "metadata") copyOptionalPath(b.Index_path, "index") + copyOptionalPath(b.Stub_flags_path, "stub_flags") copyOptionalPath(b.All_flags_path, "all_flags") } @@ -852,9 +861,6 @@ var _ android.SdkMemberType = (*bootclasspathFragmentMemberType)(nil) // specific properties. type prebuiltBootclasspathFragmentProperties struct { Hidden_api struct { - // The path to the stub-flags.csv file created by the bootclasspath_fragment. - Stub_flags *string `android:"path"` - // The path to the annotation-flags.csv file created by the bootclasspath_fragment. Annotation_flags *string `android:"path"` @@ -864,6 +870,9 @@ type prebuiltBootclasspathFragmentProperties struct { // The path to the index.csv file created by the bootclasspath_fragment. Index *string `android:"path"` + // The path to the stub-flags.csv file created by the bootclasspath_fragment. + Stub_flags *string `android:"path"` + // The path to the all-flags.csv file created by the bootclasspath_fragment. All_flags *string `android:"path"` } diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go index 86ab8253e..8a06a9969 100644 --- a/java/hiddenapi_modular.go +++ b/java/hiddenapi_modular.go @@ -297,7 +297,7 @@ func hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android. // // The rule is initialized but not built so that the caller can modify it and select an appropriate // name. -func buildRuleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, name, desc string, outputPath android.WritablePath, bootDexJars android.Paths, input HiddenAPIFlagInput, moduleStubFlagsPaths android.Paths) { +func buildRuleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, name, desc string, outputPath android.WritablePath, bootDexJars android.Paths, input HiddenAPIFlagInput, stubFlagSubsets SignatureCsvSubsets) { // Singleton rule which applies hiddenapi on all boot class path dex files. rule := android.NewRuleBuilder(pctx, ctx) @@ -317,7 +317,7 @@ func buildRuleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, name, // If no module stub flags paths are provided then this must be being called for a // bootclasspath_fragment and not the whole platform_bootclasspath. - if moduleStubFlagsPaths == nil { + if stubFlagSubsets == nil { // This is being run on a fragment of the bootclasspath. command.Flag("--fragment") } @@ -342,8 +342,8 @@ func buildRuleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, name, // If there are stub flag files that have been generated by fragments on which this depends then // use them to validate the stub flag file generated by the rules created by this method. - if len(moduleStubFlagsPaths) > 0 { - validFile := buildRuleValidateOverlappingCsvFiles(ctx, name, desc, outputPath, moduleStubFlagsPaths) + if len(stubFlagSubsets) > 0 { + validFile := buildRuleValidateOverlappingCsvFiles(ctx, name, desc, outputPath, stubFlagSubsets) // Add the file that indicates that the file generated by this is valid. // @@ -546,6 +546,20 @@ func (i *HiddenAPIInfo) mergeFromFragmentDeps(ctx android.ModuleContext, fragmen } } +// StubFlagSubset returns a SignatureCsvSubset that contains a path to a stub-flags.csv file and a +// path to a signature-patterns.csv file that defines a subset of the monolithic stub flags file, +// i.e. out/soong/hiddenapi/hiddenapi-stub-flags.txt, against which it will be compared. +func (i *HiddenAPIInfo) StubFlagSubset() SignatureCsvSubset { + return SignatureCsvSubset{i.StubFlagsPath, i.SignaturePatternsPath} +} + +// FlagSubset returns a SignatureCsvSubset that contains a path to an all-flags.csv file and a +// path to a signature-patterns.csv file that defines a subset of the monolithic flags file, i.e. +// out/soong/hiddenapi/hiddenapi-flags.csv, against which it will be compared. +func (i *HiddenAPIInfo) FlagSubset() SignatureCsvSubset { + return SignatureCsvSubset{i.AllFlagsPath, i.SignaturePatternsPath} +} + var HiddenAPIInfoProvider = blueprint.NewProvider(HiddenAPIInfo{}) // ModuleStubDexJars contains the stub dex jars provided by a single module. @@ -782,6 +796,10 @@ type HiddenAPIFlagOutput struct { // The path to the generated all-flags.csv file. AllFlagsPath android.Path + + // The path to the generated signature-patterns.txt file which defines the subset of the + // monolithic hidden API files provided in this. + SignaturePatternsPath android.Path } // bootDexJarByModule is a map from base module name (without prebuilt_ prefix) to the boot dex @@ -848,7 +866,7 @@ func pathForValidation(ctx android.PathContext, path android.WritablePath) andro // the annotationFlags. func buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc string, outputPath android.WritablePath, baseFlagsPath android.Path, annotationFlagPaths android.Paths, - flagFilesByCategory FlagFilesByCategory, allFlagsPaths android.Paths, generatedRemovedDexSignatures android.OptionalPath) { + flagFilesByCategory FlagFilesByCategory, flagSubsets SignatureCsvSubsets, generatedRemovedDexSignatures android.OptionalPath) { // Create the rule that will generate the flag files. tempPath := tempPathForRestat(ctx, outputPath) @@ -877,8 +895,8 @@ func buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc st // If there are flag files that have been generated by fragments on which this depends then use // them to validate the flag file generated by the rules created by this method. - if len(allFlagsPaths) > 0 { - validFile := buildRuleValidateOverlappingCsvFiles(ctx, name, desc, outputPath, allFlagsPaths) + if len(flagSubsets) > 0 { + validFile := buildRuleValidateOverlappingCsvFiles(ctx, name, desc, outputPath, flagSubsets) // Add the file that indicates that the file generated by this is valid. // @@ -890,20 +908,66 @@ func buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc st rule.Build(name, desc) } +// SignatureCsvSubset describes a subset of a monolithic flags file, i.e. either +// out/soong/hiddenapi/hiddenapi-stub-flags.txt or out/soong/hiddenapi/hiddenapi-flags.csv +type SignatureCsvSubset struct { + // The path to the CSV file containing hidden API flags. + // + // It has the dex member signature as the first column, with flags, one per column, in the + // subsequent columns. + CsvFile android.Path + + // The path to the CSV file containing the signature patterns. + // + // It is a single column CSV file with the column containing a signature pattern. + SignaturePatternsFile android.Path +} + +type SignatureCsvSubsets []SignatureCsvSubset + +func (s SignatureCsvSubsets) RelativeToTop() []string { + result := []string{} + for _, subset := range s { + result = append(result, fmt.Sprintf("%s:%s", subset.CsvFile.RelativeToTop(), subset.SignaturePatternsFile.RelativeToTop())) + } + return result +} + +// 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 { + 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) + rule.Command(). + BuiltTool("signature_patterns"). + FlagWithInput("--flags ", flagsPath). + FlagWithOutput("--output ", patternsFile) + rule.Build("hiddenAPISignaturePatterns", "hidden API signature patterns") + + return patternsFile +} + // buildRuleValidateOverlappingCsvFiles checks that the modular CSV files, i.e. the files generated // by the individual bootclasspath_fragment modules are subsets of the monolithic CSV file. -func buildRuleValidateOverlappingCsvFiles(ctx android.BuilderContext, name string, desc string, monolithicFilePath android.WritablePath, modularFilePaths android.Paths) android.WritablePath { +func buildRuleValidateOverlappingCsvFiles(ctx android.BuilderContext, name string, desc string, monolithicFilePath android.WritablePath, csvSubsets SignatureCsvSubsets) android.WritablePath { // The file which is used to record that the flags file is valid. validFile := pathForValidation(ctx, monolithicFilePath) // Create a rule to validate the output from the following rule. rule := android.NewRuleBuilder(pctx, ctx) - rule.Command(). + command := rule.Command(). BuiltTool("verify_overlaps"). - Input(monolithicFilePath). - Inputs(modularFilePaths). - // If validation passes then update the file that records that. - Text("&& touch").Output(validFile) + Input(monolithicFilePath) + + for _, subset := range csvSubsets { + command. + Textf("%s:%s", subset.CsvFile, subset.SignaturePatternsFile). + Implicit(subset.CsvFile).Implicit(subset.SignaturePatternsFile) + } + + // If validation passes then update the file that records that. + command.Text("&& touch").Output(validFile) rule.Build(name+"Validation", desc+" validation") return validFile diff --git a/java/hiddenapi_monolithic.go b/java/hiddenapi_monolithic.go index 404b4c133..5956e3c6c 100644 --- a/java/hiddenapi_monolithic.go +++ b/java/hiddenapi_monolithic.go @@ -29,9 +29,6 @@ type MonolithicHiddenAPIInfo struct { // that category. FlagsFilesByCategory FlagFilesByCategory - // The paths to the generated stub-flags.csv files. - StubFlagsPaths android.Paths - // The paths to the generated annotation-flags.csv files. AnnotationFlagsPaths android.Paths @@ -41,8 +38,13 @@ type MonolithicHiddenAPIInfo struct { // The paths to the generated index.csv files. IndexPaths android.Paths - // The paths to the generated all-flags.csv files. - AllFlagsPaths android.Paths + // The subsets of the monolithic hiddenapi-stubs-flags.txt file that are provided by each + // bootclasspath_fragment modules. + StubFlagSubsets SignatureCsvSubsets + + // The subsets of the monolithic hiddenapi-flags.csv file that are provided by each + // bootclasspath_fragment modules. + FlagSubsets SignatureCsvSubsets // The classes jars from the libraries on the platform bootclasspath. ClassesJars android.Paths @@ -80,11 +82,12 @@ func newMonolithicHiddenAPIInfo(ctx android.ModuleContext, flagFilesByCategory F // append appends all the files from the supplied info to the corresponding files in this struct. func (i *MonolithicHiddenAPIInfo) append(other *HiddenAPIInfo) { i.FlagsFilesByCategory.append(other.FlagFilesByCategory) - i.StubFlagsPaths = append(i.StubFlagsPaths, other.StubFlagsPath) i.AnnotationFlagsPaths = append(i.AnnotationFlagsPaths, other.AnnotationFlagsPath) i.MetadataPaths = append(i.MetadataPaths, other.MetadataPath) i.IndexPaths = append(i.IndexPaths, other.IndexPath) - i.AllFlagsPaths = append(i.AllFlagsPaths, other.AllFlagsPath) + + i.StubFlagSubsets = append(i.StubFlagSubsets, other.StubFlagSubset()) + i.FlagSubsets = append(i.FlagSubsets, other.FlagSubset()) } var MonolithicHiddenAPIInfoProvider = blueprint.NewProvider(MonolithicHiddenAPIInfo{}) diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go index 3ff4c773d..36baf7e78 100644 --- a/java/platform_bootclasspath.go +++ b/java/platform_bootclasspath.go @@ -316,7 +316,7 @@ func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android. // Generate the monolithic stub-flags.csv file. stubFlags := hiddenAPISingletonPaths(ctx).stubFlags - buildRuleToGenerateHiddenAPIStubFlagsFile(ctx, "platform-bootclasspath-monolithic-hiddenapi-stub-flags", "monolithic hidden API stub flags", stubFlags, bootDexJarByModule.bootDexJars(), input, monolithicInfo.StubFlagsPaths) + buildRuleToGenerateHiddenAPIStubFlagsFile(ctx, "platform-bootclasspath-monolithic-hiddenapi-stub-flags", "monolithic hidden API stub flags", stubFlags, bootDexJarByModule.bootDexJars(), input, monolithicInfo.StubFlagSubsets) // Generate the annotation-flags.csv file from all the module annotations. annotationFlags := android.PathForModuleOut(ctx, "hiddenapi-monolithic", "annotation-flags-from-classes.csv") @@ -329,7 +329,7 @@ func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android. allAnnotationFlagFiles := android.Paths{annotationFlags} allAnnotationFlagFiles = append(allAnnotationFlagFiles, monolithicInfo.AnnotationFlagsPaths...) allFlags := hiddenAPISingletonPaths(ctx).flags - buildRuleToGenerateHiddenApiFlags(ctx, "hiddenAPIFlagsFile", "monolithic hidden API flags", allFlags, stubFlags, allAnnotationFlagFiles, monolithicInfo.FlagsFilesByCategory, monolithicInfo.AllFlagsPaths, android.OptionalPath{}) + buildRuleToGenerateHiddenApiFlags(ctx, "hiddenAPIFlagsFile", "monolithic hidden API flags", allFlags, stubFlags, allAnnotationFlagFiles, monolithicInfo.FlagsFilesByCategory, monolithicInfo.FlagSubsets, android.OptionalPath{}) // Generate an intermediate monolithic hiddenapi-metadata.csv file directly from the annotations // in the source code. diff --git a/scripts/hiddenapi/Android.bp b/scripts/hiddenapi/Android.bp index c7298a083..7ffda62d1 100644 --- a/scripts/hiddenapi/Android.bp +++ b/scripts/hiddenapi/Android.bp @@ -104,3 +104,39 @@ python_test_host { unit_test: true, }, } + +python_binary_host { + name: "signature_patterns", + main: "signature_patterns.py", + srcs: ["signature_patterns.py"], + version: { + py2: { + enabled: false, + }, + py3: { + enabled: true, + embedded_launcher: true, + }, + }, +} + +python_test_host { + name: "signature_patterns_test", + main: "signature_patterns_test.py", + srcs: [ + "signature_patterns.py", + "signature_patterns_test.py", + ], + version: { + py2: { + enabled: false, + }, + py3: { + enabled: true, + embedded_launcher: true, + }, + }, + test_options: { + unit_test: true, + }, +} diff --git a/scripts/hiddenapi/signature_patterns.py b/scripts/hiddenapi/signature_patterns.py new file mode 100755 index 000000000..91328e60f --- /dev/null +++ b/scripts/hiddenapi/signature_patterns.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python +# +# Copyright (C) 2021 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Generate a set of signature patterns from the modular flags generated by a +bootclasspath_fragment that can be used to select a subset of monolithic flags +against which the modular flags can be compared. +""" + +import argparse +import csv + +def dict_reader(input): + return csv.DictReader(input, delimiter=',', quotechar='|', fieldnames=['signature']) + +def produce_patterns_from_file(file): + with open(file, 'r') as f: + return produce_patterns_from_stream(f) + +def produce_patterns_from_stream(stream): + patterns = [] + allFlagsReader = dict_reader(stream) + for row in allFlagsReader: + signature = row['signature'] + patterns.append(signature) + return patterns + +def main(args): + args_parser = argparse.ArgumentParser(description='Generate a set of signature patterns that select a subset of monolithic hidden API files.') + args_parser.add_argument('--flags', help='The stub flags file which contains an entry for every dex member') + args_parser.add_argument('--output', help='Generated signature prefixes') + args = args_parser.parse_args(args) + + # Read in all the patterns into a list. + patterns = produce_patterns_from_file(args.flags) + + # Write out all the patterns. + with open(args.output, 'w') as outputFile: + for pattern in patterns: + outputFile.write(pattern) + outputFile.write("\n") + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/scripts/hiddenapi/signature_patterns_test.py b/scripts/hiddenapi/signature_patterns_test.py new file mode 100755 index 000000000..83c9db29c --- /dev/null +++ b/scripts/hiddenapi/signature_patterns_test.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python +# +# Copyright (C) 2021 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Unit tests for signature_patterns.py.""" +import io +import unittest + +from signature_patterns import * + +class TestGeneratedPatterns(unittest.TestCase): + + def produce_patterns_from_string(self, csv): + with io.StringIO(csv) as f: + return produce_patterns_from_stream(f) + + def test_generate(self): + patterns = self.produce_patterns_from_string(''' +Ljava/lang/Object;->hashCode()I,public-api,system-api,test-api +Ljava/lang/Object;->toString()Ljava/lang/String;,blocked +''') + expected = [ + "Ljava/lang/Object;->hashCode()I", + "Ljava/lang/Object;->toString()Ljava/lang/String;", + ] + self.assertEqual(expected, patterns) + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/scripts/hiddenapi/verify_overlaps.py b/scripts/hiddenapi/verify_overlaps.py index fe4e359dd..8579321aa 100755 --- a/scripts/hiddenapi/verify_overlaps.py +++ b/scripts/hiddenapi/verify_overlaps.py @@ -24,16 +24,30 @@ from itertools import chain def dict_reader(input): return csv.DictReader(input, delimiter=',', quotechar='|', fieldnames=['signature']) -def extract_subset_from_monolithic_flags_as_dict(monolithicFlagsDict, signatures): +def extract_subset_from_monolithic_flags_as_dict_from_file(monolithicFlagsDict, patternsFile): """ Extract a subset of flags from the dict containing all the monolithic flags. :param monolithicFlagsDict: the dict containing all the monolithic flags. - :param signatures: a list of signature that define the subset. + :param patternsFile: a file containing a list of signature patterns that + define the subset. + :return: the dict from signature to row. + """ + with open(patternsFile, 'r') as stream: + return extract_subset_from_monolithic_flags_as_dict_from_stream(monolithicFlagsDict, stream) + +def extract_subset_from_monolithic_flags_as_dict_from_stream(monolithicFlagsDict, stream): + """ + Extract a subset of flags from the dict containing all the monolithic flags. + + :param monolithicFlagsDict: the dict containing all the monolithic flags. + :param stream: a stream containing a list of signature patterns that define + the subset. :return: the dict from signature to row. """ dict = {} - for signature in signatures: + for signature in stream: + signature = signature.rstrip() dict[signature] = monolithicFlagsDict.get(signature, {}) return dict @@ -102,9 +116,12 @@ def main(argv): # provided by the subset and the corresponding flags from the complete set of # flags and compare them. failed = False - for modularFlagsPath in args.modularFlags: + for modularPair in args.modularFlags: + parts = modularPair.split(":") + modularFlagsPath = parts[0] + modularPatternsPath = parts[1] modularFlagsDict = read_signature_csv_from_file_as_dict(modularFlagsPath) - monolithicFlagsSubsetDict = extract_subset_from_monolithic_flags_as_dict(monolithicFlagsDict, modularFlagsDict.keys()) + monolithicFlagsSubsetDict = extract_subset_from_monolithic_flags_as_dict_from_file(monolithicFlagsDict, modularPatternsPath) mismatchingSignatures = compare_signature_flags(monolithicFlagsSubsetDict, modularFlagsDict) if mismatchingSignatures: failed = True diff --git a/scripts/hiddenapi/verify_overlaps_test.py b/scripts/hiddenapi/verify_overlaps_test.py index fdb7fa2fd..b6d5fa38e 100755 --- a/scripts/hiddenapi/verify_overlaps_test.py +++ b/scripts/hiddenapi/verify_overlaps_test.py @@ -26,6 +26,10 @@ class TestDetectOverlaps(unittest.TestCase): with io.StringIO(csv) as f: return read_signature_csv_from_stream_as_dict(f) + def extract_subset_from_monolithic_flags_as_dict_from_string(self, monolithic, patterns): + with io.StringIO(patterns) as f: + return extract_subset_from_monolithic_flags_as_dict_from_stream(monolithic, f) + extractInput = ''' Ljava/lang/Object;->hashCode()I,public-api,system-api,test-api Ljava/lang/Object;->toString()Ljava/lang/String;,blocked @@ -36,7 +40,10 @@ Ljava/lang/Object;->toString()Ljava/lang/String;,blocked modular = self.read_signature_csv_from_string_as_dict(''' Ljava/lang/Object;->hashCode()I,public-api,system-api,test-api ''') - subset = extract_subset_from_monolithic_flags_as_dict(monolithic, modular.keys()) + + patterns = 'Ljava/lang/Object;->hashCode()I' + + subset = self.extract_subset_from_monolithic_flags_as_dict_from_string(monolithic, patterns) expected = { 'Ljava/lang/Object;->hashCode()I': { None: ['public-api', 'system-api', 'test-api'], diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go index c7ad79858..b60f81360 100644 --- a/sdk/bootclasspath_fragment_sdk_test.go +++ b/sdk/bootclasspath_fragment_sdk_test.go @@ -134,10 +134,10 @@ prebuilt_bootclasspath_fragment { image_name: "art", contents: ["mybootlib"], hidden_api: { - stub_flags: "hiddenapi/stub-flags.csv", annotation_flags: "hiddenapi/annotation-flags.csv", metadata: "hiddenapi/metadata.csv", index: "hiddenapi/index.csv", + stub_flags: "hiddenapi/stub-flags.csv", all_flags: "hiddenapi/all-flags.csv", }, } @@ -161,10 +161,10 @@ prebuilt_bootclasspath_fragment { image_name: "art", contents: ["mysdk_mybootlib@current"], hidden_api: { - stub_flags: "hiddenapi/stub-flags.csv", annotation_flags: "hiddenapi/annotation-flags.csv", metadata: "hiddenapi/metadata.csv", index: "hiddenapi/index.csv", + stub_flags: "hiddenapi/stub-flags.csv", all_flags: "hiddenapi/all-flags.csv", }, } @@ -185,10 +185,10 @@ sdk_snapshot { } `), checkAllCopyRules(` -.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/stub-flags.csv -> hiddenapi/stub-flags.csv .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/annotation-flags.csv -> hiddenapi/annotation-flags.csv .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/metadata.csv -> hiddenapi/metadata.csv .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/index.csv -> hiddenapi/index.csv +.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/stub-flags.csv -> hiddenapi/stub-flags.csv .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/all-flags.csv -> hiddenapi/all-flags.csv .intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar `), @@ -332,10 +332,10 @@ prebuilt_bootclasspath_fragment { stub_libs: ["mycoreplatform"], }, hidden_api: { - stub_flags: "hiddenapi/stub-flags.csv", annotation_flags: "hiddenapi/annotation-flags.csv", metadata: "hiddenapi/metadata.csv", index: "hiddenapi/index.csv", + stub_flags: "hiddenapi/stub-flags.csv", all_flags: "hiddenapi/all-flags.csv", }, } @@ -416,10 +416,10 @@ prebuilt_bootclasspath_fragment { stub_libs: ["mysdk_mycoreplatform@current"], }, hidden_api: { - stub_flags: "hiddenapi/stub-flags.csv", annotation_flags: "hiddenapi/annotation-flags.csv", metadata: "hiddenapi/metadata.csv", index: "hiddenapi/index.csv", + stub_flags: "hiddenapi/stub-flags.csv", all_flags: "hiddenapi/all-flags.csv", }, } @@ -494,10 +494,10 @@ sdk_snapshot { } `), checkAllCopyRules(` -.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/stub-flags.csv -> hiddenapi/stub-flags.csv .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/annotation-flags.csv -> hiddenapi/annotation-flags.csv .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/metadata.csv -> hiddenapi/metadata.csv .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/index.csv -> hiddenapi/index.csv +.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/stub-flags.csv -> hiddenapi/stub-flags.csv .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/all-flags.csv -> hiddenapi/all-flags.csv .intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar .intermediates/myothersdklibrary.stubs/android_common/javac/myothersdklibrary.stubs.jar -> sdk_library/public/myothersdklibrary-stubs.jar @@ -636,10 +636,10 @@ prebuilt_bootclasspath_fragment { }, ], hidden_api: { - stub_flags: "hiddenapi/stub-flags.csv", annotation_flags: "hiddenapi/annotation-flags.csv", metadata: "hiddenapi/metadata.csv", index: "hiddenapi/index.csv", + stub_flags: "hiddenapi/stub-flags.csv", all_flags: "hiddenapi/all-flags.csv", }, } @@ -838,10 +838,10 @@ prebuilt_bootclasspath_fragment { max_target_o_low_priority: ["hiddenapi/my-max-target-o-low-priority.txt"], blocked: ["hiddenapi/my-blocked.txt"], unsupported_packages: ["hiddenapi/my-unsupported-packages.txt"], - stub_flags: "hiddenapi/stub-flags.csv", annotation_flags: "hiddenapi/annotation-flags.csv", metadata: "hiddenapi/metadata.csv", index: "hiddenapi/index.csv", + stub_flags: "hiddenapi/stub-flags.csv", all_flags: "hiddenapi/all-flags.csv", }, } @@ -881,10 +881,10 @@ my-max-target-p.txt -> hiddenapi/my-max-target-p.txt my-max-target-o-low-priority.txt -> hiddenapi/my-max-target-o-low-priority.txt my-blocked.txt -> hiddenapi/my-blocked.txt my-unsupported-packages.txt -> hiddenapi/my-unsupported-packages.txt -.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/stub-flags.csv -> hiddenapi/stub-flags.csv .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/annotation-flags.csv -> hiddenapi/annotation-flags.csv .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/metadata.csv -> hiddenapi/metadata.csv .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/index.csv -> hiddenapi/index.csv +.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/stub-flags.csv -> hiddenapi/stub-flags.csv .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/all-flags.csv -> hiddenapi/all-flags.csv .intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar .intermediates/mysdklibrary.stubs/android_common/javac/mysdklibrary.stubs.jar -> sdk_library/public/mysdklibrary-stubs.jar