| # Copyright 2019 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| """Different build variants of chrome for android have different version codes. |
| Reason: for targets that have the same package name (e.g. chrome, chome |
| modern, monochrome, trichrome), Play Store considers them the same app |
| and will push the supported app with the highest version code to devices. |
| (note Play Store does not support hosting two different apps with same |
| version code and package name) |
| |
| Each key in this dict represents a unique version code that will be used for |
| one or more android chrome apks. |
| |
| Webview channels must have unique version codes for a couple reasons: |
| a) Play Store does not support having the same version code for different |
| versions of a package. Without unique codes, promoting a beta apk to stable |
| would require first removing the beta version. |
| b) Firebase project support (used by official builders) requires unique |
| [version code + package name]. |
| We cannot add new webview package names for new channels because webview |
| packages are whitelisted by Android as webview providers. |
| |
| WEBVIEW_STABLE, WEBVIEW_BETA, WEBVIEW_DEV are all used for standalone webview, |
| whereas the others are used for various chrome apks. |
| |
| Note that a final digit of '3' for webview is reserved for Trichrome Webview. |
| The same versionCode is used for both Trichrome Chrome and Trichrome Webview. |
| """ |
| ANDROID_CHROME_APK_VERSION_CODE_DIFFS = { |
| 'CHROME': 0, |
| 'CHROME_MODERN': 1, |
| 'MONOCHROME': 2, |
| 'TRICHROME': 3, |
| 'NOTOUCH_CHROME': 4, |
| 'WEBVIEW_STABLE': 0, |
| 'WEBVIEW_BETA': 1, |
| 'WEBVIEW_DEV': 2, |
| } |
| |
| """The architecture preference is encoded into the version_code for devices |
| that support multiple architectures. (exploiting play store logic that pushes |
| apk with highest version code) |
| |
| Detail: |
| Many Android devices support multiple architectures, and can run applications |
| built for any of them; the Play Store considers all of the supported |
| architectures compatible and does not, itself, have any preference for which |
| is "better". The common cases here: |
| |
| - All production arm64 devices can also run arm |
| - All production x64 devices can also run x86 |
| - Pretty much all production x86/x64 devices can also run arm (via a binary |
| translator) |
| |
| Since the Play Store has no particular preferences, you have to encode your own |
| preferences into the ordering of the version codes. There's a few relevant |
| things here: |
| |
| - For any android app, it's theoretically preferable to ship a 64-bit version to |
| 64-bit devices if it exists, because the 64-bit architectures are supposed to |
| be "better" than their 32-bit predecessors (unfortunately this is not always |
| true due to the effect on memory usage, but we currently deal with this by |
| simply not shipping a 64-bit version *at all* on the configurations where we |
| want the 32-bit version to be used). |
| - For any android app, it's definitely preferable to ship an x86 version to x86 |
| devices if it exists instead of an arm version, because running things through |
| the binary translator is a performance hit. |
| - For WebView, Monochrome, and Trichrome specifically, they are a special class |
| of APK called "multiarch" which means that they actually need to *use* more |
| than one architecture at runtime (rather than simply being compatible with |
| more than one). The 64-bit builds of these multiarch APKs contain both 32-bit |
| and 64-bit code, so that Webview is available for both ABIs. If you're |
| multiarch you *must* have a version that supports both 32-bit and 64-bit |
| version on a 64-bit device, otherwise it won't work properly. So, the 64-bit |
| version needs to be a higher versionCode, as otherwise a 64-bit device would |
| prefer the 32-bit version that does not include any 64-bit code, and fail. |
| - The relative order of mips isn't important, but it needs to be a *distinct* |
| value to the other architectures because all builds need unique version codes. |
| """ |
| ARCH_VERSION_CODE_DIFF = { |
| 'arm': 0, |
| 'x86': 10, |
| 'mipsel': 20, |
| 'arm64': 30, |
| 'x64': 60 |
| } |
| ARCH_CHOICES = ARCH_VERSION_CODE_DIFF.keys() |
| |
| """ "Next" builds get +5 last version code digit. |
| |
| We choose 5 because it won't conflict with values in |
| ANDROID_CHROME_APK_VERSION_CODE_DIFFS |
| """ |
| NEXT_BUILD_VERSION_CODE_DIFF = 5 |
| |
| """For 64-bit architectures, some packages have multiple targets with version |
| codes that differ by the second-to-last digit (the architecture digit). This is |
| for various combinations of 32-bit vs 64-bit chrome and webview. The |
| default/traditional configuration is 32-bit chrome with 64-bit webview, but we |
| are adding: |
| + 64-bit chrome with 32-bit webview |
| + 64-bit combined Chrome and Webview (only one library) |
| + (maybe someday 32-bit chrome with 32-bit webview) |
| |
| The naming scheme followed here is <chrome>_<webview>, |
| e.g. 64_32 is 64-bit chrome with 32-bit webview. |
| """ |
| ARCH64_APK_VARIANTS = { |
| '64_32': { |
| 'PACKAGES': frozenset(['MONOCHROME', 'TRICHROME']), |
| 'MODIFIER': 10 |
| }, |
| '64': { |
| 'PACKAGES': frozenset(['MONOCHROME', 'TRICHROME']), |
| 'MODIFIER': 20 |
| } |
| } |
| |
| |
| def GenerateVersionCodes(version_values, arch, is_next_build): |
| """Get dict of version codes for chrome-for-android-related targets |
| |
| e.g. |
| { |
| 'CHROME_VERSION_CODE': '378100010', |
| 'MONOCHROME_VERSION_CODE': '378100013', |
| ... |
| } |
| |
| versionCode values are built like this: |
| {full BUILD int}{3 digits for PATCH}{1 digit for architecture}{final digit}. |
| |
| MAJOR and MINOR values are not used for generating versionCode. |
| - MINOR is always 0. It was used for something long ago in Chrome's history |
| but has not been used since, and has never been nonzero on Android. |
| - MAJOR is cosmetic and controlled by the release managers. MAJOR and BUILD |
| always have reasonable sort ordering: for two version codes A and B, it's |
| always the case that (A.MAJOR < B.MAJOR) implies (A.BUILD < B.BUILD), and |
| that (A.MAJOR > B.MAJOR) implies (A.BUILD > B.BUILD). This property is just |
| maintained by the humans who set MAJOR. |
| |
| Thus, this method is responsible for the final two digits of versionCode. |
| """ |
| |
| base_version_code = '%s%03d00' % (version_values['BUILD'], |
| int(version_values['PATCH'])) |
| new_version_code = int(base_version_code) |
| |
| new_version_code += ARCH_VERSION_CODE_DIFF[arch] |
| if is_next_build: |
| new_version_code += NEXT_BUILD_VERSION_CODE_DIFF |
| |
| version_codes = {} |
| for apk, diff in ANDROID_CHROME_APK_VERSION_CODE_DIFFS.iteritems(): |
| version_code_name = apk + '_VERSION_CODE' |
| version_code_val = new_version_code + diff |
| version_codes[version_code_name] = str(version_code_val) |
| |
| if arch == 'arm64' or arch == 'x64': |
| for variant, config in ARCH64_APK_VARIANTS.iteritems(): |
| if apk in config['PACKAGES']: |
| variant_name = apk + '_' + variant + '_VERSION_CODE' |
| variant_val = version_code_val + config['MODIFIER'] |
| version_codes[variant_name] = str(variant_val) |
| |
| |
| return version_codes |