tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 747cf457f2e53f8961a829e7d0a23255e51483b8
parent 5f69ec3ff974cc330813df72e2209e87ad311e4a
Author: Georg Koppen <gk@torproject.org>
Date:   Tue, 13 Oct 2020 07:17:10 +0000

[android] Modify build system

Bug 40083: Make locale ordering in BuildConfig deterministic

Bug 40042: Add option do overwrite timestamp in extension version

Bug 40059: Use MOZ_BUILD_DATE for versionCode

At the same time we adapt MOZ_BUILD_DATE to our needs where it is
actually used and not in tor-browser-build. This gives us more
flexibility. See: tor-browser-build#40084.

Bug 40067: Fix reproducibility issue in classes2.dex

We make sure our MOZ_BUILD_DATE gets used as a source for showing date
related information on the Fenix about page.

Bug 40071: Show only supported locales

Bug 40064: Use Gecko Beta for Nightly and Debug variants

Bug 40123: Allow building the instrumented tests apks for variants other than debug

This allows to specify the variant of the instrumented tests via
a `testBuildType` gradle argument. It also applies a workaround for
a R8 issue from https://issuetracker.google.com/issues/140851070.

Bug 40143: Use deterministic date in Test apk

The build config was using Date() when generating the Test apk's
versionName.

