prebuild.sh raw

   1  #!/bin/bash
   2  #
   3  #    Fennec build scripts
   4  #    Copyright (C) 2020-2024  Matías Zúñiga, Andrew Nayenko, Tavi
   5  #
   6  #    This program is free software: you can redistribute it and/or modify
   7  #    it under the terms of the GNU Affero General Public License as
   8  #    published by the Free Software Foundation, either version 3 of the
   9  #    License, or (at your option) any later version.
  10  #
  11  #    This program is distributed in the hope that it will be useful,
  12  #    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13  #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14  #    GNU Affero General Public License for more details.
  15  #
  16  #    You should have received a copy of the GNU Affero General Public License
  17  #    along with this program.  If not, see <https://www.gnu.org/licenses/>.
  18  #
  19  
  20  set -e
  21  
  22  if [ -z "$1" ] || [ -z "$2" ]; then
  23      echo "Usage: $0 versionName versionCode" >&1
  24      exit 1
  25  fi
  26  
  27  # shellcheck source=paths.sh
  28  source "$(dirname "$0")/paths.sh"
  29  
  30  function localize_maven {
  31      # Replace custom Maven repositories with mavenLocal()
  32      find ./* -name '*.gradle' -type f -print0 | xargs -0 \
  33          sed -n -i \
  34              -e '/maven {/{:loop;N;/}$/!b loop;/plugins.gradle.org/!s/maven .*/mavenLocal()/};p'
  35      # Make gradlew scripts call our Gradle wrapper
  36      find ./* -name gradlew -type f | while read -r gradlew; do
  37          echo -e '#!/bin/sh\ngradle "$@"' > "$gradlew"
  38          chmod 755 "$gradlew"
  39      done
  40  }
  41  
  42  function apply_patch {
  43      echo "Apply $1"
  44      patch -p1 --no-backup-if-mismatch --quiet < "$1"
  45  }
  46  
  47  # Set up Rust
  48  rustup default 1.93.0
  49  
  50  #
  51  # Fenix
  52  #
  53  
  54  pushd "$fenix"
  55  
  56  # Set up the app ID, version name and version code
  57  sed -i \
  58      -e 's|org\.mozilla\.firefox|lol.smesh.felice|' \
  59      -e "s/Config.releaseVersionName(project)/'$1'/" \
  60      -e "s/Config.generateFennecVersionCode(abi)/$2/" \
  61      app/build.gradle
  62  sed -i \
  63      -e '/android:targetPackage/s/org\.mozilla\.firefox/lol.smesh.felice/' \
  64      app/src/release/res/xml/shortcuts.xml
  65  
  66  # Disable crash reporting
  67  sed -i -e '/CRASH_REPORTING/s/true/false/' app/build.gradle
  68  
  69  # Disable MetricController
  70  sed -i -e '/TELEMETRY/s/true/false/' app/build.gradle
  71  
  72  # Let it be Felice
  73  sed -i -e 's/Firefox Daylight/Felice/; s/Firefox/Felice/g' \
  74      app/src/*/res/values*/*strings.xml
  75  
  76  # Fenix uses reflection to create a instance of profile based on the text of
  77  # the label, see
  78  # app/src/main/java/org/mozilla/fenix/perf/ProfilerStartDialogFragment.kt#185
  79  sed -i \
  80      -e 's/ProfilerSettings.Firefox/ProfilerSettings.Felice/' \
  81      app/src/main/java/org/mozilla/fenix/perf/ProfilerStartDialogFragment.kt
  82  sed -i \
  83      -e '/Firefox(.*, .*)/s/Firefox/Felice/' \
  84      -e 's/firefox_threads/felice_threads/' \
  85      -e 's/firefox_features/felice_features/' \
  86      app/src/main/java/org/mozilla/fenix/perf/ProfilerUtils.kt
  87  
  88  # Replace proprietary artwork
  89  sed -i -e 's|@drawable/animated_splash_screen<|@drawable/splash_screen<|' \
  90      app/src/main/res/values-v*/styles.xml
  91  find "$patches/fenix-overlay" -type f | while read -r src; do
  92      dst=app/src/release/${src#"$patches/fenix-overlay/"}
  93      mkdir -p "$(dirname "$dst")"
  94      cp "$src" "$dst"
  95  done
  96  # Drop the Fennec fox vector; the release overlay provides Felice webps at every density
  97  rm -f app/src/main/res/drawable/ic_firefox.xml
  98  
  99  # Route completed .xpi downloads into AddonManager instead of the download-complete snackbar
 100  sed -i \
 101      -e '/^import org\.mozilla\.fenix\.components\.AppStore$/a\
 102  import org.mozilla.fenix.ext.components' \
 103      -e '/\/\/ If the download is just paused/i\
 104      if (downloadJobStatus == Status.COMPLETED \&\&\
 105          (downloadState.contentType == "application\/x-xpinstall" ||\
 106           downloadState.fileName?.endsWith(".xpi") == true)) {\
 107          val safeContext = context ?: return\
 108          val fileUri = "file:\/\/" + downloadState.filePath\
 109          safeContext.components.addonManager.installAddon(\
 110              fileUri,\
 111              mozilla.components.concept.engine.webextension.InstallationMethod.FROM_FILE,\
 112              onSuccess = { },\
 113              onError = { _ -> },\
 114          )\
 115          return\
 116      }\
 117  ' app/src/main/java/org/mozilla/fenix/browser/DownloadUtils.kt
 118  
 119  # Register as handler for .xpi extension files
 120  sed -i '/<action android:name="android.intent.action.SEND" \/>/i\
 121          <intent-filter>\
 122              <action android:name="android.intent.action.VIEW" \/>\
 123              <category android:name="android.intent.category.BROWSABLE" \/>\
 124              <category android:name="android.intent.category.DEFAULT" \/>\
 125              <data android:scheme="http" \/>\
 126              <data android:scheme="https" \/>\
 127              <data android:mimeType="application\/x-xpinstall" \/>\
 128          <\/intent-filter>\
 129  \
 130          <intent-filter>\
 131              <action android:name="android.intent.action.VIEW" \/>\
 132              <category android:name="android.intent.category.BROWSABLE" \/>\
 133              <category android:name="android.intent.category.DEFAULT" \/>\
 134              <data android:scheme="content" \/>\
 135              <data android:scheme="file" \/>\
 136              <data android:mimeType="application\/x-xpinstall" \/>\
 137          <\/intent-filter>\
 138  \
 139          <intent-filter>\
 140              <action android:name="android.intent.action.VIEW" \/>\
 141              <category android:name="android.intent.category.BROWSABLE" \/>\
 142              <category android:name="android.intent.category.DEFAULT" \/>\
 143              <data android:scheme="content" \/>\
 144              <data android:scheme="file" \/>\
 145              <data android:host="*" \/>\
 146              <data android:pathPattern=".*\\\\.xpi" \/>\
 147          <\/intent-filter>\
 148  ' app/src/main/AndroidManifest.xml
 149  
 150  # There are a lot of "No cast needed" warnings in the generated code
 151  sed -i -e '/compilerOptions.allWarningsAsErrors/s/true/false/' build.gradle
 152  
 153  # Enable about:config
 154  sed -i \
 155      -e 's/aboutConfigEnabled(.*)/aboutConfigEnabled(true)/' \
 156      app/src/*/java/org/mozilla/fenix/*/GeckoProvider.kt
 157  
 158  # Disable remote improvements by default
 159  sed -i \
 160      -e '/android:defaultValue=/s/"true"/"false"/' \
 161      app/src/main/res/xml/remote_improvements_preferences.xml
 162  
 163  # Add wallpaper URL
 164  echo 'https://gitlab.com/relan/fennecmedia/-/raw/master/wallpapers/android' > .wallpaper_url
 165  
 166  # Set up target parameters
 167  case $(echo "$2" | cut -c 6) in
 168      0)
 169          abi=armeabi-v7a
 170          target=arm-linux-androideabi
 171          echo "ARM" > "$llvm/targets_to_build"
 172          rusttarget=arm
 173          rustup target add thumbv7neon-linux-androideabi
 174          rustup target add armv7-linux-androideabi
 175          ;;
 176      1)
 177          abi=x86_64
 178          target=x86_64-linux-android
 179          echo "X86" > "$llvm/targets_to_build"
 180          rusttarget=x86_64
 181          rustup target add x86_64-linux-android
 182          ;;
 183      2)
 184          abi=arm64-v8a
 185          target=aarch64-linux-android
 186          echo "AArch64" > "$llvm/targets_to_build"
 187          rusttarget=arm64
 188          rustup target add aarch64-linux-android
 189          ;;
 190      *)
 191          echo "Unknown target code in $2." >&2
 192          exit 1
 193      ;;
 194  esac
 195  sed -i -e "s/include \".*\"/include \"$abi\"/" app/build.gradle
 196  
 197  # Disable FUS Service or we'll get errors like:
 198  # Exception while loading configuration for :app: Could not load the value of field `__buildFusService__` of task `:app:compileFenixReleaseKotlin` of type `org.jetbrains.kotlin.gradle.tasks.KotlinCompile`.
 199  echo "kotlin.internal.collectFUSMetrics=false" >> local.properties
 200  
 201  popd
 202  
 203  #
 204  # Glean
 205  #
 206  
 207  pushd "$glean"
 208  echo "rust.targets=linux-x86-64,$rusttarget" >> local.properties
 209  localize_maven
 210  popd
 211  
 212  #
 213  # Glean for Application Services
 214  #
 215  
 216  pushd "$glean_as"
 217  echo "rust.targets=linux-x86-64,$rusttarget" >> local.properties
 218  localize_maven
 219  popd
 220  
 221  #
 222  # Android Components
 223  #
 224  
 225  pushd "$android_components"
 226  find "$patches/a-c-overlay" -type f | while read -r src; do
 227      cp "$src" "${src#"$patches/a-c-overlay/"}"
 228  done
 229  # Add the added search engines as `general` engines
 230  sed -i \
 231      -e '/GENERAL_SEARCH_ENGINE_IDS = setOf/a\    "brave",' \
 232      -e '/GENERAL_SEARCH_ENGINE_IDS = setOf/a\    "ddghtml",' \
 233      -e '/GENERAL_SEARCH_ENGINE_IDS = setOf/a\    "ddglite",' \
 234      -e '/GENERAL_SEARCH_ENGINE_IDS = setOf/a\    "metager",' \
 235      -e '/GENERAL_SEARCH_ENGINE_IDS = setOf/a\    "mojeek",' \
 236      -e '/GENERAL_SEARCH_ENGINE_IDS = setOf/a\    "qwantlite",' \
 237      -e '/GENERAL_SEARCH_ENGINE_IDS = setOf/a\    "startpage",' \
 238      components/feature/search/src/main/java/mozilla/components/feature/search/storage/SearchEngineReader.kt
 239  popd
 240  
 241  #
 242  # UnifiedPush Android Component
 243  #
 244  
 245  pushd "$unifiedpush_ac"
 246  localize_maven
 247  # Set A-C version
 248  echo "mozilla.version=${1%.0}" >> local.properties
 249  # Set A-S version
 250  sed -i -e 's/0.0.1-SNAPSHOT-+/149.0/' gradle/libs.versions.toml
 251  popd
 252  
 253  #
 254  # Application Services
 255  #
 256  
 257  pushd "$application_services"
 258  rm -vrf components/remote_settings/dumps/*/attachments/search-config-icons/*
 259  find "$patches/a-s-overlay" -type f | while read -r src; do
 260      cp "$src" "${src#"$patches/a-s-overlay/"}"
 261  done
 262  # Remove Mozilla repositories substitution and explicitly add the required ones
 263  apply_patch "$patches/a-s-localize_maven.patch"
 264  # Configure default search engines
 265  apply_patch "$patches/a-s-configure-default-search-engines.patch"
 266  # Break the dependency on older A-C
 267  sed -i -e '/android-components = /s/"146\.0\.1"/"149.0"/' gradle/libs.versions.toml
 268  echo "rust.targets=linux-x86-64,$rusttarget" >> local.properties
 269  sed -i -e '/NDK ez-install/,/^$/d' libs/verify-android-ci-environment.sh
 270  popd
 271  
 272  #
 273  # WASI SDK
 274  #
 275  
 276  pushd "$wasi"
 277  apply_patch "$mozilla_release/taskcluster/scripts/misc/wasi-sdk.patch"
 278  popd
 279  
 280  #
 281  # GeckoView
 282  #
 283  
 284  pushd "$mozilla_release"
 285  
 286  # Remove unneeded dependecies
 287  apply_patch "$patches/gecko-dependencies.patch"
 288  
 289  # Remove Mozilla repositories substitution and explicitly add the required ones
 290  apply_patch "$patches/gecko-localize_maven.patch"
 291  
 292  # Replace GMS with microG client library
 293  apply_patch "$patches/gecko-liberate.patch"
 294  
 295  # Work-around upstream bug to fix compilation with WASI SDK 20, see
 296  # https://bugzilla.mozilla.org/show_bug.cgi?id=1994063
 297  apply_patch "$patches/gecko-unbreak-wasi-sdk-20-clang.patch"
 298  
 299  # Add UnifiedPush support
 300  apply_patch "$unifiedpush_ac/patches/a-c-unifiedpush.patch"
 301  apply_patch "$unifiedpush_ac/patches/fenix-unifiedpush.patch"
 302  
 303  # Patch the use of proprietary and tracking libraries
 304  apply_patch "$patches/fenix-liberate.patch"
 305  
 306  # Disable search engines configuration fetching from a Mozilla server
 307  apply_patch "$patches/fenix-disable-remote-search-configuration.patch"
 308  sed -i 's|https://firefox.settings.services.allizom.org/v1/buckets/main/collections/search-config/records||g' toolkit/components/search/SearchUtils.sys.mjs
 309  sed -i 's|https://firefox.settings.services.allizom.org/v1/buckets/main-preview/collections/search-config/records||g' toolkit/components/search/SearchUtils.sys.mjs
 310  sed -i 's|https://firefox.settings.services.mozilla.com/v1/buckets/main/collections/search-config/records||g' toolkit/components/search/SearchUtils.sys.mjs
 311  sed -i 's|https://firefox.settings.services.mozilla.com/v1/buckets/main-preview/collections/search-config/records||g' toolkit/components/search/SearchUtils.sys.mjs
 312  
 313  # Remove the use of RemoteSettingsCrashPull, the part of the crash reporter
 314  apply_patch "$patches/fenix-disable-crashpull.patch"
 315  
 316  # Remove "Sent from Firefox" reference on sharing
 317  apply_patch "$patches/fenix-disable-sent-from-fx.patch"
 318  
 319  # Add "Enable UnifiedPush" and "Use UnifiedPush" settings
 320  apply_patch "$patches/fenix-use-unifiedpush.patch"
 321  
 322  # Fail on use of prebuilt binary
 323  sed -i 's|https://|hxxps://|' mobile/android/gradle/plugins/nimbus-gradle-plugin/src/main/groovy/org/mozilla/appservices/tooling/nimbus/NimbusGradlePlugin.groovy
 324  
 325  # Make Nimbus Gradle Plugin use obj/dist/host/bin/nimbus-fml which we copy
 326  # there manually from A-S. Otherwise Nimbus Gradle Plugin tries to download
 327  # nimbus-fml from Mozilla.
 328  sed -i 's/project.gradle.ext.mozconfig.substs.MOZ_APPSERVICES_IN_TREE/true/' mobile/android/gradle/plugins/nimbus-gradle-plugin/src/main/groovy/org/mozilla/appservices/tooling/nimbus/NimbusGradlePlugin.groovy
 329  
 330  # Fix v125 aar output not including native libraries
 331  sed -i \
 332      -e 's/singleVariant("debug")/singleVariant("release")/' \
 333      mobile/android/exoplayer2/build.gradle
 334  sed -i \
 335      -e "s/singleVariant('debug')/singleVariant('release')/" \
 336      mobile/android/geckoview/build.gradle
 337  
 338  # Hack the timeout for
 339  # geckoview:generateJNIWrappersForGeneratedWithGeckoBinariesDebug
 340  sed -i \
 341      -e 's/max_wait_seconds=600/max_wait_seconds=1800/' \
 342      mobile/android/gradle.py
 343  
 344  # Patch the LLVM source code
 345  # Search clang- in https://android.googlesource.com/platform/ndk/+/refs/tags/ndk-r28b/ndk/toolchains.py
 346  LLVM_SVN='530567'
 347  python3 "$toolchain_utils/llvm_tools/patch_manager.py" \
 348      --svn_version "$LLVM_SVN" \
 349      --patch_metadata_file "$llvm_android/patches/PATCHES.json" \
 350      --src_path "$llvm"
 351  
 352  # Fail on use of prebuilt binary
 353  sed -i 's|https://github.com|hxxps://github.com|' python/mozboot/mozboot/android.py
 354  
 355  # Make the build system think we installed the emulator and an AVD
 356  mkdir -p "$ANDROID_HOME/emulator"
 357  touch "$ANDROID_HOME/emulator/emulator"
 358  chmod +x "$ANDROID_HOME/emulator/emulator"
 359  mkdir -p "$HOME/.mozbuild/android-device/avd"
 360  
 361  # Use terser from Debian
 362  sed -i \
 363      -e 's|terser_path = terser_dir / ".*"|terser_path = Path("/usr/bin/terser")|' \
 364      python/mozbuild/mozpack/files.py
 365  
 366  # Configure
 367  cat << EOF > mozconfig
 368  ac_add_options --disable-crashreporter
 369  ac_add_options --disable-debug
 370  ac_add_options --disable-tests
 371  ac_add_options --disable-updater
 372  ac_add_options --enable-application=mobile/android
 373  ac_add_options --enable-release
 374  ac_add_options --enable-update-channel=release
 375  ac_add_options --target=$target
 376  ac_add_options --with-android-ndk="$ANDROID_NDK"
 377  ac_add_options --with-android-sdk="$ANDROID_SDK"
 378  ac_add_options --with-libclang-path="$llvm/out/lib"
 379  ac_add_options --with-java-bin-path="/usr/bin"
 380  ac_add_options --with-gradle=$(command -v gradle)
 381  ac_add_options --with-wasi-sysroot="$wasi/build/install/wasi/share/wasi-sysroot"
 382  ac_add_options CC="$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/clang"
 383  ac_add_options CXX="$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++"
 384  ac_add_options STRIP="$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip"
 385  ac_add_options WASM_CC="$wasi/build/install/wasi/bin/clang"
 386  ac_add_options WASM_CXX="$wasi/build/install/wasi/bin/clang++"
 387  mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj
 388  mk_add_options MOZ_MAKE_FLAGS="-j1"
 389  export MOZ_REQUIRE_SIGNING=
 390  EOF
 391  
 392  # Disable Gecko Media Plugins and casting
 393  sed -i -e '/gmp-provider/d; /casting.enabled/d' mobile/android/app/geckoview-prefs.js
 394  cat << EOF >> mobile/android/app/geckoview-prefs.js
 395  
 396  // Disable Encrypted Media Extensions
 397  pref("media.eme.enabled", false);
 398  
 399  // Disable Gecko Media Plugins
 400  pref("media.gmp-provider.enabled", false);
 401  
 402  // Avoid openh264 being downloaded
 403  pref("media.gmp-manager.url.override", "data:text/plain,");
 404  
 405  // Disable openh264 if it is already downloaded
 406  pref("media.gmp-gmpopenh264.enabled", false);
 407  
 408  // Disable RemoteSettingsCrashPull
 409  pref("browser.crashReports.crashPull", false, locked);
 410  pref("browser.crashReports.requestedNeverShowAgain", true, locked);
 411  
 412  // Disable mandatory extension signing
 413  pref("xpinstall.signatures.required", false);
 414  
 415  // Allow extension installs from any site
 416  pref("xpinstall.whitelist.fileRequest", true);
 417  pref("extensions.langpacks.signatures.required", false);
 418  pref("extensions.experiments.enabled", true);
 419  pref("extensions.install.requireBuiltInCerts", false);
 420  pref("extensions.webextensions.restrictedDomains", "");
 421  pref("xpinstall.whitelist.required", false);
 422  pref("xpinstall.whitelist.directRequest", true);
 423  
 424  pref("browser.startup.homepage_override.mstone", "ignore");
 425  EOF
 426  
 427  popd
 428  
 429  # On cold start with no tabs to restore and no intent URL, open smesh.lol.
 430  # Fenix ignores browser.startup.homepage on Android — this is the only way.
 431  sed -i '/maybeShowSetAsDefaultBrowserPrompt()$/i\
 432                  if (!settings().shouldReturnToBrowser) {\
 433                      openToBrowserAndLoad(\
 434                          searchTermOrURL = "https:\/\/smesh.lol",\
 435                          newTab = true,\
 436                          from = BrowserDirection.FromGlobal,\
 437                      )\
 438                  }' "$fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt"
 439