Пример #1
0
def add_uses_non_sdk_api(doc):
    """Add android:usesNonSdkApi=true attribute to <application>.

  Args:
    doc: The XML document. May be modified by this function.
  Raises:
    RuntimeError: Invalid manifest
  """

    manifest = parse_manifest(doc)
    elems = get_children_with_tag(manifest, 'application')
    application = elems[0] if len(elems) == 1 else None
    if len(elems) > 1:
        raise RuntimeError('found multiple <application> tags')
    elif not elems:
        application = doc.createElement('application')
        indent = get_indent(manifest.firstChild, 1)
        first = manifest.firstChild
        manifest.insertBefore(doc.createTextNode(indent), first)
        manifest.insertBefore(application, first)

    attr = application.getAttributeNodeNS(android_ns, 'usesNonSdkApi')
    if attr is None:
        attr = doc.createAttributeNS(android_ns, 'android:usesNonSdkApi')
        attr.value = 'true'
        application.setAttributeNode(attr)
Пример #2
0
def extract_uses_libs_xml(xml):
    """Extract <uses-library> tags from the manifest."""

    manifest = parse_manifest(xml)
    elems = get_children_with_tag(manifest, 'application')
    application = elems[0] if len(elems) == 1 else None
    if len(elems) > 1:
        raise RuntimeError('found multiple <application> tags')
    elif not elems:
        if uses_libraries or optional_uses_libraries:
            raise ManifestMismatchError('no <application> tag found')
        return

    libs = get_children_with_tag(application, 'uses-library')

    required = [uses_library_name(x) for x in libs if uses_library_required(x)]
    optional = [
        uses_library_name(x) for x in libs if not uses_library_required(x)
    ]

    # render <uses-library> tags as XML for a pretty error message
    tags = []
    for lib in libs:
        tags.append(lib.toprettyxml())

    required = first_unique_elements(required)
    optional = first_unique_elements(optional)
    tags = first_unique_elements(tags)
    return required, optional, tags
Пример #3
0
def extract_target_sdk_version(doc):
    """Returns the targetSdkVersion from the manifest.

  Args:
    doc: The XML document.
  Raises:
    RuntimeError: invalid manifest
  """

    manifest = parse_manifest(doc)

    # Get or insert the uses-sdk element
    uses_sdk = get_children_with_tag(manifest, 'uses-sdk')
    if len(uses_sdk) > 1:
        raise RuntimeError('found multiple uses-sdk elements')
    elif len(uses_sdk) == 0:
        raise RuntimeError('missing uses-sdk element')

    uses_sdk = uses_sdk[0]

    min_attr = uses_sdk.getAttributeNodeNS(android_ns, 'minSdkVersion')
    if min_attr is None:
        raise RuntimeError('minSdkVersion is not specified')

    target_attr = uses_sdk.getAttributeNodeNS(android_ns, 'targetSdkVersion')
    if target_attr is None:
        target_attr = min_attr

    return target_attr.value
