Merge "Update language to comply with Android's inclusive language guidance" am: 31be55091f am: df5b66050c
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1374279 Change-Id: I9bff1926c2878da6b20f67482683afccb21123f4
This commit is contained in:
committed by
Automerger Merge Worker
commit
b6f7d962e4
@@ -13,9 +13,7 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
"""
|
"""Generate API lists for non-SDK API enforcement."""
|
||||||
Generate API lists for non-SDK API enforcement.
|
|
||||||
"""
|
|
||||||
import argparse
|
import argparse
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
import functools
|
import functools
|
||||||
@@ -24,27 +22,47 @@ import re
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
# Names of flags recognized by the `hiddenapi` tool.
|
# Names of flags recognized by the `hiddenapi` tool.
|
||||||
FLAG_WHITELIST = "whitelist"
|
FLAG_SDK = 'sdk'
|
||||||
FLAG_GREYLIST = "greylist"
|
FLAG_UNSUPPORTED = 'unsupported'
|
||||||
FLAG_BLACKLIST = "blacklist"
|
FLAG_BLOCKED = 'blocked'
|
||||||
FLAG_GREYLIST_MAX_O = "greylist-max-o"
|
FLAG_MAX_TARGET_O = 'max-target-o'
|
||||||
FLAG_GREYLIST_MAX_P = "greylist-max-p"
|
FLAG_MAX_TARGET_P = 'max-target-p'
|
||||||
FLAG_GREYLIST_MAX_Q = "greylist-max-q"
|
FLAG_MAX_TARGET_Q = 'max-target-q'
|
||||||
FLAG_GREYLIST_MAX_R = "greylist-max-r"
|
FLAG_MAX_TARGET_R = 'max-target-r'
|
||||||
FLAG_CORE_PLATFORM_API = "core-platform-api"
|
FLAG_CORE_PLATFORM_API = 'core-platform-api'
|
||||||
FLAG_PUBLIC_API = "public-api"
|
FLAG_PUBLIC_API = 'public-api'
|
||||||
FLAG_SYSTEM_API = "system-api"
|
FLAG_SYSTEM_API = 'system-api'
|
||||||
FLAG_TEST_API = "test-api"
|
FLAG_TEST_API = 'test-api'
|
||||||
|
|
||||||
|
OLD_FLAG_SDK = "whitelist"
|
||||||
|
OLD_FLAG_UNSUPPORTED = "greylist"
|
||||||
|
OLD_FLAG_BLOCKED = "blacklist"
|
||||||
|
OLD_FLAG_MAX_TARGET_O = "greylist-max-o"
|
||||||
|
OLD_FLAG_MAX_TARGET_P = "greylist-max-p"
|
||||||
|
OLD_FLAG_MAX_TARGET_Q = "greylist-max-q"
|
||||||
|
OLD_FLAG_MAX_TARGET_R = "greylist-max-r"
|
||||||
|
|
||||||
|
OLD_FLAGS_TO_NEW = {
|
||||||
|
OLD_FLAG_SDK: FLAG_SDK,
|
||||||
|
OLD_FLAG_UNSUPPORTED: FLAG_UNSUPPORTED,
|
||||||
|
OLD_FLAG_BLOCKED: FLAG_BLOCKED,
|
||||||
|
OLD_FLAG_MAX_TARGET_O: FLAG_MAX_TARGET_O,
|
||||||
|
OLD_FLAG_MAX_TARGET_P: FLAG_MAX_TARGET_P,
|
||||||
|
OLD_FLAG_MAX_TARGET_Q: FLAG_MAX_TARGET_Q,
|
||||||
|
OLD_FLAG_MAX_TARGET_R: FLAG_MAX_TARGET_R,
|
||||||
|
}
|
||||||
|
|
||||||
|
NEW_FLAGS_TO_OLD = dict(zip(OLD_FLAGS_TO_NEW.values(), OLD_FLAGS_TO_NEW.keys()))
|
||||||
|
|
||||||
# List of all known flags.
|
# List of all known flags.
|
||||||
FLAGS_API_LIST = [
|
FLAGS_API_LIST = [
|
||||||
FLAG_WHITELIST,
|
FLAG_SDK,
|
||||||
FLAG_GREYLIST,
|
FLAG_UNSUPPORTED,
|
||||||
FLAG_BLACKLIST,
|
FLAG_BLOCKED,
|
||||||
FLAG_GREYLIST_MAX_O,
|
FLAG_MAX_TARGET_O,
|
||||||
FLAG_GREYLIST_MAX_P,
|
FLAG_MAX_TARGET_P,
|
||||||
FLAG_GREYLIST_MAX_Q,
|
FLAG_MAX_TARGET_Q,
|
||||||
FLAG_GREYLIST_MAX_R,
|
FLAG_MAX_TARGET_R,
|
||||||
]
|
]
|
||||||
ALL_FLAGS = FLAGS_API_LIST + [
|
ALL_FLAGS = FLAGS_API_LIST + [
|
||||||
FLAG_CORE_PLATFORM_API,
|
FLAG_CORE_PLATFORM_API,
|
||||||
@@ -58,7 +76,7 @@ ALL_FLAGS_SET = set(ALL_FLAGS)
|
|||||||
|
|
||||||
# Suffix used in command line args to express that only known and
|
# Suffix used in command line args to express that only known and
|
||||||
# otherwise unassigned entries should be assign the given flag.
|
# otherwise unassigned entries should be assign the given flag.
|
||||||
# For example, the P dark greylist is checked in as it was in P,
|
# For example, the max-target-P list is checked in as it was in P,
|
||||||
# but signatures have changes since then. The flag instructs this
|
# but signatures have changes since then. The flag instructs this
|
||||||
# script to skip any entries which do not exist any more.
|
# script to skip any entries which do not exist any more.
|
||||||
FLAG_IGNORE_CONFLICTS_SUFFIX = "-ignore-conflicts"
|
FLAG_IGNORE_CONFLICTS_SUFFIX = "-ignore-conflicts"
|
||||||
@@ -87,6 +105,7 @@ SERIALIZATION_REGEX = re.compile(r'.*->(' + '|'.join(SERIALIZATION_PATTERNS) + r
|
|||||||
HAS_NO_API_LIST_ASSIGNED = lambda api, flags: not FLAGS_API_LIST_SET.intersection(flags)
|
HAS_NO_API_LIST_ASSIGNED = lambda api, flags: not FLAGS_API_LIST_SET.intersection(flags)
|
||||||
IS_SERIALIZATION = lambda api, flags: SERIALIZATION_REGEX.match(api)
|
IS_SERIALIZATION = lambda api, flags: SERIALIZATION_REGEX.match(api)
|
||||||
|
|
||||||
|
|
||||||
def get_args():
|
def get_args():
|
||||||
"""Parses command line arguments.
|
"""Parses command line arguments.
|
||||||
|
|
||||||
@@ -113,6 +132,7 @@ def get_args():
|
|||||||
|
|
||||||
return parser.parse_args()
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
def read_lines(filename):
|
def read_lines(filename):
|
||||||
"""Reads entire file and return it as a list of lines.
|
"""Reads entire file and return it as a list of lines.
|
||||||
|
|
||||||
@@ -130,8 +150,9 @@ def read_lines(filename):
|
|||||||
lines = map(lambda line: line.strip(), lines)
|
lines = map(lambda line: line.strip(), lines)
|
||||||
return set(lines)
|
return set(lines)
|
||||||
|
|
||||||
|
|
||||||
def write_lines(filename, lines):
|
def write_lines(filename, lines):
|
||||||
"""Writes list of lines into a file, overwriting the file it it exists.
|
"""Writes list of lines into a file, overwriting the file if it exists.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
filename (string): Path to the file to be writting into.
|
filename (string): Path to the file to be writting into.
|
||||||
@@ -141,6 +162,7 @@ def write_lines(filename, lines):
|
|||||||
with open(filename, 'w') as f:
|
with open(filename, 'w') as f:
|
||||||
f.writelines(lines)
|
f.writelines(lines)
|
||||||
|
|
||||||
|
|
||||||
def extract_package(signature):
|
def extract_package(signature):
|
||||||
"""Extracts the package from a signature.
|
"""Extracts the package from a signature.
|
||||||
|
|
||||||
@@ -159,6 +181,7 @@ def extract_package(signature):
|
|||||||
package_name = full_class_name.rpartition("/")[0]
|
package_name = full_class_name.rpartition("/")[0]
|
||||||
return package_name.replace('/', '.')
|
return package_name.replace('/', '.')
|
||||||
|
|
||||||
|
|
||||||
class FlagsDict:
|
class FlagsDict:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._dict_keyset = set()
|
self._dict_keyset = set()
|
||||||
@@ -182,6 +205,36 @@ class FlagsDict:
|
|||||||
"Please visit go/hiddenapi for more information.").format(
|
"Please visit go/hiddenapi for more information.").format(
|
||||||
source, "\n".join(flags_subset - ALL_FLAGS_SET))
|
source, "\n".join(flags_subset - ALL_FLAGS_SET))
|
||||||
|
|
||||||
|
def convert_to_new_flag(self, flag):
|
||||||
|
"""Converts old flag to a new variant.
|
||||||
|
|
||||||
|
Flags that are considered old are replaced with new versions.
|
||||||
|
Otherwise, it is a no-op.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
flag: a string, representing SDK flag.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A string. Result of conversion.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return OLD_FLAGS_TO_NEW.get(flag, flag)
|
||||||
|
|
||||||
|
def convert_to_old_flag(self, flag):
|
||||||
|
"""Converts a new flag to a old variant.
|
||||||
|
|
||||||
|
No-op if there is no suitable old flag.
|
||||||
|
Only used to support backwards compatibility.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
flag: a string, representing SDK flag.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A string. Result of conversion.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return NEW_FLAGS_TO_OLD.get(flag, flag)
|
||||||
|
|
||||||
def filter_apis(self, filter_fn):
|
def filter_apis(self, filter_fn):
|
||||||
"""Returns APIs which match a given predicate.
|
"""Returns APIs which match a given predicate.
|
||||||
|
|
||||||
@@ -212,10 +265,16 @@ class FlagsDict:
|
|||||||
def generate_csv(self):
|
def generate_csv(self):
|
||||||
"""Constructs CSV entries from a dictionary.
|
"""Constructs CSV entries from a dictionary.
|
||||||
|
|
||||||
|
Old versions of flags are used to generate the file.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List of lines comprising a CSV file. See "parse_and_merge_csv" for format description.
|
List of lines comprising a CSV file. See "parse_and_merge_csv" for format description.
|
||||||
"""
|
"""
|
||||||
return sorted(map(lambda api: ",".join([api] + sorted(self._dict[api])), self._dict))
|
lines = []
|
||||||
|
for api in self._dict:
|
||||||
|
flags = sorted([self.convert_to_old_flag(flag) for flag in self._dict[api]])
|
||||||
|
lines.append(",".join([api] + flags))
|
||||||
|
return sorted(lines)
|
||||||
|
|
||||||
def parse_and_merge_csv(self, csv_lines, source = "<unknown>"):
|
def parse_and_merge_csv(self, csv_lines, source = "<unknown>"):
|
||||||
"""Parses CSV entries and merges them into a given dictionary.
|
"""Parses CSV entries and merges them into a given dictionary.
|
||||||
@@ -237,17 +296,16 @@ class FlagsDict:
|
|||||||
self._dict_keyset.update([ csv[0] for csv in csv_values ])
|
self._dict_keyset.update([ csv[0] for csv in csv_values ])
|
||||||
|
|
||||||
# Check that all flags are known.
|
# Check that all flags are known.
|
||||||
csv_flags = set(functools.reduce(
|
csv_flags = set()
|
||||||
lambda x, y: set(x).union(y),
|
for csv in csv_values:
|
||||||
[ csv[1:] for csv in csv_values ],
|
csv_flags.update([self.convert_to_new_flag(flag) for flag in csv[1:]])
|
||||||
[]))
|
|
||||||
self._check_flags_set(csv_flags, source)
|
self._check_flags_set(csv_flags, source)
|
||||||
|
|
||||||
# Iterate over all CSV lines, find entry in dict and append flags to it.
|
# Iterate over all CSV lines, find entry in dict and append flags to it.
|
||||||
for csv in csv_values:
|
for csv in csv_values:
|
||||||
flags = csv[1:]
|
flags = [self.convert_to_new_flag(flag) for flag in csv[1:]]
|
||||||
if (FLAG_PUBLIC_API in flags) or (FLAG_SYSTEM_API in flags):
|
if (FLAG_PUBLIC_API in flags) or (FLAG_SYSTEM_API in flags):
|
||||||
flags.append(FLAG_WHITELIST)
|
flags.append(FLAG_SDK)
|
||||||
self._dict[csv[0]].update(flags)
|
self._dict[csv[0]].update(flags)
|
||||||
|
|
||||||
def assign_flag(self, flag, apis, source="<unknown>"):
|
def assign_flag(self, flag, apis, source="<unknown>"):
|
||||||
@@ -271,6 +329,7 @@ class FlagsDict:
|
|||||||
for api in apis:
|
for api in apis:
|
||||||
self._dict[api].add(flag)
|
self._dict[api].add(flag)
|
||||||
|
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
# Parse arguments.
|
# Parse arguments.
|
||||||
args = vars(get_args())
|
args = vars(get_args())
|
||||||
@@ -287,8 +346,8 @@ def main(argv):
|
|||||||
flags.parse_and_merge_csv(read_lines(filename), filename)
|
flags.parse_and_merge_csv(read_lines(filename), filename)
|
||||||
|
|
||||||
# Combine inputs which do not require any particular order.
|
# Combine inputs which do not require any particular order.
|
||||||
# (1) Assign serialization API to whitelist.
|
# (1) Assign serialization API to SDK.
|
||||||
flags.assign_flag(FLAG_WHITELIST, flags.filter_apis(IS_SERIALIZATION))
|
flags.assign_flag(FLAG_SDK, flags.filter_apis(IS_SERIALIZATION))
|
||||||
|
|
||||||
# (2) Merge text files with a known flag into the dictionary.
|
# (2) Merge text files with a known flag into the dictionary.
|
||||||
for flag in ALL_FLAGS:
|
for flag in ALL_FLAGS:
|
||||||
@@ -314,8 +373,8 @@ def main(argv):
|
|||||||
valid_entries = flags.filter_apis(should_add_signature_to_list)
|
valid_entries = flags.filter_apis(should_add_signature_to_list)
|
||||||
flags.assign_flag(flag, valid_entries)
|
flags.assign_flag(flag, valid_entries)
|
||||||
|
|
||||||
# Assign all remaining entries to the blacklist.
|
# Mark all remaining entries as blocked.
|
||||||
flags.assign_flag(FLAG_BLACKLIST, flags.filter_apis(HAS_NO_API_LIST_ASSIGNED))
|
flags.assign_flag(FLAG_BLOCKED, flags.filter_apis(HAS_NO_API_LIST_ASSIGNED))
|
||||||
|
|
||||||
# Write output.
|
# Write output.
|
||||||
write_lines(args["output"], flags.generate_csv())
|
write_lines(args["output"], flags.generate_csv())
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class TestHiddenapiListGeneration(unittest.TestCase):
|
|||||||
# Initialize flags so that A and B are put on the whitelist and
|
# Initialize flags so that A and B are put on the whitelist and
|
||||||
# C, D, E are left unassigned. Try filtering for the unassigned ones.
|
# C, D, E are left unassigned. Try filtering for the unassigned ones.
|
||||||
flags = FlagsDict()
|
flags = FlagsDict()
|
||||||
flags.parse_and_merge_csv(['A,' + FLAG_WHITELIST, 'B,' + FLAG_WHITELIST,
|
flags.parse_and_merge_csv(['A,' + FLAG_SDK, 'B,' + FLAG_SDK,
|
||||||
'C', 'D', 'E'])
|
'C', 'D', 'E'])
|
||||||
filter_set = flags.filter_apis(lambda api, flags: not flags)
|
filter_set = flags.filter_apis(lambda api, flags: not flags)
|
||||||
self.assertTrue(isinstance(filter_set, set))
|
self.assertTrue(isinstance(filter_set, set))
|
||||||
@@ -32,10 +32,10 @@ class TestHiddenapiListGeneration(unittest.TestCase):
|
|||||||
def test_get_valid_subset_of_unassigned_keys(self):
|
def test_get_valid_subset_of_unassigned_keys(self):
|
||||||
# Create flags where only A is unassigned.
|
# Create flags where only A is unassigned.
|
||||||
flags = FlagsDict()
|
flags = FlagsDict()
|
||||||
flags.parse_and_merge_csv(['A,' + FLAG_WHITELIST, 'B', 'C'])
|
flags.parse_and_merge_csv(['A,' + FLAG_SDK, 'B', 'C'])
|
||||||
flags.assign_flag(FLAG_GREYLIST, set(['C']))
|
flags.assign_flag(FLAG_UNSUPPORTED, set(['C']))
|
||||||
self.assertEqual(flags.generate_csv(),
|
self.assertEqual(flags.generate_csv(),
|
||||||
[ 'A,' + FLAG_WHITELIST, 'B', 'C,' + FLAG_GREYLIST ])
|
[ 'A,' + OLD_FLAG_SDK, 'B', 'C,' + OLD_FLAG_UNSUPPORTED ])
|
||||||
|
|
||||||
# Check three things:
|
# Check three things:
|
||||||
# (1) B is selected as valid unassigned
|
# (1) B is selected as valid unassigned
|
||||||
@@ -50,20 +50,21 @@ class TestHiddenapiListGeneration(unittest.TestCase):
|
|||||||
# Test empty CSV entry.
|
# Test empty CSV entry.
|
||||||
self.assertEqual(flags.generate_csv(), [])
|
self.assertEqual(flags.generate_csv(), [])
|
||||||
|
|
||||||
# Test new additions.
|
# Test new additions. CSV generator produces values with old flags
|
||||||
|
# to be backwards compatible.
|
||||||
flags.parse_and_merge_csv([
|
flags.parse_and_merge_csv([
|
||||||
'A,' + FLAG_GREYLIST,
|
'A,' + FLAG_UNSUPPORTED,
|
||||||
'B,' + FLAG_BLACKLIST + ',' + FLAG_GREYLIST_MAX_O,
|
'B,' + FLAG_BLOCKED + ',' + FLAG_MAX_TARGET_O,
|
||||||
'C,' + FLAG_SYSTEM_API + ',' + FLAG_WHITELIST,
|
'C,' + FLAG_SDK + ',' + FLAG_SYSTEM_API,
|
||||||
'D,' + FLAG_GREYLIST+ ',' + FLAG_TEST_API,
|
'D,' + FLAG_UNSUPPORTED + ',' + FLAG_TEST_API,
|
||||||
'E,' + FLAG_BLACKLIST+ ',' + FLAG_TEST_API,
|
'E,' + FLAG_BLOCKED + ',' + FLAG_TEST_API,
|
||||||
])
|
])
|
||||||
self.assertEqual(flags.generate_csv(), [
|
self.assertEqual(flags.generate_csv(), [
|
||||||
'A,' + FLAG_GREYLIST,
|
'A,' + OLD_FLAG_UNSUPPORTED,
|
||||||
'B,' + FLAG_BLACKLIST + "," + FLAG_GREYLIST_MAX_O,
|
'B,' + OLD_FLAG_BLOCKED + "," + OLD_FLAG_MAX_TARGET_O,
|
||||||
'C,' + FLAG_SYSTEM_API + ',' + FLAG_WHITELIST,
|
'C,' + FLAG_SYSTEM_API + ',' + OLD_FLAG_SDK,
|
||||||
'D,' + FLAG_GREYLIST+ ',' + FLAG_TEST_API,
|
'D,' + OLD_FLAG_UNSUPPORTED + ',' + FLAG_TEST_API,
|
||||||
'E,' + FLAG_BLACKLIST+ ',' + FLAG_TEST_API,
|
'E,' + OLD_FLAG_BLOCKED + ',' + FLAG_TEST_API,
|
||||||
])
|
])
|
||||||
|
|
||||||
# Test unknown flag.
|
# Test unknown flag.
|
||||||
@@ -72,16 +73,16 @@ class TestHiddenapiListGeneration(unittest.TestCase):
|
|||||||
|
|
||||||
def test_assign_flag(self):
|
def test_assign_flag(self):
|
||||||
flags = FlagsDict()
|
flags = FlagsDict()
|
||||||
flags.parse_and_merge_csv(['A,' + FLAG_WHITELIST, 'B'])
|
flags.parse_and_merge_csv(['A,' + FLAG_SDK, 'B'])
|
||||||
|
|
||||||
# Test new additions.
|
# Test new additions.
|
||||||
flags.assign_flag(FLAG_GREYLIST, set([ 'A', 'B' ]))
|
flags.assign_flag(FLAG_UNSUPPORTED, set([ 'A', 'B' ]))
|
||||||
self.assertEqual(flags.generate_csv(),
|
self.assertEqual(flags.generate_csv(),
|
||||||
[ 'A,' + FLAG_GREYLIST + "," + FLAG_WHITELIST, 'B,' + FLAG_GREYLIST ])
|
[ 'A,' + OLD_FLAG_UNSUPPORTED + "," + OLD_FLAG_SDK, 'B,' + OLD_FLAG_UNSUPPORTED ])
|
||||||
|
|
||||||
# Test invalid API signature.
|
# Test invalid API signature.
|
||||||
with self.assertRaises(AssertionError):
|
with self.assertRaises(AssertionError):
|
||||||
flags.assign_flag(FLAG_WHITELIST, set([ 'C' ]))
|
flags.assign_flag(FLAG_SDK, set([ 'C' ]))
|
||||||
|
|
||||||
# Test invalid flag.
|
# Test invalid flag.
|
||||||
with self.assertRaises(AssertionError):
|
with self.assertRaises(AssertionError):
|
||||||
|
|||||||
Reference in New Issue
Block a user