Overriding placeholder version in updatable apks

Test: presubmit, checked the app version after build locally
Bug: 231691162
Change-Id: Icd242432540ea424235b226a45aac839dbc995be
This commit is contained in:
Alexei Nicoara 2022-07-27 14:59:18 +01:00
parent 950f28abe2
commit 69cf0f3756
5 changed files with 78 additions and 17 deletions

View file

@ -105,6 +105,7 @@ type aapt struct {
noticeFile android.OptionalPath noticeFile android.OptionalPath
assetPackage android.OptionalPath assetPackage android.OptionalPath
isLibrary bool isLibrary bool
defaultManifestVersion string
useEmbeddedNativeLibs bool useEmbeddedNativeLibs bool
useEmbeddedDex bool useEmbeddedDex bool
usesNonSdkApis bool usesNonSdkApis bool
@ -281,14 +282,15 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon
manifestSrcPath := android.PathForModuleSrc(ctx, manifestFile) manifestSrcPath := android.PathForModuleSrc(ctx, manifestFile)
manifestPath := ManifestFixer(ctx, manifestSrcPath, ManifestFixerParams{ manifestPath := ManifestFixer(ctx, manifestSrcPath, ManifestFixerParams{
SdkContext: sdkContext, SdkContext: sdkContext,
ClassLoaderContexts: classLoaderContexts, ClassLoaderContexts: classLoaderContexts,
IsLibrary: a.isLibrary, IsLibrary: a.isLibrary,
UseEmbeddedNativeLibs: a.useEmbeddedNativeLibs, DefaultManifestVersion: a.defaultManifestVersion,
UsesNonSdkApis: a.usesNonSdkApis, UseEmbeddedNativeLibs: a.useEmbeddedNativeLibs,
UseEmbeddedDex: a.useEmbeddedDex, UsesNonSdkApis: a.usesNonSdkApis,
HasNoCode: a.hasNoCode, UseEmbeddedDex: a.useEmbeddedDex,
LoggingParent: a.LoggingParent, HasNoCode: a.hasNoCode,
LoggingParent: a.LoggingParent,
}) })
// Add additional manifest files to transitive manifests. // Add additional manifest files to transitive manifests.

View file

@ -56,15 +56,16 @@ func targetSdkVersionForManifestFixer(ctx android.ModuleContext, sdkContext andr
} }
type ManifestFixerParams struct { type ManifestFixerParams struct {
SdkContext android.SdkContext SdkContext android.SdkContext
ClassLoaderContexts dexpreopt.ClassLoaderContextMap ClassLoaderContexts dexpreopt.ClassLoaderContextMap
IsLibrary bool IsLibrary bool
UseEmbeddedNativeLibs bool DefaultManifestVersion string
UsesNonSdkApis bool UseEmbeddedNativeLibs bool
UseEmbeddedDex bool UsesNonSdkApis bool
HasNoCode bool UseEmbeddedDex bool
TestOnly bool HasNoCode bool
LoggingParent string TestOnly bool
LoggingParent string
} }
// Uses manifest_fixer.py to inject minSdkVersion, etc. into an AndroidManifest.xml // 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, "--replaceMaxSdkVersionPlaceholder ", strconv.Itoa(replaceMaxSdkVersionPlaceholder.FinalOrFutureInt()))
args = append(args, "--raise-min-sdk-version") 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") fixedManifest := android.PathForModuleOut(ctx, "manifest_fixer", "AndroidManifest.xml")
argsMapper["args"] = strings.Join(args, " ") argsMapper["args"] = strings.Join(args, " ")

View file

@ -417,6 +417,9 @@ func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
a.aapt.splitNames = a.appProperties.Package_splits a.aapt.splitNames = a.appProperties.Package_splits
a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent) 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.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts,
a.usesLibraryProperties.Exclude_uses_libs, aaptLinkFlags...) a.usesLibraryProperties.Exclude_uses_libs, aaptLinkFlags...)

View file

@ -70,6 +70,8 @@ def parse_args():
parser.add_argument('--test-only', dest='test_only', action='store_true', parser.add_argument('--test-only', dest='test_only', action='store_true',
help=('adds testOnly="true" attribute to application. Assign true value if application elem ' help=('adds testOnly="true" attribute to application. Assign true value if application elem '
'already has a testOnly attribute.')) '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('input', help='input AndroidManifest.xml file')
parser.add_argument('output', help='output AndroidManifest.xml file') parser.add_argument('output', help='output AndroidManifest.xml file')
return parser.parse_args() 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': if max_attr and max_attr.value == 'current':
max_attr.value = max_sdk_version 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(): def main():
"""Program entry point.""" """Program entry point."""
try: try:
@ -401,6 +416,9 @@ def main():
if args.extract_native_libs is not None: if args.extract_native_libs is not None:
add_extract_native_libs(doc, args.extract_native_libs) 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: with open(args.output, 'w') as f:
write_xml(f, doc) write_xml(f, doc)

View file

@ -643,5 +643,39 @@ class SetMaxSdkVersionTest(unittest.TestCase):
output = self.run_test(manifest_input, '9000') output = self.run_test(manifest_input, '9000')
self.assert_xml_equal(output, expected) 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 = (
'<?xml version="1.0" encoding="utf-8"?>\n'
'<manifest xmlns:android="http://schemas.android.com/apk/res/android" '
'android:versionCode="%s">\n'
'</manifest>\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__': if __name__ == '__main__':
unittest.main(verbosity=2) unittest.main(verbosity=2)