Пример #4
0
def raise_min_sdk_version(doc, min_sdk_version, target_sdk_version, library):
    """Ensure the manifest contains a <uses-sdk> tag with a minSdkVersion.

  Args:
    doc: The XML document.  May be modified by this function.
    min_sdk_version: The requested minSdkVersion attribute.
    target_sdk_version: The requested targetSdkVersion attribute.
    library: True if the manifest is for a library.
  Raises:
    RuntimeError: invalid manifest
  """

    manifest = parse_manifest(doc)

    # Get or insert the uses-sdk element
    uses_sdk = get_children_with_tag(manifest, 'uses-sdk')
    if len(uses_sdk) > 1:
        raise RuntimeError('found multiple uses-sdk elements')
    elif len(uses_sdk) == 1:
        element = uses_sdk[0]
    else:
        element = doc.createElement('uses-sdk')
        indent = get_indent(manifest.firstChild, 1)
        manifest.insertBefore(element, manifest.firstChild)

        # Insert an indent before uses-sdk to line it up with the indentation of the
        # other children of the <manifest> tag.
        manifest.insertBefore(doc.createTextNode(indent), manifest.firstChild)

    # Get or insert the minSdkVersion attribute.  If it is already present, make
    # sure it as least the requested value.
    min_attr = element.getAttributeNodeNS(android_ns, 'minSdkVersion')
    if min_attr is None:
        min_attr = doc.createAttributeNS(android_ns, 'android:minSdkVersion')
        min_attr.value = min_sdk_version
        element.setAttributeNode(min_attr)
    else:
        if compare_version_gt(min_sdk_version, min_attr.value):
            min_attr.value = min_sdk_version

    # Insert the targetSdkVersion attribute if it is missing.  If it is already
    # present leave it as is.
    target_attr = element.getAttributeNodeNS(android_ns, 'targetSdkVersion')
    if target_attr is None:
        target_attr = doc.createAttributeNS(android_ns,
                                            'android:targetSdkVersion')
        if library:
            # TODO(b/117122200): libraries shouldn't set targetSdkVersion at all, but
            # ManifestMerger treats minSdkVersion="Q" as targetSdkVersion="Q" if it
            # is empty.  Set it to something low so that it will be overriden by the
            # main manifest, but high enough that it doesn't cause implicit
            # permissions grants.
            target_attr.value = '15'
        else:
            target_attr.value = target_sdk_version
        element.setAttributeNode(target_attr)
Пример #5
0
def main(argv):
    if argv.__len__() < 2:
        if str(argv[0]).endswith(".manifest"):
            path = argv[0]
        else:
            path = os.path.abspath(
                '../') + "/resources/flowers-xy-V201902220937263726.manifest"
        data_set = manifest.parse_manifest(path)
        validate(data_set)
    elif argv.__len__() < 3:
        data_set = manifest.parse_manifest(argv[1])
        validate(data_set)
    else:
        path = argv[1]
        ak = argv[2]
        sk = argv[3]
        endpoint = argv[4]
        data_set = manifest.parse_manifest(path, ak, sk, endpoint)
        validate(data_set)
Пример #6
0
def add_uses_libraries(doc, new_uses_libraries, required):
    """Add additional <uses-library> tags

  Args:
    doc: The XML document. May be modified by this function.
    new_uses_libraries: The names of libraries to be added by this function.
    required: The value of android:required attribute. Can be true or false.
  Raises:
    RuntimeError: Invalid manifest
  """

    manifest = parse_manifest(doc)
    elems = get_children_with_tag(manifest, 'application')
    application = elems[0] if len(elems) == 1 else None
    if len(elems) > 1:
        raise RuntimeError('found multiple <application> tags')
    elif not elems:
        application = doc.createElement('application')
        indent = get_indent(manifest.firstChild, 1)
        first = manifest.firstChild
        manifest.insertBefore(doc.createTextNode(indent), first)
        manifest.insertBefore(application, first)

    indent = get_indent(application.firstChild, 2)

    last = application.lastChild
    if last is not None and last.nodeType != minidom.Node.TEXT_NODE:
        last = None

    for name in new_uses_libraries:
        if find_child_with_attribute(application, 'uses-library', android_ns,
                                     'name', name) is not None:
            # If the uses-library tag of the same 'name' attribute value exists,
            # respect it.
            continue

        ul = doc.createElement('uses-library')
        ul.setAttributeNS(android_ns, 'android:name', name)
        ul.setAttributeNS(android_ns, 'android:required',
                          str(required).lower())

        application.insertBefore(doc.createTextNode(indent), last)
        application.insertBefore(ul, last)

    # align the closing tag with the opening tag if it's not
    # indented
    if application.lastChild.nodeType != minidom.Node.TEXT_NODE:
        indent = get_indent(application.previousSibling, 1)
        application.appendChild(doc.createTextNode(indent))
def overwrite_package_name(test_config_doc, manifest_doc, package_name):

    manifest = parse_manifest(manifest_doc)
    original_package = manifest.getAttribute('package')

    test_config = parse_test_config(test_config_doc)
    tests = get_children_with_tag(test_config, 'test')

    for test in tests:
        options = get_children_with_tag(test, 'option')
        for option in options:
            if option.getAttribute(
                    'name') == "package" and option.getAttribute(
                        'value') == original_package:
                option.setAttribute('value', package_name)
