def _ParseManifestFromApk(apk_path): aapt_output = aapt.Dump('xmltree', apk_path, 'AndroidManifest.xml') parsed_manifest = {} node_stack = [parsed_manifest] indent = ' ' for line in aapt_output[1:]: if len(line) == 0: continue indent_depth = 0 while line[(len(indent) * indent_depth):].startswith(indent): indent_depth += 1 node_stack = node_stack[:indent_depth] node = node_stack[-1] m = _MANIFEST_ELEMENT_RE.match(line[len(indent) * indent_depth:]) if m: if not m.group(1) in node: node[m.group(1)] = {} node_stack += [node[m.group(1)]] continue m = _MANIFEST_ATTRIBUTE_RE.match(line[len(indent) * indent_depth:]) if m: if not m.group(1) in node: node[m.group(1)] = [] node[m.group(1)].append(m.group(2) or m.group(3)) continue return parsed_manifest
def _ParseManifestFromApk(apk_path): aapt_output = aapt.Dump('xmltree', apk_path, 'AndroidManifest.xml') parsed_manifest = {} node_stack = [parsed_manifest] indent = ' ' if aapt_output[0].decode('utf8').startswith('N'): # if the first line is a namespace then the root manifest is indented, and # we need to add a dummy namespace node, then skip the first line (we dont # care about namespaces). node_stack.insert(0, {}) output_to_parse = aapt_output[1:] else: output_to_parse = aapt_output for line in output_to_parse: if len(line) == 0: continue # If namespaces are stripped, aapt still outputs the full url to the # namespace and appends it to the attribute names. line = line.decode('utf8') line = line.replace('http://schemas.android.com/apk/res/android:', 'android:') indent_depth = 0 while line[(len(indent) * indent_depth):].startswith(indent): indent_depth += 1 # Pop the stack until the height of the stack is the same is the depth of # the current line within the tree. node_stack = node_stack[:indent_depth + 1] node = node_stack[-1] # Element nodes are a list of python dicts while attributes are just a dict. # This is because multiple elements, at the same depth of tree and the same # name, are all added to the same list keyed under the element name. m = _MANIFEST_ELEMENT_RE.match(line[len(indent) * indent_depth:]) if m: manifest_key = m.group(1) if manifest_key in node: node[manifest_key] += [{}] else: node[manifest_key] = [{}] node_stack += [node[manifest_key][-1]] continue m = _MANIFEST_ATTRIBUTE_RE.match(line[len(indent) * indent_depth:]) if m: manifest_key = m.group(1) if manifest_key in node: raise ApkHelperError( "A single attribute should have one key and one value: {}". format(line)) else: node[manifest_key] = m.group(2) or m.group(3) continue return parsed_manifest
def GetSplitName(self): """Returns the name of the split of the apk.""" if self._split_name: return self._split_name aapt_output = aapt.Dump('badging', self._apk_path) for line in aapt_output: m = _SPLIT_NAME_RE.match(line) if m: self._split_name = m.group(1) return self._split_name return None
def GetPackageName(self): """Returns the package name of the apk.""" if self._package_name: return self._package_name aapt_output = aapt.Dump('badging', self._apk_path) for line in aapt_output: m = _PACKAGE_NAME_RE.match(line) if m: self._package_name = m.group(1) return self._package_name raise Exception('Failed to determine package name of %s' % self._apk_path)
def _ParseManifestFromApk(apk_path): aapt_output = aapt.Dump('xmltree', apk_path, 'AndroidManifest.xml') parsed_manifest = {} node_stack = [parsed_manifest] indent = ' ' for line in aapt_output[1:]: if len(line) == 0: continue indent_depth = 0 while line[(len(indent) * indent_depth):].startswith(indent): indent_depth += 1 node_stack = node_stack[:indent_depth] node = node_stack[-1] m = _MANIFEST_ELEMENT_RE.match(line[len(indent) * indent_depth:]) if m: manifest_key = m.group(1) if manifest_key in node: node[manifest_key] += [{}] else: node[manifest_key] = [{}] node_stack += [node[manifest_key][-1]] continue m = _MANIFEST_ATTRIBUTE_RE.match(line[len(indent) * indent_depth:]) if m: manifest_key = m.group(1) if manifest_key in node: raise base_error.BaseError( "A single attribute should have one key and one value") else: node[manifest_key] = m.group(2) or m.group(3) continue return parsed_manifest