From 5b16dfb39af0c90695c9d5921b1886e8e8d285aa Mon Sep 17 00:00:00 2001 From: Baligh Uddin Date: Tue, 11 Feb 2020 17:27:19 -0800 Subject: [PATCH] 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 --- java/aar.go | 4 ++- java/android_manifest.go | 5 ++- java/app.go | 5 ++- java/app_test.go | 62 ++++++++++++++++++++-------------- scripts/manifest_fixer.py | 52 ++++++++++++++++++++++++++++ scripts/manifest_fixer_test.py | 41 ++++++++++++++++++++++ 6 files changed, 141 insertions(+), 28 deletions(-) diff --git a/java/aar.go b/java/aar.go index 24c5e7d04..05e662501 100644 --- a/java/aar.go +++ b/java/aar.go @@ -101,6 +101,7 @@ type aapt struct { usesNonSdkApis bool sdkLibraries []string hasNoCode bool + LoggingParent string splitNames []string splits []split @@ -241,7 +242,8 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, ex manifestSrcPath := android.PathForModuleSrc(ctx, manifestFile) manifestPath := manifestFixer(ctx, manifestSrcPath, sdkContext, sdkLibraries, - a.isLibrary, a.useEmbeddedNativeLibs, a.usesNonSdkApis, a.useEmbeddedDex, a.hasNoCode) + a.isLibrary, a.useEmbeddedNativeLibs, a.usesNonSdkApis, a.useEmbeddedDex, a.hasNoCode, + a.LoggingParent) // Add additional manifest files to transitive manifests. additionalManifests := android.PathsForModuleSrc(ctx, a.aaptProperties.Additional_manifests) diff --git a/java/android_manifest.go b/java/android_manifest.go index e3646f5f9..9a71be28a 100644 --- a/java/android_manifest.go +++ b/java/android_manifest.go @@ -53,7 +53,7 @@ var optionalUsesLibs = []string{ // Uses manifest_fixer.py to inject minSdkVersion, etc. into an AndroidManifest.xml func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext sdkContext, sdkLibraries []string, - isLibrary, useEmbeddedNativeLibs, usesNonSdkApis, useEmbeddedDex, hasNoCode bool) android.Path { + isLibrary, useEmbeddedNativeLibs, usesNonSdkApis, useEmbeddedDex, hasNoCode bool, loggingParent string) android.Path { var args []string if isLibrary { @@ -91,6 +91,9 @@ func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext args = append(args, "--has-no-code") } + if loggingParent != "" { + args = append(args, "--logging-parent", loggingParent) + } var deps android.Paths targetSdkVersion, err := sdkContext.targetSdkVersion().effectiveVersionString(ctx) if err != nil { diff --git a/java/app.go b/java/app.go index 02f3e7fc0..7e56d5716 100755 --- a/java/app.go +++ b/java/app.go @@ -111,6 +111,9 @@ type overridableAppProperties struct { // the package name of this app. The package name in the manifest file is used if one was not given. Package_name *string + + // the logging parent of this app. + Logging_parent *string } type AndroidApp struct { @@ -309,7 +312,7 @@ func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) { a.aapt.splitNames = a.appProperties.Package_splits a.aapt.sdkLibraries = a.exportedSdkLibs - + a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent) a.aapt.buildActions(ctx, sdkContext(a), aaptLinkFlags...) // apps manifests are handled by aapt, don't let Module see them diff --git a/java/app_test.go b/java/app_test.go index c86b038af..6d94160fa 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -1181,6 +1181,7 @@ func TestOverrideAndroidApp(t *testing.T) { name: "bar", base: "foo", certificate: ":new_certificate", + logging_parent: "bah", } android_app_certificate { @@ -1196,37 +1197,41 @@ func TestOverrideAndroidApp(t *testing.T) { `) expectedVariants := []struct { - moduleName string - variantName string - apkName string - apkPath string - signFlag string - overrides []string - aaptFlag string + moduleName string + variantName string + apkName string + apkPath string + signFlag string + overrides []string + aaptFlag string + logging_parent string }{ { - moduleName: "foo", - variantName: "android_common", - apkPath: "/target/product/test_device/system/app/foo/foo.apk", - signFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", - overrides: []string{"qux"}, - aaptFlag: "", + moduleName: "foo", + variantName: "android_common", + apkPath: "/target/product/test_device/system/app/foo/foo.apk", + signFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", + overrides: []string{"qux"}, + aaptFlag: "", + logging_parent: "", }, { - moduleName: "bar", - variantName: "android_common_bar", - apkPath: "/target/product/test_device/system/app/bar/bar.apk", - signFlag: "cert/new_cert.x509.pem cert/new_cert.pk8", - overrides: []string{"qux", "foo"}, - aaptFlag: "", + moduleName: "bar", + variantName: "android_common_bar", + apkPath: "/target/product/test_device/system/app/bar/bar.apk", + signFlag: "cert/new_cert.x509.pem cert/new_cert.pk8", + overrides: []string{"qux", "foo"}, + aaptFlag: "", + logging_parent: "bah", }, { - moduleName: "baz", - variantName: "android_common_baz", - apkPath: "/target/product/test_device/system/app/baz/baz.apk", - signFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", - overrides: []string{"qux", "foo"}, - aaptFlag: "--rename-manifest-package org.dandroid.bp", + moduleName: "baz", + variantName: "android_common_baz", + apkPath: "/target/product/test_device/system/app/baz/baz.apk", + signFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", + overrides: []string{"qux", "foo"}, + aaptFlag: "--rename-manifest-package org.dandroid.bp", + logging_parent: "", }, } for _, expected := range expectedVariants { @@ -1260,6 +1265,13 @@ func TestOverrideAndroidApp(t *testing.T) { expected.overrides, mod.appProperties.Overrides) } + // Test Overridable property: Logging_parent + logging_parent := mod.aapt.LoggingParent + if expected.logging_parent != logging_parent { + t.Errorf("Incorrect overrides property value for logging parent, expected: %q, got: %q", + expected.logging_parent, logging_parent) + } + // Check the package renaming flag, if exists. res := variant.Output("package-res.apk") aapt2Flags := res.Args["flags"] diff --git a/scripts/manifest_fixer.py b/scripts/manifest_fixer.py index 945bc1832..c59732bb9 100755 --- a/scripts/manifest_fixer.py +++ b/scripts/manifest_fixer.py @@ -51,6 +51,9 @@ def parse_args(): help='specify additional 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 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 @@ def raise_min_sdk_version(doc, min_sdk_version, target_sdk_version, library): element.setAttributeNode(target_attr) +def add_logging_parent(doc, logging_parent_value): + """Add logging parent as an additional 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 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 tags @@ -291,6 +340,9 @@ def main(): 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 ea8095e48..d6e7f2674 100755 --- a/scripts/manifest_fixer_test.py +++ b/scripts/manifest_fixer_test.py @@ -226,6 +226,47 @@ class RaiseMinSdkVersionTest(unittest.TestCase): 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 = ( + '\n' + '\n' + '%s' + '\n') + + def uses_logging_parent(self, logging_parent=None): + attrs = '' + if logging_parent: + meta_text = ('\n') % (logging_parent) + attrs += ' \n %s \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."""