Пример #8
0
def AddLoggingParent(android_manifest, logging_parent_value):
    """Add logging parent as an additional <meta-data> tag.

  Args:
    android_manifest: A string representing AndroidManifest.xml
    logging_parent_value: A string representing the logging
      parent value.
  Raises:
    RuntimeError: Invalid manifest
  Returns:
    A path to modified AndroidManifest.xml
  """
    doc = minidom.parse(android_manifest)
    manifest = parse_manifest(doc)
    logging_parent_key = 'android.content.pm.LOGGING_PARENT'
    elems = get_children_with_tag(manifest, 'application')
    application = elems[0] if len(elems) == 1 else None
    if len(elems) > 1:
        raise RuntimeError('found multiple <application> tags')
    elif not elems:
        application = doc.createElement('application')
        indent = get_indent(manifest.firstChild, 1)
        first = manifest.firstChild
        manifest.insertBefore(doc.createTextNode(indent), first)
        manifest.insertBefore(application, first)

    indent = get_indent(application.firstChild, 2)
    last = application.lastChild
    if last is not None and last.nodeType != minidom.Node.TEXT_NODE:
        last = None

    if not find_child_with_attribute(application, 'meta-data', android_ns,
                                     'name', logging_parent_key):
        ul = doc.createElement('meta-data')
        ul.setAttributeNS(android_ns, 'android:name', logging_parent_key)
        ul.setAttributeNS(android_ns, 'android:value', logging_parent_value)
        application.insertBefore(doc.createTextNode(indent), last)
        application.insertBefore(ul, last)
        last = application.lastChild

    if last and last.nodeType != minidom.Node.TEXT_NODE:
        indent = get_indent(application.previousSibling, 1)
        application.appendChild(doc.createTextNode(indent))

    with tempfile.NamedTemporaryFile(delete=False) as temp:
        write_xml(temp, doc)
        return temp.name
Пример #9
0
def add_logging_parent(doc, logging_parent_value):
    """Add logging parent as an additional <meta-data> tag.

  Args:
    doc: The XML document. May be modified by this function.
    logging_parent_value: A string representing the logging
      parent value.
  Raises:
    RuntimeError: Invalid manifest
  """
    manifest = parse_manifest(doc)

    logging_parent_key = 'android.content.pm.LOGGING_PARENT'
    elems = get_children_with_tag(manifest, 'application')
    application = elems[0] if len(elems) == 1 else None
    if len(elems) > 1:
        raise RuntimeError('found multiple <application> tags')
    elif not elems:
        application = doc.createElement('application')
        indent = get_indent(manifest.firstChild, 1)
        first = manifest.firstChild
        manifest.insertBefore(doc.createTextNode(indent), first)
        manifest.insertBefore(application, first)

    indent = get_indent(application.firstChild, 2)

    last = application.lastChild
    if last is not None and last.nodeType != minidom.Node.TEXT_NODE:
        last = None

    if not find_child_with_attribute(application, 'meta-data', android_ns,
                                     'name', logging_parent_key):
        ul = doc.createElement('meta-data')
        ul.setAttributeNS(android_ns, 'android:name', logging_parent_key)
        ul.setAttributeNS(android_ns, 'android:value', logging_parent_value)
        application.insertBefore(doc.createTextNode(indent), last)
        application.insertBefore(ul, last)
        last = application.lastChild

    # align the closing tag with the opening tag if it's not
    # indented
    if last and last.nodeType != minidom.Node.TEXT_NODE:
        indent = get_indent(application.previousSibling, 1)
        application.appendChild(doc.createTextNode(indent))
Пример #10
0
def set_has_code_to_false(doc):
    manifest = parse_manifest(doc)
    elems = get_children_with_tag(manifest, 'application')
    application = elems[0] if len(elems) == 1 else None
    if len(elems) > 1:
        raise RuntimeError('found multiple <application> tags')
    elif not elems:
        application = doc.createElement('application')
        indent = get_indent(manifest.firstChild, 1)
        first = manifest.firstChild
        manifest.insertBefore(doc.createTextNode(indent), first)
        manifest.insertBefore(application, first)

    attr = application.getAttributeNodeNS(android_ns, 'hasCode')
    if attr is not None:
        # Do nothing if the application already has a hasCode attribute.
        return
    attr = doc.createAttributeNS(android_ns, 'android:hasCode')
    attr.value = 'false'
    application.setAttributeNode(attr)
