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

Commit 8f42ce71 authored by William Roberts's avatar William Roberts Committed by Dan Albert
Browse files

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: default avatarWilliam Roberts <william.c.roberts@intel.com>
parent 5f059a76
Loading
Loading
Loading
Loading
+120 −60
Original line number Diff line number Diff line
@@ -98,8 +98,20 @@ class AID(object):
        value (str) The User Id (uid) of the associate define.
        found (str) The file it was found in, can be None.
        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):
        """
        Args:
@@ -116,6 +128,39 @@ class AID(object):
        self.found = found
        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):
    """Represents a filesystem config array entry.
@@ -160,22 +205,12 @@ class AIDHeaderParser(object):
    """

    _SKIPWORDS = ['UNUSED']
    _AID_KW = 'AID_'
    _AID_DEFINE = re.compile(r'\s*#define\s+%s.*' % _AID_KW)
    _AID_DEFINE = re.compile(r'\s*#define\s+%s.*' % AID.PREFIX)
    _OEM_START_KW = 'START'
    _OEM_END_KW = 'END'
    _OEM_RANGE = re.compile('AID_OEM_RESERVED_[0-9]*_{0,1}(%s|%s)' %
                            (_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):
        """
        Args:
@@ -240,19 +275,18 @@ class AIDHeaderParser(object):
            ValueError: With message set to indicate the error.
        """

        # friendly name
        name = AIDHeaderParser._convert_friendly(identifier)
        aid = AID(identifier, value, self._aid_header)

        # 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)

        if value in self._aid_value_to_name:
            raise ValueError('Duplicate aid value "%u" for %s' % value,
                             identifier)

        self._aid_name_to_value[name] = AID(identifier, value, self._aid_header)
        self._aid_value_to_name[value] = name
        self._aid_name_to_value[aid.friendly] = aid
        self._aid_value_to_name[value] = aid.friendly

    def _handle_oem_range(self, identifier, value):
        """Handle an OEM range C #define.
@@ -363,7 +397,7 @@ class AIDHeaderParser(object):
        Returns:
            A list of AID() objects.
        """
        return self._aid_name_to_value
        return self._aid_name_to_value.values()

    @staticmethod
    def _convert_lst_to_tup(name, lst):
@@ -385,25 +419,6 @@ class AIDHeaderParser(object):

        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
    def _is_oem_range(aid):
        """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
    # checks end, if you change this, you may have to update the error
    # 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'

    # list of handler to required options, used to identify the
@@ -560,7 +574,7 @@ class FSConfigFileParser(object):
                                               self._seen_aids[0])

        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):
            tmp_errmsg = ('Invalid characters in AID section at "%d" for: "%s"'
                          % (invalid, FSConfigFileParser._AID_ERR_MSG))
@@ -861,6 +875,13 @@ class FSConfigGen(BaseGenerator):

    _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):

        opt_group.add_argument(
@@ -874,19 +895,46 @@ class FSConfigGen(BaseGenerator):

    def __call__(self, args):

        hdr = AIDHeaderParser(args['aid_header'])
        oem_ranges = hdr.oem_ranges
        self._base_parser = AIDHeaderParser(args['aid_header'])
        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)
        FSConfigGen._generate(parser.files, parser.dirs, parser.aids)
        # Detect name collisions on AIDs. Since friendly works as the
        # 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
    def _to_fs_entry(fs_config):
        """
        Given an FSConfig entry, converts it to a proper
        array entry for the array entry.
        base_set = set(base_friendly.keys())
        oem_set = set(oem_friendly.keys())

        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.

        { mode, user, group, caps, "path" },
        Prints '{ mode, user, group, caps, "path" },'.

        Calls sys.exit() on error.

        Args:
            fs_config (FSConfig): The entry to convert to
@@ -901,6 +949,19 @@ class FSConfigGen(BaseGenerator):
        caps = fs_config.caps
        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" },'

        expanded = fmt % (mode, user, group, caps, path)
@@ -910,15 +971,11 @@ class FSConfigGen(BaseGenerator):

    @staticmethod
    def _gen_inc():
        """
        Generate the include header lines and print to stdout.
        Internal use only.
        """
        """Generate the include header lines and print to stdout."""
        for include in FSConfigGen._INCLUDES:
            print '#include %s' % include

    @staticmethod
    def _generate(files, dirs, aids):
    def _generate(self):
        """Generates an OEM android_filesystem_config.h header file to stdout.

        Args:
@@ -933,6 +990,10 @@ class FSConfigGen(BaseGenerator):
        FSConfigGen._gen_inc()
        print

        dirs = self._oem_parser.dirs
        files = self._oem_parser.files
        aids = self._oem_parser.aids

        are_dirs = len(dirs) > 0
        are_files = len(files) > 0
        are_aids = len(aids) > 0
@@ -952,13 +1013,12 @@ class FSConfigGen(BaseGenerator):
            print FSConfigGen._DEFINE_NO_FILES + '\n'

        if not are_files and not are_dirs and not are_aids:
            print FSConfigGen._DEFAULT_WARNING
            return

        if are_files:
            print FSConfigGen._OPEN_FILE_STRUCT
            for fs_config in files:
                FSConfigGen._to_fs_entry(fs_config)
                self._to_fs_entry(fs_config)

            if not are_dirs:
                print FSConfigGen._IFDEF_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
@@ -971,7 +1031,7 @@ class FSConfigGen(BaseGenerator):
        if are_dirs:
            print FSConfigGen._OPEN_DIR_STRUCT
            for dir_entry in dirs:
                FSConfigGen._to_fs_entry(dir_entry)
                self._to_fs_entry(dir_entry)

            print FSConfigGen._CLOSE_FILE_STRUCT

@@ -1019,8 +1079,8 @@ class AIDArrayGen(BaseGenerator):
        print
        print AIDArrayGen._OPEN_ID_ARRAY

        for name, aid in hdr.aids.iteritems():
            print AIDArrayGen._ID_ENTRY % (name, aid.identifier)
        for aid in hdr.aids:
            print AIDArrayGen._ID_ENTRY % (aid.friendly, aid.identifier)

        print AIDArrayGen._CLOSE_FILE_STRUCT
        print