diff options
author | David Brazdil <dbrazdil@google.com> | 2018-09-11 11:09:01 +0100 |
---|---|---|
committer | David Brazdil <dbrazdil@google.com> | 2018-09-11 11:43:07 +0100 |
commit | 4a55eebf26a5366de302578f76947e7c05305a22 (patch) | |
tree | 2f1811bb36030f2252a422b3bca1b3a7f6762f0a /tools/hiddenapi/generate_hiddenapi_lists.py | |
parent | 60ff003a9d988ba7459906b131fa5718b80dc093 (diff) |
Revert "Check in P dark greylist, use it for hidden API list generation"
This reverts commit 3cc74c71ef907a76547424aea6597f7b2907e9fb.
We saw app crashes due stricter classification of non-SDK APIs.
Bug: 115284625
Bug: 113881436
Test: phone boots
Change-Id: I689d0fbf66fabeffa5032e13f2f1f314c50b6cc5
Diffstat (limited to 'tools/hiddenapi/generate_hiddenapi_lists.py')
-rwxr-xr-x | tools/hiddenapi/generate_hiddenapi_lists.py | 88 |
1 files changed, 64 insertions, 24 deletions
diff --git a/tools/hiddenapi/generate_hiddenapi_lists.py b/tools/hiddenapi/generate_hiddenapi_lists.py index c5fcb63624c5..6c46e67be63d 100755 --- a/tools/hiddenapi/generate_hiddenapi_lists.py +++ b/tools/hiddenapi/generate_hiddenapi_lists.py @@ -45,12 +45,9 @@ def get_args(): '--input-whitelists', nargs='*', help='Lists of members to force on whitelist') parser.add_argument( - '--input-light-greylists', nargs='*', + '--input-greylists', nargs='*', help='Lists of members to force on light greylist') parser.add_argument( - '--input-dark-greylists', nargs='*', - help='Lists of members to force on dark greylist') - parser.add_argument( '--input-blacklists', nargs='*', help='Lists of members to force on blacklist') parser.add_argument('--output-whitelist', required=True) @@ -83,31 +80,61 @@ def write_lines(filename, lines): with open(filename, 'w') as f: f.writelines(lines) -def move_between_sets(subset, src, dst, source = "<unknown>", ignoreMissing = False): +def move_between_sets(subset, src, dst, source = "<unknown>"): """Removes a subset of elements from one set and add it to another. Args: subset (set): The subset of `src` to be moved from `src` to `dst`. src (set): Source set. Must be a superset of `subset`. dst (set): Destination set. Must be disjoint with `subset`. - source (string): Name of the data source. - ignoreMissing (bool): If true, do not check whether `src` is a superset of `subset`. """ - if ignoreMissing: - # Some entries in `subset` may not be in `src`. Remove such entries first. - subset.intersection_update(src) - else: - assert src.issuperset(subset), ( - "Error processing: {}\n" - "The following entries were not found:\n" - "{}" - "Please visit go/hiddenapi for more information.").format( - source, "".join(map(lambda x: " " + str(x), subset.difference(src)))) - assert dst.isdisjoint(subset) + assert src.issuperset(subset), ( + "Error processing: {}\n" + "The following entries were not found:\n" + "{}" + "Please visit go/hiddenapi for more information.").format( + source, "".join(map(lambda x: " " + str(x), subset.difference(src)))) + assert dst.isdisjoint(subset) # Order matters if `src` and `subset` are the same object. dst.update(subset) src.difference_update(subset) +def get_package_name(signature): + """Returns the package name prefix of a class member signature. + + Example: "Ljava/lang/String;->hashCode()J" --> "Ljava/lang/" + + Args: + signature (string): Member signature + + Returns + string: Package name of the given member + """ + class_name_end = signature.find("->") + assert class_name_end != -1, "Invalid signature: {}".format(signature) + package_name_end = signature.rfind("/", 0, class_name_end) + assert package_name_end != -1, "Invalid signature: {}".format(signature) + return signature[:package_name_end + 1] + +def all_package_names(*args): + """Returns a set of packages names in given lists of member signatures. + + Example: args = [ set([ "Lpkg1/ClassA;->foo()V", "Lpkg2/ClassB;->bar()J" ]), + set([ "Lpkg1/ClassC;->baz()Z" ]) ] + return value = set([ "Lpkg1/", "Lpkg2" ]) + + Args: + *args (list): List of sets to iterate over and extract the package names + of its elements (member signatures) + + Returns: + set: All package names extracted from the given lists of signatures. + """ + packages = set() + for arg in args: + packages = packages.union(map(get_package_name, arg)) + return packages + def move_all(src, dst): """Moves all elements of one set to another. @@ -117,7 +144,7 @@ def move_all(src, dst): """ move_between_sets(src, src, dst) -def move_from_files(filenames, src, dst, ignoreMissing = False): +def move_from_files(filenames, src, dst): """Loads member signatures from a list of files and moves them to a given set. Opens files in `filenames`, reads all their lines and moves those from `src` @@ -130,7 +157,7 @@ def move_from_files(filenames, src, dst, ignoreMissing = False): """ if filenames: for filename in filenames: - move_between_sets(set(read_lines(filename)), src, dst, filename, ignoreMissing) + move_between_sets(set(read_lines(filename)), src, dst, filename) def move_serialization(src, dst): """Moves all members matching serialization API signatures between given sets. @@ -152,6 +179,17 @@ def move_serialization(src, dst): regex = re.compile(r'.*->(' + '|'.join(serialization_patterns) + r')$') move_between_sets(filter(lambda api: regex.match(api), src), src, dst) +def move_from_packages(packages, src, dst): + """Moves all members of given package names from one set to another. + + Args: + packages (list): List of string package names. + src (set): Set that will be searched for API matching one of the given + package names. Surch API will be removed from the set. + dst (set): Set that matching API will be moved to. + """ + move_between_sets(filter(lambda api: get_package_name(api) in packages, src), src, dst) + def main(argv): args = get_args() @@ -171,15 +209,17 @@ def main(argv): # Read all files which manually assign members to specific lists. move_from_files(args.input_whitelists, uncategorized, whitelist) - move_from_files(args.input_light_greylists, uncategorized, light_greylist) + move_from_files(args.input_greylists, uncategorized, light_greylist) move_from_files(args.input_blacklists, uncategorized, blacklist) # Iterate over all uncategorized members and move serialization API to light greylist. move_serialization(uncategorized, light_greylist) - # Read dark greylist inputs and move all entries to dark greylist. - # Note that the input is the list from P, so we will ignore missing entries. - move_from_files(args.input_dark_greylists, uncategorized, dark_greylist, ignoreMissing=True) + # Extract package names of members from whitelist and light greylist, which + # are assumed to have been finalized at this point. Assign all uncategorized + # members from the same packages to the dark greylist. + dark_greylist_packages = all_package_names(whitelist, light_greylist) + move_from_packages(dark_greylist_packages, uncategorized, dark_greylist) # Assign all uncategorized members to the blacklist. move_all(uncategorized, blacklist) |