Пример #11
0
def add_use_embedded_dex(doc):
    manifest = parse_manifest(doc)
    elems = get_children_with_tag(manifest, 'application')
    application = elems[0] if len(elems) == 1 else None
    if len(elems) > 1:
        raise RuntimeError('found multiple <application> tags')
    elif not elems:
        application = doc.createElement('application')
        indent = get_indent(manifest.firstChild, 1)
        first = manifest.firstChild
        manifest.insertBefore(doc.createTextNode(indent), first)
        manifest.insertBefore(application, first)

    attr = application.getAttributeNodeNS(android_ns, 'useEmbeddedDex')
    if attr is None:
        attr = doc.createAttributeNS(android_ns, 'android:useEmbeddedDex')
        attr.value = 'true'
        application.setAttributeNode(attr)
    elif attr.value != 'true':
        raise RuntimeError(
            'existing attribute mismatches the option of --use-embedded-dex')
Пример #12
0
def extract_target_sdk_version_xml(xml):
    """Extract targetSdkVersion tags from the manifest."""

    manifest = parse_manifest(xml)

    # Get or insert the uses-sdk element
    uses_sdk = get_children_with_tag(manifest, 'uses-sdk')
    if len(uses_sdk) > 1:
        raise RuntimeError('found multiple uses-sdk elements')
    elif len(uses_sdk) == 0:
        raise RuntimeError('missing uses-sdk element')

    uses_sdk = uses_sdk[0]

    min_attr = uses_sdk.getAttributeNodeNS(android_ns, 'minSdkVersion')
    if min_attr is None:
        raise RuntimeError('minSdkVersion is not specified')

    target_attr = uses_sdk.getAttributeNodeNS(android_ns, 'targetSdkVersion')
    if target_attr is None:
        target_attr = min_attr

    return target_attr.value
Пример #13
0
def add_extract_native_libs(doc, extract_native_libs):
    manifest = parse_manifest(doc)
    elems = get_children_with_tag(manifest, 'application')
    application = elems[0] if len(elems) == 1 else None
    if len(elems) > 1:
        raise RuntimeError('found multiple <application> tags')
    elif not elems:
        application = doc.createElement('application')
        indent = get_indent(manifest.firstChild, 1)
        first = manifest.firstChild
        manifest.insertBefore(doc.createTextNode(indent), first)
        manifest.insertBefore(application, first)

    value = str(extract_native_libs).lower()
    attr = application.getAttributeNodeNS(android_ns, 'extractNativeLibs')
    if attr is None:
        attr = doc.createAttributeNS(android_ns, 'android:extractNativeLibs')
        attr.value = value
        application.setAttributeNode(attr)
    elif attr.value != value:
        raise RuntimeError(
            'existing attribute extractNativeLibs="%s" conflicts with --extract-native-libs="%s"'
            % (attr.value, value))
Пример #14
0
def enforce_uses_libraries(doc, uses_libraries, optional_uses_libraries):
    """Verify that the <uses-library> tags in the manifest match those provided by the build system.

  Args:
    doc: The XML document.
    uses_libraries: The names of <uses-library> tags known to the build system
    optional_uses_libraries: The names of <uses-library> tags with required:fals
      known to the build system
  Raises:
    RuntimeError: Invalid manifest
    ManifestMismatchError: Manifest does not match
  """

    manifest = parse_manifest(doc)
    elems = get_children_with_tag(manifest, 'application')
    application = elems[0] if len(elems) == 1 else None
    if len(elems) > 1:
        raise RuntimeError('found multiple <application> tags')
    elif not elems:
        if uses_libraries or optional_uses_libraries:
            raise ManifestMismatchError('no <application> tag found')
        return

    verify_uses_library(application, uses_libraries, optional_uses_libraries)