Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e87700fc authored by David Brazdil's avatar David Brazdil Committed by Gerrit Code Review
Browse files

Merge "Revert "Check in P dark greylist, use it for hidden API list generation""

parents 60ff003a 4a55eebf
Loading
Loading
Loading
Loading
+1 −5
Original line number Diff line number Diff line
@@ -336,7 +336,6 @@ $(INTERNAL_PLATFORM_HIDDENAPI_WHITELIST): \
    frameworks/base/tools/hiddenapi/generate_hiddenapi_lists.py \
    frameworks/base/config/hiddenapi-light-greylist.txt \
    frameworks/base/config/hiddenapi-vendor-list.txt \
    frameworks/base/config/hiddenapi-dark-greylist.txt \
    frameworks/base/config/hiddenapi-force-blacklist.txt \
    $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST) \
    $(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST) \
@@ -345,15 +344,12 @@ $(INTERNAL_PLATFORM_HIDDENAPI_WHITELIST): \
	    --input-public $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST) \
	    --input-private $(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST) \
	    --input-whitelists $(PRIVATE_WHITELIST_INPUTS) \
	    --input-light-greylists \
	    --input-greylists \
	        frameworks/base/config/hiddenapi-light-greylist.txt \
	        frameworks/base/config/hiddenapi-vendor-list.txt \
	        <(comm -12 <(sort $(INTERNAL_PLATFORM_REMOVED_DEX_API_FILE)) \
	                   $(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST)) \
	        $(PRIVATE_GREYLIST_INPUTS) \
	    --input-dark-greylists \
	        frameworks/base/config/hiddenapi-dark-greylist.txt \
	        $(PRIVATE_DARKGREYLIST_INPUTS) \
	    --input-blacklists frameworks/base/config/hiddenapi-force-blacklist.txt \
	    --output-whitelist $(INTERNAL_PLATFORM_HIDDENAPI_WHITELIST).tmp \
	    --output-light-greylist $(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST).tmp \
+0 −120915

File deleted.

Preview size limit exceeded, changes collapsed.

+64 −24
Original line number Diff line number Diff line
@@ -45,11 +45,8 @@ 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')
@@ -83,20 +80,14 @@ 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"
@@ -108,6 +99,42 @@ def move_between_sets(subset, src, dst, source = "<unknown>", ignoreMissing = Fa
    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)
+40 −0
Original line number Diff line number Diff line
@@ -38,6 +38,33 @@ class TestHiddenapiListGeneration(unittest.TestCase):
        with self.assertRaises(AssertionError) as ar:
            move_between_sets(set([1, 4]), A, B)

    def test_get_package_name(self):
        self.assertEqual(get_package_name("Ljava/lang/String;->clone()V"), "Ljava/lang/")

    def test_get_package_name_fail_no_arrow(self):
        with self.assertRaises(AssertionError) as ar:
            get_package_name("Ljava/lang/String;-clone()V")
        with self.assertRaises(AssertionError) as ar:
            get_package_name("Ljava/lang/String;>clone()V")
        with self.assertRaises(AssertionError) as ar:
            get_package_name("Ljava/lang/String;__clone()V")

    def test_get_package_name_fail_no_package(self):
        with self.assertRaises(AssertionError) as ar:
            get_package_name("LString;->clone()V")

    def test_all_package_names(self):
        self.assertEqual(all_package_names(), set())
        self.assertEqual(all_package_names(set(["Lfoo/Bar;->baz()V"])), set(["Lfoo/"]))
        self.assertEqual(
            all_package_names(set(["Lfoo/Bar;->baz()V", "Lfoo/BarX;->bazx()I"])),
            set(["Lfoo/"]))
        self.assertEqual(
            all_package_names(
                set(["Lfoo/Bar;->baz()V"]),
                set(["Lfoo/BarX;->bazx()I", "Labc/xyz/Mno;->ijk()J"])),
            set(["Lfoo/", "Labc/xyz/"]))

    def test_move_all(self):
        src = set([ "abc", "xyz" ])
        dst = set([ "def" ])
@@ -45,5 +72,18 @@ class TestHiddenapiListGeneration(unittest.TestCase):
        self.assertEqual(src, set())
        self.assertEqual(dst, set([ "abc", "def", "xyz" ]))

    def test_move_from_packages(self):
        src = set([ "Lfoo/bar/ClassA;->abc()J",        # will be moved
                    "Lfoo/bar/ClassA;->def()J",        # will be moved
                    "Lcom/pkg/example/ClassD;->ijk:J", # not moved: different package
                    "Lfoo/bar/xyz/ClassC;->xyz()Z" ])  # not moved: subpackage
        dst = set()
        packages = set([ "Lfoo/bar/" ])
        move_from_packages(packages, src, dst)
        self.assertEqual(
            src, set([ "Lfoo/bar/xyz/ClassC;->xyz()Z", "Lcom/pkg/example/ClassD;->ijk:J" ]))
        self.assertEqual(
            dst, set([ "Lfoo/bar/ClassA;->abc()J", "Lfoo/bar/ClassA;->def()J" ]))

if __name__ == '__main__':
    unittest.main()