From 69cf0f375687f936c1832bc7c049e8b105304abb Mon Sep 17 00:00:00 2001 From: Alexei Nicoara Date: Wed, 27 Jul 2022 14:59:18 +0100 Subject: [PATCH] Overriding placeholder version in updatable apks Test: presubmit, checked the app version after build locally Bug: 231691162 Change-Id: Icd242432540ea424235b226a45aac839dbc995be --- java/aar.go | 18 ++++++++++-------- java/android_manifest.go | 22 +++++++++++++--------- java/app.go | 3 +++ scripts/manifest_fixer.py | 18 ++++++++++++++++++ scripts/manifest_fixer_test.py | 34 ++++++++++++++++++++++++++++++++++ 5 files changed, 78 insertions(+), 17 deletions(-) diff --git a/java/aar.go b/java/aar.go index dadfc6a6f..e13ccb3bb 100644 --- a/java/aar.go +++ b/java/aar.go @@ -105,6 +105,7 @@ type aapt struct { noticeFile android.OptionalPath assetPackage android.OptionalPath isLibrary bool + defaultManifestVersion string useEmbeddedNativeLibs bool useEmbeddedDex bool usesNonSdkApis bool @@ -281,14 +282,15 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon manifestSrcPath := android.PathForModuleSrc(ctx, manifestFile) manifestPath := ManifestFixer(ctx, manifestSrcPath, ManifestFixerParams{ - SdkContext: sdkContext, - ClassLoaderContexts: classLoaderContexts, - IsLibrary: a.isLibrary, - UseEmbeddedNativeLibs: a.useEmbeddedNativeLibs, - UsesNonSdkApis: a.usesNonSdkApis, - UseEmbeddedDex: a.useEmbeddedDex, - HasNoCode: a.hasNoCode, - LoggingParent: a.LoggingParent, + SdkContext: sdkContext, + ClassLoaderContexts: classLoaderContexts, + IsLibrary: a.isLibrary, + DefaultManifestVersion: a.defaultManifestVersion, + UseEmbeddedNativeLibs: a.useEmbeddedNativeLibs, + UsesNonSdkApis: a.usesNonSdkApis, + UseEmbeddedDex: a.useEmbeddedDex, + HasNoCode: a.hasNoCode, + LoggingParent: a.LoggingParent, }) // Add additional manifest files to transitive manifests. diff --git a/java/android_manifest.go b/java/android_manifest.go index c61823d06..83cb171c6 100644 --- a/java/android_manifest.go +++ b/java/android_manifest.go @@ -56,15 +56,16 @@ func targetSdkVersionForManifestFixer(ctx android.ModuleContext, sdkContext andr } type ManifestFixerParams struct { - SdkContext android.SdkContext - ClassLoaderContexts dexpreopt.ClassLoaderContextMap - IsLibrary bool - UseEmbeddedNativeLibs bool - UsesNonSdkApis bool - UseEmbeddedDex bool - HasNoCode bool - TestOnly bool - LoggingParent string + SdkContext android.SdkContext + ClassLoaderContexts dexpreopt.ClassLoaderContextMap + IsLibrary bool + DefaultManifestVersion string + UseEmbeddedNativeLibs bool + UsesNonSdkApis bool + UseEmbeddedDex bool + HasNoCode bool + TestOnly bool + LoggingParent string } // Uses manifest_fixer.py to inject minSdkVersion, etc. into an AndroidManifest.xml @@ -153,6 +154,9 @@ func ManifestFixer(ctx android.ModuleContext, manifest android.Path, args = append(args, "--replaceMaxSdkVersionPlaceholder ", strconv.Itoa(replaceMaxSdkVersionPlaceholder.FinalOrFutureInt())) args = append(args, "--raise-min-sdk-version") } + if params.DefaultManifestVersion != "" { + args = append(args, "--override-placeholder-version", params.DefaultManifestVersion) + } fixedManifest := android.PathForModuleOut(ctx, "manifest_fixer", "AndroidManifest.xml") argsMapper["args"] = strings.Join(args, " ") diff --git a/java/app.go b/java/app.go index 23a9816b4..24f269c68 100755 --- a/java/app.go +++ b/java/app.go @@ -417,6 +417,9 @@ func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) { a.aapt.splitNames = a.appProperties.Package_splits a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent) + if a.Updatable() { + a.aapt.defaultManifestVersion = android.DefaultUpdatableModuleVersion + } a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts, a.usesLibraryProperties.Exclude_uses_libs, aaptLinkFlags...) diff --git a/scripts/manifest_fixer.py b/scripts/manifest_fixer.py index 2da29ee91..58079aa5d 100755 --- a/scripts/manifest_fixer.py +++ b/scripts/manifest_fixer.py @@ -70,6 +70,8 @@ def parse_args(): parser.add_argument('--test-only', dest='test_only', action='store_true', help=('adds testOnly="true" attribute to application. Assign true value if application elem ' 'already has a testOnly attribute.')) + parser.add_argument('--override-placeholder-version', dest='new_version', + help='Overrides the versionCode if it\'s set to the placeholder value of 0') parser.add_argument('input', help='input AndroidManifest.xml file') parser.add_argument('output', help='output AndroidManifest.xml file') return parser.parse_args() @@ -362,6 +364,19 @@ def set_max_sdk_version(doc, max_sdk_version): if max_attr and max_attr.value == 'current': max_attr.value = max_sdk_version +def override_placeholder_version(doc, new_version): + """Replace the versionCode attribute value if it\'s currently + set to the placeholder version of 0. + + Args: + doc: The XML document. May be modified by this function. + new_version: The new version to set if versionCode is equal to 0. + """ + manifest = parse_manifest(doc) + version = manifest.getAttribute("android:versionCode") + if (version == '0'): + manifest.setAttribute("android:versionCode", new_version) + def main(): """Program entry point.""" try: @@ -401,6 +416,9 @@ def main(): if args.extract_native_libs is not None: add_extract_native_libs(doc, args.extract_native_libs) + if args.new_version: + override_placeholder_version(doc, args.new_version) + with open(args.output, 'w') as f: write_xml(f, doc) diff --git a/scripts/manifest_fixer_test.py b/scripts/manifest_fixer_test.py index dad104a54..0a62b10a4 100755 --- a/scripts/manifest_fixer_test.py +++ b/scripts/manifest_fixer_test.py @@ -643,5 +643,39 @@ class SetMaxSdkVersionTest(unittest.TestCase): output = self.run_test(manifest_input, '9000') self.assert_xml_equal(output, expected) +class OverrideDefaultVersionTest(unittest.TestCase): + """Unit tests for override_default_version function.""" + + def assert_xml_equal(self, output, expected): + self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected)) + + def run_test(self, input_manifest, version): + doc = minidom.parseString(input_manifest) + manifest_fixer.override_placeholder_version(doc, version) + output = io.StringIO() + manifest_fixer.write_xml(output, doc) + return output.getvalue() + + manifest_tmpl = ( + '\n' + '\n' + '\n') + + def test_doesnt_override_existing_version(self): + """Tests that an existing version is not overridden""" + manifest_input = self.manifest_tmpl % '12345' + expected = manifest_input + output = self.run_test(manifest_input, '67890') + self.assert_xml_equal(output, expected) + + def test_overrides_default_version(self): + """Tests that a default version is overridden""" + manifest_input = self.manifest_tmpl % '0' + expected = self.manifest_tmpl % '67890' + output = self.run_test(manifest_input, '67890') + self.assert_xml_equal(output, expected) + + if __name__ == '__main__': unittest.main(verbosity=2)