Diffstat:
M.gitignore | 8++++++++
Mmobile/android/android-components/plugins/config/src/main/java/ConfigPlugin.kt | 9+++++++--
Mmobile/android/fenix/app/build.gradle | 28++++++++++++++++++++++++++--
Mmobile/android/fenix/app/proguard-rules.pro | 3+++
Mmobile/android/fenix/build.gradle | 2++
Amobile/android/fenix/tools/tba-fetch-deps.sh | 7+++++++
Amobile/android/fenix/tools/tba-sign-devbuilds.sh | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 130 insertions(+), 4 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -403,3 +403,11 @@ CLAUDE.local.md # Ignore binary base of Tor Browser .binaries + +# Other files modified at build time +mobile/android/.experimenter.json + +# Tor libraries for local builds +mobile/android/fenix/app/tor-expert-bundle.aar +mobile/android/fenix/app/src/main/assets/extensions/{73a6fe31-595d-460b-a920-fcc0f8843232}.xpi + diff --git a/mobile/android/android-components/plugins/config/src/main/java/ConfigPlugin.kt b/mobile/android/android-components/plugins/config/src/main/java/ConfigPlugin.kt @@ -21,7 +21,12 @@ object Config { @JvmStatic private fun generateDebugVersionName(): String { - val today = Date() + val today = if (System.getenv("MOZ_BUILD_DATE") != null) { + val format = SimpleDateFormat("yyyyMMddHHmmss", Locale.US) + format.parse(System.getenv("MOZ_BUILD_DATE")) + } else { + Date() + } // Append the year (2 digits) and week in year (2 digits). This will make it easier to distinguish versions and // identify ancient versions when debugging issues. However this will still keep the same version number during // the week so that we do not end up with a lot of versions in tools like Sentry. As an extra this matches the @@ -60,7 +65,7 @@ object Config { private val fennecBaseVersionCode by lazy { val format = SimpleDateFormat("yyyyMMddHHmmss", Locale.US) val cutoff = format.parse("20141228000000") - val build = Date() + val build = if (System.getenv("MOZ_BUILD_DATE") != null) format.parse(System.getenv("MOZ_BUILD_DATE")) else Date() Math.floor((build.time - cutoff.time) / (1000.0 * 60.0 * 60.0)).toInt() } diff --git a/mobile/android/fenix/app/build.gradle b/mobile/android/fenix/app/build.gradle @@ -61,7 +61,17 @@ def getBuildId() { return file("${gradle.mozconfig.topobjdir}/buildid.h").getText('utf-8').split()[2] } +def obtainTestBuildType() { + def result = "debug"; + if (project.hasProperty("testBuildType")) { + result = project.getProperties().get("testBuildType") + } + result +} + android { + testBuildType obtainTestBuildType() + project.maybeConfigForJetpackBenchmark(it) if (project.hasProperty("testBuildType")) { // Allowing to configure the test build type via command line flag (./gradlew -PtestBuildType=beta ..) @@ -314,12 +324,18 @@ android.applicationVariants.configureEach { variant -> def isDebugOrDCD = isDebug || isDataCollectionDisabled def useReleaseVersioning = variant.buildType.buildConfigFields['USE_RELEASE_VERSIONING']?.value ?: false + // When this is set, a-s doesn't attempt to download NIMBUS_FML. + if (gradle.mozconfig.substs.NIMBUS_FML) { + System.setProperty("nimbusFml", gradle.mozconfig.substs.NIMBUS_FML) + } + project.logger.debug("----------------------------------------------") project.logger.debug("Variant name: " + variant.name) project.logger.debug("Application ID: " + [variant.applicationId, variant.buildType.applicationIdSuffix].findAll().join()) project.logger.debug("Build type: " + variant.buildType.name) project.logger.debug("Flavor: " + variant.flavorName) project.logger.debug("Telemetry enabled: " + !isDebugOrDCD) + project.logger.debug("nimbusFml: " + System.getProperty("nimbusFml")) if (useReleaseVersioning) { // The Google Play Store does not allow multiple APKs for the same app that all have the @@ -916,16 +932,24 @@ def getSupportedLocales() { // This isn't running as a task, instead the array is build when the gradle file is parsed. // https://github.com/mozilla-mobile/fenix/issues/14175 def foundLocales = new StringBuilder() + def languageCodes = [] foundLocales.append("new String[]{") fileTree("src/main/res").visit { FileVisitDetails details -> - if (details.file.path.endsWith("${File.separator}strings.xml")) { + if (details.file.path.endsWith("${File.separator}torbrowser_strings.xml")) { def languageCode = details.file.parent.tokenize(File.separator).last().replaceAll('values-', '').replaceAll('-r', '-') languageCode = (languageCode == "values") ? "en-US" : languageCode - foundLocales.append("\"").append(languageCode).append("\"").append(",") + languageCodes.add(languageCode) } } + // The order of files in a `FileTree` is not stable, even on a single + // computer. Thus we need to sort the `languageCode`s. See: fenix#40083. + languageCodes.sort() + languageCodes.each { + foundLocales.append("\"").append(it).append("\"").append(",") + } + foundLocales.append("}") def foundLocalesString = foundLocales.toString().replaceAll(',}', '}') return foundLocalesString diff --git a/mobile/android/fenix/app/proguard-rules.pro b/mobile/android/fenix/app/proguard-rules.pro @@ -28,3 +28,6 @@ # Keep code generated from Glean Metrics -keep class org.mozilla.fenix.GleanMetrics.** { *; } + +# Workaround for 'already has mapping' r8 issue (https://issuetracker.google.com/issues/140851070) +-keep class com.google.android.gms.common.internal.BaseGmsClient { *; } diff --git a/mobile/android/fenix/build.gradle b/mobile/android/fenix/build.gradle @@ -8,6 +8,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile buildscript { // This logic is duplicated in the allprojects block: I don't know how to fix that. repositories { + mavenLocal() gradle.mozconfig.substs.GRADLE_MAVEN_REPOSITORIES.each { repository -> maven { url = repository @@ -42,6 +43,7 @@ plugins { allprojects { // This logic is duplicated in the buildscript block: I don't know how to fix that. repositories { + mavenLocal() gradle.mozconfig.substs.GRADLE_MAVEN_REPOSITORIES.each { repository -> maven { url = repository diff --git a/mobile/android/fenix/tools/tba-fetch-deps.sh b/mobile/android/fenix/tools/tba-fetch-deps.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +echo -e "\033[1;33mThis file is deprecated.\033[0m" +echo "Run ./mach bootstrap and/or define options in your mozconfig from now on." +echo "See documentation at: https://gitlab.torproject.org/tpo/applications/wiki/-/wikis/Development-Information/Firefox-Android/Building" + +exit 1 diff --git a/mobile/android/fenix/tools/tba-sign-devbuilds.sh b/mobile/android/fenix/tools/tba-sign-devbuilds.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +cd "$(dirname $(realpath "$0"))/.." + +objdir=$1 +if [ -z "$objdir" ]; then + echo "Usage $0 objdir" + exit 1 +fi + +if [ -z "$APKSIGNER_ARGS" ]; then + if [ -z "$QA_KEY" ]; then + if [ -z "$TOR_BROWSER_BUILD" ]; then + TOR_BROWSER_BUILD=../../../../tor-browser-build + fi + QA_KEY="$TOR_BROWSER_BUILD/projects/browser/android-qa.keystore" + fi + if [ ! -f "$QA_KEY" ]; then + echo "The QA key has not been found." + echo "Please define either \$QA_KEY with its path, or \$TOR_BROWSER_BUILD with the path to tor-browser-build" + exit 2 + fi + APKSIGNER_ARGS="--ks "$QA_KEY" --ks-key-alias androidqakey --key-pass pass:android --ks-pass pass:android" +fi + +if [ -z "$ANDROID_HOME" ]; then + ANDROID_HOME=~/Android +fi + +function find_tool() { + tool="$(find $ANDROID_HOME -name "$1" | head -1)" + if [ -z "$tool" ]; then + tool=$(which $1) + fi + echo $tool +} + +apksigner="$(find_tool apksigner)" +zipalign="$(find_tool zipalign)" +if [ -z "$apksigner" -o ! -x "$apksigner" -o -z "$zipalign" -o ! -x "$zipalign" ]; then + echo "apksigner or zipalign not found." + echo "Please make sure they are on your \$PATH, or define \$ANDROID_HOME." + exit 3 +fi + +noscript="$(find "$TOR_BROWSER_BUILD/out/browser" -name 'noscript*.xpi' -print | sort | tail -1)" +tmpdir="$(mktemp -d)" +mkdir -p "$tmpdir/assets/extensions" +if [ -f "$noscript" ]; then + cp "$noscript" "$tmpdir/assets/extensions/{73a6fe31-595d-460b-a920-fcc0f8843232}.xpi" +fi + +sign () { + apk="$(realpath $1)" + out="$apk" + if [ ! -f "$apk" ]; then + return + fi + out="${out/unsigned/signed}" + aligned="$apk" + aligned="${aligned/unsigned/aligned}" + pushd "$tmpdir" > /dev/null + zip -Xr "$apk" assets > /dev/null + popd > /dev/null + rm -f "$aligned" + "$zipalign" -p 4 "$apk" "$aligned" + echo "Signing $out" + "$apksigner" sign --in "$aligned" --out "$out" $APKSIGNER_ARGS +} + +for channel in "$objdir/gradle/build/mobile/android/fenix/app/outputs/apk/fenix/"*; do + for apk in $channel/*-unsigned.apk; do + sign "$apk" + done +done + +rm -rf "$tmpdir"