Allow for setting a logging_parent for an Android App.
Unit test: go test ./... -test.v -run TestOverrideAndroidApp
Unit test: python manifest_fixer_test.py
BUG: 148198056
Change-Id: Ib5ff235d2a93e88b86aec1c0b16327ea938a094d
diff --git a/scripts/manifest_fixer.py b/scripts/manifest_fixer.py
index 945bc18..c59732b 100755
--- a/scripts/manifest_fixer.py
+++ b/scripts/manifest_fixer.py
@@ -51,6 +51,9 @@
help='specify additional <uses-library> tag to add. android:requred is set to false')
parser.add_argument('--uses-non-sdk-api', dest='uses_non_sdk_api', action='store_true',
help='manifest is for a package built against the platform')
+ parser.add_argument('--logging-parent', dest='logging_parent', default='',
+ help=('specify logging parent as an additional <meta-data> tag. '
+ 'This value is ignored if the logging_parent meta-data tag is present.'))
parser.add_argument('--use-embedded-dex', dest='use_embedded_dex', action='store_true',
help=('specify if the app wants to use embedded dex and avoid extracted,'
'locally compiled code. Must not conflict if already declared '
@@ -124,6 +127,52 @@
element.setAttributeNode(target_attr)
+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))
+
+
def add_uses_libraries(doc, new_uses_libraries, required):
"""Add additional <uses-library> tags
@@ -291,6 +340,9 @@
if args.uses_non_sdk_api:
add_uses_non_sdk_api(doc)
+ if args.logging_parent:
+ add_logging_parent(doc, args.logging_parent)
+
if args.use_embedded_dex:
add_use_embedded_dex(doc)
diff --git a/scripts/manifest_fixer_test.py b/scripts/manifest_fixer_test.py
index ea8095e..d6e7f26 100755
--- a/scripts/manifest_fixer_test.py
+++ b/scripts/manifest_fixer_test.py
@@ -226,6 +226,47 @@
self.assertEqual(output, expected)
+class AddLoggingParentTest(unittest.TestCase):
+ """Unit tests for add_logging_parent function."""
+
+ def add_logging_parent_test(self, input_manifest, logging_parent=None):
+ doc = minidom.parseString(input_manifest)
+ if logging_parent:
+ manifest_fixer.add_logging_parent(doc, logging_parent)
+ output = StringIO.StringIO()
+ manifest_fixer.write_xml(output, doc)
+ return output.getvalue()
+
+ manifest_tmpl = (
+ '<?xml version="1.0" encoding="utf-8"?>\n'
+ '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
+ '%s'
+ '</manifest>\n')
+
+ def uses_logging_parent(self, logging_parent=None):
+ attrs = ''
+ if logging_parent:
+ meta_text = ('<meta-data android:name="android.content.pm.LOGGING_PARENT" '
+ 'android:value="%s"/>\n') % (logging_parent)
+ attrs += ' <application>\n %s </application>\n' % (meta_text)
+
+ return attrs
+
+ def test_no_logging_parent(self):
+ """Tests manifest_fixer with no logging_parent."""
+ manifest_input = self.manifest_tmpl % ''
+ expected = self.manifest_tmpl % self.uses_logging_parent()
+ output = self.add_logging_parent_test(manifest_input)
+ self.assertEqual(output, expected)
+
+ def test_logging_parent(self):
+ """Tests manifest_fixer with no logging_parent."""
+ manifest_input = self.manifest_tmpl % ''
+ expected = self.manifest_tmpl % self.uses_logging_parent('FOO')
+ output = self.add_logging_parent_test(manifest_input, 'FOO')
+ self.assertEqual(output, expected)
+
+
class AddUsesLibrariesTest(unittest.TestCase):
"""Unit tests for add_uses_libraries function."""