fs_config: generate friendly in AID class

Generate the friendly name in one location. This prepares
the tool for generatting passwd and group files.

Also support mapping friendly names to identifiers.

Test: That output files stay the same as before.
Change-Id: I12198611126613eae81ca61614ed269c2439b72b
Signed-off-by: William Roberts <william.c.roberts@intel.com>
This commit is contained in:
William Roberts
2016-04-25 12:27:43 -07:00
committed by Dan Albert
parent 5f059a7691
commit 8f42ce71ac

View File

@@ -98,8 +98,20 @@ class AID(object):
value (str) The User Id (uid) of the associate define. value (str) The User Id (uid) of the associate define.
found (str) The file it was found in, can be None. found (str) The file it was found in, can be None.
normalized_value (str): Same as value, but base 10. normalized_value (str): Same as value, but base 10.
friendly (str): The friendly name of aid.
""" """
PREFIX = 'AID_'
# Some of the AIDS like AID_MEDIA_EX had names like mediaex
# list a map of things to fixup until we can correct these
# at a later date.
_FIXUPS = {
'media_drm': 'mediadrm',
'media_ex': 'mediaex',
'media_codec': 'mediacodec'
}
def __init__(self, identifier, value, found): def __init__(self, identifier, value, found):
""" """
Args: Args:
@@ -116,6 +128,39 @@ class AID(object):
self.found = found self.found = found
self.normalized_value = str(int(value, 0)) self.normalized_value = str(int(value, 0))
# Where we calculate the friendly name
friendly = identifier[len(AID.PREFIX):].lower()
self.friendly = AID._fixup_friendly(friendly)
@staticmethod
def is_friendly(name):
"""Determines if an AID is a freindly name or C define.
For example if name is AID_SYSTEM it returns false, if name
was system, it would return true.
Returns:
True if name is a friendly name False otherwise.
"""
return not name.startswith(AID.PREFIX)
@staticmethod
def _fixup_friendly(friendly):
"""Fixup friendly names that historically don't follow the convention.
Args:
friendly (str): The friendly name.
Returns:
The fixedup friendly name as a str.
"""
if friendly in AID._FIXUPS:
return AID._FIXUPS[friendly]
return friendly
class FSConfig(object): class FSConfig(object):
"""Represents a filesystem config array entry. """Represents a filesystem config array entry.
@@ -160,22 +205,12 @@ class AIDHeaderParser(object):
""" """
_SKIPWORDS = ['UNUSED'] _SKIPWORDS = ['UNUSED']
_AID_KW = 'AID_' _AID_DEFINE = re.compile(r'\s*#define\s+%s.*' % AID.PREFIX)
_AID_DEFINE = re.compile(r'\s*#define\s+%s.*' % _AID_KW)
_OEM_START_KW = 'START' _OEM_START_KW = 'START'
_OEM_END_KW = 'END' _OEM_END_KW = 'END'
_OEM_RANGE = re.compile('AID_OEM_RESERVED_[0-9]*_{0,1}(%s|%s)' % _OEM_RANGE = re.compile('AID_OEM_RESERVED_[0-9]*_{0,1}(%s|%s)' %
(_OEM_START_KW, _OEM_END_KW)) (_OEM_START_KW, _OEM_END_KW))
# Some of the AIDS like AID_MEDIA_EX had names like mediaex
# list a map of things to fixup until we can correct these
# at a later date.
_FIXUPS = {
'media_drm': 'mediadrm',
'media_ex': 'mediaex',
'media_codec': 'mediacodec'
}
def __init__(self, aid_header): def __init__(self, aid_header):
""" """
Args: Args:
@@ -240,19 +275,18 @@ class AIDHeaderParser(object):
ValueError: With message set to indicate the error. ValueError: With message set to indicate the error.
""" """
# friendly name aid = AID(identifier, value, self._aid_header)
name = AIDHeaderParser._convert_friendly(identifier)
# duplicate name # duplicate name
if name in self._aid_name_to_value: if aid.friendly in self._aid_name_to_value:
raise ValueError('Duplicate aid "%s"' % identifier) raise ValueError('Duplicate aid "%s"' % identifier)
if value in self._aid_value_to_name: if value in self._aid_value_to_name:
raise ValueError('Duplicate aid value "%u" for %s' % value, raise ValueError('Duplicate aid value "%u" for %s' % value,
identifier) identifier)
self._aid_name_to_value[name] = AID(identifier, value, self._aid_header) self._aid_name_to_value[aid.friendly] = aid
self._aid_value_to_name[value] = name self._aid_value_to_name[value] = aid.friendly
def _handle_oem_range(self, identifier, value): def _handle_oem_range(self, identifier, value):
"""Handle an OEM range C #define. """Handle an OEM range C #define.
@@ -363,7 +397,7 @@ class AIDHeaderParser(object):
Returns: Returns:
A list of AID() objects. A list of AID() objects.
""" """
return self._aid_name_to_value return self._aid_name_to_value.values()
@staticmethod @staticmethod
def _convert_lst_to_tup(name, lst): def _convert_lst_to_tup(name, lst):
@@ -385,25 +419,6 @@ class AIDHeaderParser(object):
return tuple(lst) return tuple(lst)
@staticmethod
def _convert_friendly(identifier):
"""
Translate AID_FOO_BAR to foo_bar (ie name)
Args:
identifier (str): The name of the #define.
Returns:
The friendly name as a str.
"""
name = identifier[len(AIDHeaderParser._AID_KW):].lower()
if name in AIDHeaderParser._FIXUPS:
return AIDHeaderParser._FIXUPS[name]
return name
@staticmethod @staticmethod
def _is_oem_range(aid): def _is_oem_range(aid):
"""Detects if a given aid is within the reserved OEM range. """Detects if a given aid is within the reserved OEM range.
@@ -449,8 +464,7 @@ class FSConfigFileParser(object):
# Since _AID_PREFIX is within the set of _AID_MATCH the error logic only # Since _AID_PREFIX is within the set of _AID_MATCH the error logic only
# checks end, if you change this, you may have to update the error # checks end, if you change this, you may have to update the error
# detection code. # detection code.
_AID_PREFIX = 'AID_' _AID_MATCH = re.compile('%s[A-Z0-9_]+' % AID.PREFIX)
_AID_MATCH = re.compile('%s[A-Z0-9_]+' % _AID_PREFIX)
_AID_ERR_MSG = 'Expecting upper case, a number or underscore' _AID_ERR_MSG = 'Expecting upper case, a number or underscore'
# list of handler to required options, used to identify the # list of handler to required options, used to identify the
@@ -560,7 +574,7 @@ class FSConfigFileParser(object):
self._seen_aids[0]) self._seen_aids[0])
match = FSConfigFileParser._AID_MATCH.match(section_name) match = FSConfigFileParser._AID_MATCH.match(section_name)
invalid = match.end() if match else len(FSConfigFileParser._AID_PREFIX) invalid = match.end() if match else len(AID.PREFIX)
if invalid != len(section_name): if invalid != len(section_name):
tmp_errmsg = ('Invalid characters in AID section at "%d" for: "%s"' tmp_errmsg = ('Invalid characters in AID section at "%d" for: "%s"'
% (invalid, FSConfigFileParser._AID_ERR_MSG)) % (invalid, FSConfigFileParser._AID_ERR_MSG))
@@ -861,6 +875,13 @@ class FSConfigGen(BaseGenerator):
_FILE_COMMENT = '// Defined in file: \"%s\"' _FILE_COMMENT = '// Defined in file: \"%s\"'
def __init__(self, *args, **kwargs):
BaseGenerator.__init__(args, kwargs)
self._oem_parser = None
self._base_parser = None
self._friendly_to_aid = None
def add_opts(self, opt_group): def add_opts(self, opt_group):
opt_group.add_argument( opt_group.add_argument(
@@ -874,19 +895,46 @@ class FSConfigGen(BaseGenerator):
def __call__(self, args): def __call__(self, args):
hdr = AIDHeaderParser(args['aid_header']) self._base_parser = AIDHeaderParser(args['aid_header'])
oem_ranges = hdr.oem_ranges self._oem_parser = FSConfigFileParser(args['fsconfig'],
self._base_parser.oem_ranges)
base_aids = self._base_parser.aids
oem_aids = self._oem_parser.aids
parser = FSConfigFileParser(args['fsconfig'], oem_ranges) # Detect name collisions on AIDs. Since friendly works as the
FSConfigGen._generate(parser.files, parser.dirs, parser.aids) # identifier for collision testing and we need friendly later on for
# name resolution, just calculate and use friendly.
# {aid.friendly: aid for aid in base_aids}
base_friendly = {aid.friendly: aid for aid in base_aids}
oem_friendly = {aid.friendly: aid for aid in oem_aids}
@staticmethod base_set = set(base_friendly.keys())
def _to_fs_entry(fs_config): oem_set = set(oem_friendly.keys())
"""
Given an FSConfig entry, converts it to a proper
array entry for the array entry.
{ mode, user, group, caps, "path" }, common = base_set & oem_set
if len(common) > 0:
emsg = 'Following AID Collisions detected for: \n'
for friendly in common:
base = base_friendly[friendly]
oem = oem_friendly[friendly]
emsg += (
'Identifier: "%s" Friendly Name: "%s" '
'found in file "%s" and "%s"' %
(base.identifier, base.friendly, base.found, oem.found))
sys.exit(emsg)
self._friendly_to_aid = oem_friendly
self._friendly_to_aid.update(base_friendly)
self._generate()
def _to_fs_entry(self, fs_config):
"""Converts an FSConfig entry to an fs entry.
Prints '{ mode, user, group, caps, "path" },'.
Calls sys.exit() on error.
Args: Args:
fs_config (FSConfig): The entry to convert to fs_config (FSConfig): The entry to convert to
@@ -901,6 +949,19 @@ class FSConfigGen(BaseGenerator):
caps = fs_config.caps caps = fs_config.caps
path = fs_config.path path = fs_config.path
emsg = 'Cannot convert friendly name "%s" to identifier!'
# remap friendly names to identifier names
if AID.is_friendly(user):
if user not in self._friendly_to_aid:
sys.exit(emsg % user)
user = self._friendly_to_aid[user].identifier
if AID.is_friendly(group):
if group not in self._friendly_to_aid:
sys.exit(emsg % group)
group = self._friendly_to_aid[group].identifier
fmt = '{ %s, %s, %s, %s, "%s" },' fmt = '{ %s, %s, %s, %s, "%s" },'
expanded = fmt % (mode, user, group, caps, path) expanded = fmt % (mode, user, group, caps, path)
@@ -910,15 +971,11 @@ class FSConfigGen(BaseGenerator):
@staticmethod @staticmethod
def _gen_inc(): def _gen_inc():
""" """Generate the include header lines and print to stdout."""
Generate the include header lines and print to stdout.
Internal use only.
"""
for include in FSConfigGen._INCLUDES: for include in FSConfigGen._INCLUDES:
print '#include %s' % include print '#include %s' % include
@staticmethod def _generate(self):
def _generate(files, dirs, aids):
"""Generates an OEM android_filesystem_config.h header file to stdout. """Generates an OEM android_filesystem_config.h header file to stdout.
Args: Args:
@@ -933,6 +990,10 @@ class FSConfigGen(BaseGenerator):
FSConfigGen._gen_inc() FSConfigGen._gen_inc()
print print
dirs = self._oem_parser.dirs
files = self._oem_parser.files
aids = self._oem_parser.aids
are_dirs = len(dirs) > 0 are_dirs = len(dirs) > 0
are_files = len(files) > 0 are_files = len(files) > 0
are_aids = len(aids) > 0 are_aids = len(aids) > 0
@@ -952,13 +1013,12 @@ class FSConfigGen(BaseGenerator):
print FSConfigGen._DEFINE_NO_FILES + '\n' print FSConfigGen._DEFINE_NO_FILES + '\n'
if not are_files and not are_dirs and not are_aids: if not are_files and not are_dirs and not are_aids:
print FSConfigGen._DEFAULT_WARNING
return return
if are_files: if are_files:
print FSConfigGen._OPEN_FILE_STRUCT print FSConfigGen._OPEN_FILE_STRUCT
for fs_config in files: for fs_config in files:
FSConfigGen._to_fs_entry(fs_config) self._to_fs_entry(fs_config)
if not are_dirs: if not are_dirs:
print FSConfigGen._IFDEF_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS print FSConfigGen._IFDEF_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
@@ -971,7 +1031,7 @@ class FSConfigGen(BaseGenerator):
if are_dirs: if are_dirs:
print FSConfigGen._OPEN_DIR_STRUCT print FSConfigGen._OPEN_DIR_STRUCT
for dir_entry in dirs: for dir_entry in dirs:
FSConfigGen._to_fs_entry(dir_entry) self._to_fs_entry(dir_entry)
print FSConfigGen._CLOSE_FILE_STRUCT print FSConfigGen._CLOSE_FILE_STRUCT
@@ -1019,8 +1079,8 @@ class AIDArrayGen(BaseGenerator):
print print
print AIDArrayGen._OPEN_ID_ARRAY print AIDArrayGen._OPEN_ID_ARRAY
for name, aid in hdr.aids.iteritems(): for aid in hdr.aids:
print AIDArrayGen._ID_ENTRY % (name, aid.identifier) print AIDArrayGen._ID_ENTRY % (aid.friendly, aid.identifier)
print AIDArrayGen._CLOSE_FILE_STRUCT print AIDArrayGen._CLOSE_FILE_STRUCT
print print