LeOSium-WF/app/build.gradle

686 lines
27 KiB
Groovy
Raw Permalink Normal View History

2024-12-12 08:45:34 +01:00
import com.android.build.OutputFile
import groovy.json.JsonOutput
import net.waterfox.android.gradle.tasks.ApkSizeTask
plugins {
id "com.jetbrains.python.envs" version "0.0.26"
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-parcelize'
apply plugin: 'jacoco'
apply plugin: 'androidx.navigation.safeargs.kotlin'
apply plugin: 'com.google.android.gms.oss-licenses-plugin'
import org.gradle.internal.logging.text.StyledTextOutput.Style
import org.gradle.internal.logging.text.StyledTextOutputFactory
import static org.gradle.api.tasks.testing.TestResult.ResultType
apply from: 'benchmark.gradle'
android {
project.maybeConfigForJetpackBenchmark(it)
if (project.hasProperty("testBuildType")) {
// Allowing to configure the test build type via command line flag (./gradlew -PtestBuildType=release ..)
// in order to run UI tests against other build variants than debug in automation.
testBuildType project.property("testBuildType")
}
defaultConfig {
applicationId "com.leos.leosium"
minSdkVersion Config.minSdkVersion
compileSdk Config.compileSdkVersion
targetSdkVersion Config.targetSdkVersion
versionCode 1
versionName Config.generateDebugVersionName(project)
vectorDrawables.useSupportLibrary = true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments clearPackageData: 'true'
resValue "bool", "IS_DEBUG", "false"
buildConfigField "boolean", "USE_RELEASE_VERSIONING", "false"
buildConfigField "String", "GIT_HASH", "\"\"" // see override in release builds for why it's blank.
// This should be the "public" base URL of AMO.
buildConfigField "String", "AMO_BASE_URL", "\"https://addons.mozilla.org\""
buildConfigField "String", "AMO_COLLECTION_NAME", "\"LeOSium-Android\""
buildConfigField "String", "AMO_COLLECTION_USER", "\"17224042\""
// This should be the base URL used to call the AMO API.
buildConfigField "String", "AMO_SERVER_URL", "\"https://services.addons.mozilla.org\""
def deepLinkSchemeValue = "waterfox-dev"
buildConfigField "String", "DEEP_LINK_SCHEME", "\"$deepLinkSchemeValue\""
manifestPlaceholders = [
"deepLinkScheme": deepLinkSchemeValue
]
buildConfigField "String[]", "SUPPORTED_LOCALE_ARRAY", getSupportedLocales()
}
def releaseTemplate = {
// We allow disabling optimization by passing `-PdisableOptimization` to gradle. This is used
// in automation for UI testing non-debug builds.
shrinkResources !project.hasProperty("disableOptimization")
minifyEnabled !project.hasProperty("disableOptimization")
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
matchingFallbacks = ['release'] // Use on the "release" build type in dependencies (AARs)
// Changing the build config can cause files that depend on BuildConfig.java to recompile
// so we only set the git hash in release builds to avoid possible recompilation in debug builds.
// TODO: [Waterfox] This times out for some reason. Find a solution.
// buildConfigField "String", "GIT_HASH", "\"${Config.getGitHash()}\""
if (gradle.hasProperty("localProperties.autosignReleaseWithDebugKey")) {
signingConfig signingConfigs.debug
}
if (gradle.hasProperty("localProperties.debuggable")) {
debuggable true
}
}
buildTypes {
debug {
shrinkResources false
minifyEnabled false
applicationIdSuffix ".debug"
resValue "bool", "IS_DEBUG", "true"
pseudoLocalesEnabled true
}
release releaseTemplate >> {
buildConfigField "boolean", "USE_RELEASE_VERSIONING", "true"
applicationIdSuffix ""
def deepLinkSchemeValue = "waterfox"
buildConfigField "String", "DEEP_LINK_SCHEME", "\"$deepLinkSchemeValue\""
manifestPlaceholders = [
"deepLinkScheme": deepLinkSchemeValue
]
}
}
buildFeatures {
viewBinding true
buildConfig true
}
androidResources {
// All JavaScript code used internally by GeckoView is packaged in a
// file called omni.ja. If this file is compressed in the APK,
// GeckoView must uncompress it before it can do anything else which
// causes a significant delay on startup.
noCompress 'ja'
// manifest.template.json is converted to manifest.json at build time.
// No need to package the template in the APK.
ignoreAssetsPattern "manifest.template.json"
}
testOptions {
execution 'ANDROIDX_TEST_ORCHESTRATOR'
unitTests.includeAndroidResources = true
animationsDisabled = true
}
flavorDimensions "engine"
sourceSets {
androidTest {
resources.srcDirs += ['src/androidTest/resources']
}
}
splits {
abi {
enable true
reset()
include "x86", "armeabi-v7a", "arm64-v8a", "x86_64"
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
lint {
lintConfig file("lint.xml")
baseline file("lint-baseline.xml")
}
packagingOptions {
resources {
excludes += ['META-INF/atomicfu.kotlin_module', 'META-INF/AL2.0', 'META-INF/LGPL2.1']
}
jniLibs {
useLegacyPackaging true
}
}
testOptions {
unitTests.returnDefaultValues = true
unitTests.all {
// We keep running into memory issues when running our tests. With this config we
// reserve more memory and also create a new process after every 80 test classes. This
// is a band-aid solution and eventually we should try to find and fix the leaks
// instead. :)
forkEvery = 80
maxHeapSize = "3072m"
minHeapSize = "1024m"
}
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion = Versions.androidx_compose_compiler
}
namespace 'net.waterfox.android'
}
android.applicationVariants.all { variant ->
// -------------------------------------------------------------------------------------------------
// Generate version codes for builds
// -------------------------------------------------------------------------------------------------
def isDebug = variant.buildType.resValues['IS_DEBUG']?.value ?: false
def useReleaseVersioning = variant.buildType.buildConfigFields['USE_RELEASE_VERSIONING']?.value ?: false
println("----------------------------------------------")
println("Variant name: " + variant.name)
println("Application ID: " + [variant.applicationId, variant.buildType.applicationIdSuffix].findAll().join())
println("Build type: " + variant.buildType.name)
println("Flavor: " + variant.flavorName)
if (useReleaseVersioning) {
// The Google Play Store does not allow multiple APKs for the same app that all have the
// same version code. Therefore we need to have different version codes for our ARM and x86
// builds.
def versionName = Config.releaseVersionName(project)
println("versionName override: $versionName")
variant.outputs.each { output ->
def abi = output.getFilter(OutputFile.ABI)
// We use the same version code generator, that we inherited from Fennec, across all channels - even on
// channels that never shipped a Fennec build.
def versionCodeOverride = Config.generateFennecVersionCode(abi)
println("versionCode for $abi = $versionCodeOverride")
output.versionNameOverride = versionName
output.versionCodeOverride = versionCodeOverride
}
} else if (gradle.hasProperty("localProperties.branchBuild.waterfox.version")) {
def versionName = gradle.getProperty("localProperties.branchBuild.waterfox.version")
println("versionName override: $versionName")
variant.outputs.each { output ->
output.versionNameOverride = versionName
}
}
// -------------------------------------------------------------------------------------------------
// BuildConfig: Set variables for Sentry and Crash Reporting
// -------------------------------------------------------------------------------------------------
buildConfigField 'String', 'SENTRY_TOKEN', 'null'
if (!isDebug) {
buildConfigField 'boolean', 'CRASH_REPORTING', 'true'
// Reading sentry token from local file (if it exists). In a release task on Fastlane it will be available.
try {
def token = new File("${rootDir}/.sentry_token").text.trim()
buildConfigField 'String', 'SENTRY_TOKEN', '"' + token + '"'
} catch (FileNotFoundException ignored) {}
} else {
buildConfigField 'boolean', 'CRASH_REPORTING', 'false'
}
def buildDate = Config.generateBuildDate()
// Setting buildDate with every build changes the generated BuildConfig, which slows down the
// build. Only do this for non-debug builds, to speed-up builds produced during local development.
if (isDebug) {
buildConfigField 'String', 'BUILD_DATE', '"debug build"'
} else {
buildConfigField 'String', 'BUILD_DATE', '"' + buildDate + '"'
}
// -------------------------------------------------------------------------------------------------
// MLS: Read token from local file if it exists
// -------------------------------------------------------------------------------------------------
print("MLS token: ")
try {
def token = new File("${rootDir}/.mls_token").text.trim()
buildConfigField 'String', 'MLS_TOKEN', '"' + token + '"'
println "(Added from .mls_token file)"
} catch (FileNotFoundException ignored) {
buildConfigField 'String', 'MLS_TOKEN', '""'
println("X_X")
}
// -------------------------------------------------------------------------------------------------
// BuildConfig: Set flag for official builds; similar to MOZILLA_OFFICIAL in mozilla-central.
// -------------------------------------------------------------------------------------------------
if (project.hasProperty("official") || gradle.hasProperty("localProperties.official")) {
buildConfigField 'Boolean', 'MOZILLA_OFFICIAL', 'true'
} else {
buildConfigField 'Boolean', 'MOZILLA_OFFICIAL', 'false'
}
// -------------------------------------------------------------------------------------------------
// BuildConfig: Set remote wallpaper URL using local file if it exists
// -------------------------------------------------------------------------------------------------
print("Wallpaper URL: ")
try {
def token = new File("${rootDir}/.wallpaper_url").text.trim()
buildConfigField 'String', 'WALLPAPER_URL', '"' + token + '"'
println "(Added from .wallpaper_url file)"
} catch (FileNotFoundException ignored) {
buildConfigField 'String', 'WALLPAPER_URL', '""'
println("--")
}
}
// [Waterfox] try to exclude all telemetry dependencies
configurations.all {
// Telemetry is a transitive dependency of several necessary dependencies,
// thus we have to exclude it globally.
exclude group: 'org.mozilla.telemetry', module: 'glean-native'
}
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
kotlinOptions {
freeCompilerArgs += "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi"
}
}
dependencies {
implementation Deps.mozilla_browser_engine_gecko
implementation Deps.kotlin_stdlib
implementation Deps.kotlin_coroutines
implementation Deps.kotlin_coroutines_android
testImplementation Deps.kotlin_coroutines_test
implementation Deps.androidx_appcompat
implementation Deps.androidx_activity_compose
implementation Deps.androidx_constraintlayout
implementation Deps.androidx_coordinatorlayout
implementation Deps.google_accompanist_drawablepainter
implementation Deps.google_accompanist_insets
implementation Deps.google_accompanist_swiperefresh
implementation Deps.coil
implementation Deps.sentry
implementation Deps.mozilla_compose_awesomebar
implementation Deps.mozilla_concept_awesomebar
implementation Deps.mozilla_concept_base
implementation Deps.mozilla_concept_engine
implementation Deps.mozilla_concept_menu
implementation Deps.mozilla_concept_push
implementation Deps.mozilla_concept_storage
implementation Deps.mozilla_concept_sync
implementation Deps.mozilla_concept_toolbar
implementation Deps.mozilla_concept_tabstray
implementation Deps.mozilla_browser_domains
implementation Deps.mozilla_browser_icons
implementation Deps.mozilla_browser_menu
implementation Deps.mozilla_browser_menu2
implementation Deps.mozilla_browser_session_storage
implementation Deps.mozilla_browser_state
implementation Deps.mozilla_browser_storage_sync
implementation Deps.mozilla_browser_tabstray
implementation Deps.mozilla_browser_thumbnails
implementation Deps.mozilla_browser_toolbar
implementation Deps.mozilla_feature_addons
implementation Deps.mozilla_feature_accounts
implementation Deps.mozilla_feature_app_links
implementation Deps.mozilla_feature_autofill
implementation Deps.mozilla_feature_awesomebar
implementation Deps.mozilla_feature_contextmenu
implementation Deps.mozilla_feature_customtabs
implementation Deps.mozilla_feature_downloads
implementation Deps.mozilla_feature_intent
implementation Deps.mozilla_feature_media
implementation Deps.mozilla_feature_prompts
implementation Deps.mozilla_feature_push
implementation Deps.mozilla_feature_privatemode
implementation Deps.mozilla_feature_pwa
implementation Deps.mozilla_feature_qr
implementation Deps.mozilla_feature_search
implementation Deps.mozilla_feature_session
implementation Deps.mozilla_feature_syncedtabs
implementation Deps.mozilla_feature_toolbar
implementation Deps.mozilla_feature_tabs
implementation Deps.mozilla_feature_findinpage
implementation Deps.mozilla_feature_logins
implementation Deps.mozilla_feature_site_permissions
implementation Deps.mozilla_feature_readerview
implementation Deps.mozilla_feature_tab_collections
implementation Deps.mozilla_feature_recentlyclosed
implementation Deps.mozilla_feature_top_sites
implementation Deps.mozilla_feature_share
implementation Deps.mozilla_feature_accounts_push
implementation Deps.mozilla_feature_webauthn
implementation Deps.mozilla_feature_webcompat
implementation Deps.mozilla_feature_webnotifications
implementation Deps.mozilla_feature_webcompat_reporter
implementation Deps.mozilla_service_contile
implementation Deps.mozilla_service_digitalassetlinks
implementation Deps.mozilla_service_sync_autofill
implementation Deps.mozilla_service_sync_logins
implementation Deps.mozilla_service_firefox_accounts
implementation Deps.mozilla_service_location
implementation Deps.mozilla_support_extensions
implementation Deps.mozilla_support_base
implementation Deps.mozilla_support_rusterrors
implementation Deps.mozilla_support_images
implementation Deps.mozilla_support_ktx
implementation Deps.mozilla_support_rustlog
implementation Deps.mozilla_support_utils
implementation Deps.mozilla_support_locale
implementation Deps.mozilla_ui_colors
implementation Deps.mozilla_ui_icons
implementation Deps.mozilla_lib_publicsuffixlist
implementation Deps.mozilla_ui_widgets
implementation Deps.mozilla_ui_tabcounter
implementation Deps.mozilla_lib_crash
implementation Deps.lib_crash_sentry
implementation Deps.mozilla_lib_state
implementation Deps.mozilla_lib_dataprotect
debugImplementation Deps.leakcanary
implementation Deps.androidx_compose_ui
implementation Deps.androidx_compose_ui_tooling
implementation Deps.androidx_compose_foundation
implementation Deps.androidx_compose_material
implementation Deps.androidx_compose_paging
implementation Deps.androidx_legacy
implementation Deps.androidx_biometric
implementation Deps.androidx_paging
implementation Deps.androidx_preference
implementation Deps.androidx_fragment
implementation Deps.androidx_navigation_fragment
implementation Deps.androidx_navigation_ui
implementation Deps.androidx_recyclerview
implementation Deps.androidx_lifecycle_common
implementation Deps.androidx_lifecycle_livedata
implementation Deps.androidx_lifecycle_process
implementation Deps.androidx_lifecycle_runtime
implementation Deps.androidx_lifecycle_viewmodel
implementation Deps.androidx_core
implementation Deps.androidx_core_ktx
implementation Deps.androidx_transition
implementation Deps.androidx_work_ktx
implementation Deps.androidx_datastore
implementation Deps.google_material
androidTestImplementation Deps.uiautomator
androidTestImplementation "tools.fastlane:screengrab:2.0.0"
// This Falcon version is added to maven central now required for Screengrab
implementation 'com.jraska:falcon:2.2.0'
androidTestImplementation Deps.androidx_compose_ui_test
androidTestImplementation Deps.espresso_core, {
exclude group: 'com.android.support', module: 'support-annotations'
}
androidTestImplementation(Deps.espresso_contrib) {
exclude module: 'appcompat-v7'
exclude module: 'support-v4'
exclude module: 'support-annotations'
exclude module: 'recyclerview-v7'
exclude module: 'design'
exclude module: 'espresso-core'
exclude module: 'protobuf-lite'
}
androidTestImplementation Deps.androidx_test_core
androidTestImplementation Deps.espresso_idling_resources
androidTestImplementation Deps.espresso_intents
androidTestImplementation Deps.tools_test_runner
androidTestImplementation Deps.tools_test_rules
androidTestUtil Deps.orchestrator
androidTestImplementation Deps.espresso_core, {
exclude group: 'com.android.support', module: 'support-annotations'
}
androidTestImplementation Deps.androidx_junit
androidTestImplementation Deps.androidx_test_extensions
androidTestImplementation Deps.androidx_work_testing
androidTestImplementation Deps.androidx_benchmark_junit4
androidTestImplementation Deps.mockwebserver
testImplementation Deps.mozilla_support_test
testImplementation Deps.mozilla_support_test_libstate
testImplementation Deps.androidx_junit
testImplementation Deps.androidx_test_extensions
testImplementation Deps.androidx_work_testing
testImplementation (Deps.robolectric) {
exclude group: 'org.apache.maven'
}
testImplementation 'org.apache.maven:maven-ant-tasks:2.1.3'
implementation Deps.mozilla_support_rusthttp
testImplementation Deps.mockk
lintChecks project(":mozilla-lint-rules")
}
if (project.hasProperty("coverage")) {
tasks.withType(Test).configureEach {
jacoco.includeNoLocationClasses = true
jacoco.excludes = ['jdk.internal.*']
}
jacoco {
toolVersion = "0.8.7"
}
android.applicationVariants.all { variant ->
tasks.register("jacoco${variant.name.capitalize()}TestReport", JacocoReport) {
dependsOn "test${variant.name.capitalize()}UnitTest"
reports {
xml.enabled = true
html.enabled = true
}
def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*',
'**/*Test*.*', 'android/**/*.*', '**/*$[0-9].*']
def kotlinDebugTree = fileTree(dir: "$project.buildDir/tmp/kotlin-classes/${variant.name}", excludes: fileFilter)
def javaDebugTree = fileTree(dir: "$project.buildDir/intermediates/classes/${variant.flavorName}/${variant.buildType.name}",
excludes: fileFilter)
def mainSrc = "$project.projectDir/src/main/java"
sourceDirectories.setFrom(files([mainSrc]))
classDirectories.setFrom(files([kotlinDebugTree, javaDebugTree]))
executionData.setFrom(fileTree(dir: project.buildDir, includes: [
"jacoco/test${variant.name.capitalize()}UnitTest.exec",
'outputs/code-coverage/connected/*coverage.ec'
]))
}
}
android {
buildTypes {
debug {
testCoverageEnabled true
}
}
}
}
// -------------------------------------------------------------------------------------------------
// Task for printing APK information for the requested variant
// Usage: "./gradlew printVariants
// -------------------------------------------------------------------------------------------------
tasks.register('printVariants') {
doLast {
def variants = android.applicationVariants.collect { variant -> [
apks: variant.outputs.collect { output -> [
abi: output.getFilter(com.android.build.VariantOutput.FilterType.ABI),
fileName: output.outputFile.name
]},
build_type: variant.buildType.name,
name: variant.name,
]}
// AndroidTest is a special case not included above
variants.add([
apks: [[
abi: 'noarch',
fileName: 'app-debug-androidTest.apk',
]],
build_type: 'androidTest',
name: 'androidTest',
])
println 'variants: ' + JsonOutput.toJson(variants)
}
}
afterEvaluate {
// Format test output. Ported from AC #2401
tasks.withType(Test).configureEach {
systemProperty "robolectric.logging", "stdout"
systemProperty "logging.test-mode", "true"
testLogging.events = []
def out = services.get(StyledTextOutputFactory).create("tests")
beforeSuite { descriptor ->
if (descriptor.getClassName() != null) {
out.style(Style.Header).println("\nSUITE: " + descriptor.getClassName())
}
}
beforeTest { descriptor ->
out.style(Style.Description).println(" TEST: " + descriptor.getName())
}
onOutput { descriptor, event ->
logger.lifecycle(" " + event.message.trim())
}
afterTest { descriptor, result ->
switch (result.getResultType()) {
case ResultType.SUCCESS:
out.style(Style.Success).println(" SUCCESS")
break
case ResultType.FAILURE:
out.style(Style.Failure).println(" FAILURE")
logger.lifecycle("", result.getException())
break
case ResultType.SKIPPED:
out.style(Style.Info).println(" SKIPPED")
break
}
logger.lifecycle("")
}
}
}
if (gradle.hasProperty('localProperties.dependencySubstitutions.geckoviewTopsrcdir')) {
if (gradle.hasProperty('localProperties.dependencySubstitutions.geckoviewTopobjdir')) {
ext.topobjdir = gradle."localProperties.dependencySubstitutions.geckoviewTopobjdir"
}
ext.topsrcdir = gradle."localProperties.dependencySubstitutions.geckoviewTopsrcdir"
apply from: "${topsrcdir}/substitute-local-geckoview.gradle"
}
def acSrcDir = null
if (gradle.hasProperty('localProperties.autoPublish.android-components.dir')) {
acSrcDir = gradle.getProperty('localProperties.autoPublish.android-components.dir')
} else if (gradle.hasProperty('localProperties.branchBuild.android-components.dir')) {
acSrcDir = gradle.getProperty('localProperties.branchBuild.android-components.dir')
}
if (acSrcDir) {
if (acSrcDir.startsWith("/")) {
apply from: "${acSrcDir}/substitute-local-ac.gradle"
} else {
apply from: "../${acSrcDir}/substitute-local-ac.gradle"
}
}
def appServicesSrcDir = null
if (gradle.hasProperty('localProperties.autoPublish.application-services.dir')) {
appServicesSrcDir = gradle.getProperty('localProperties.autoPublish.application-services.dir')
} else if (gradle.hasProperty('localProperties.branchBuild.application-services.dir')) {
appServicesSrcDir = gradle.getProperty('localProperties.branchBuild.application-services.dir')
}
if (appServicesSrcDir) {
if (appServicesSrcDir.startsWith("/")) {
apply from: "${appServicesSrcDir}/build-scripts/substitute-local-appservices.gradle"
} else {
apply from: "../${appServicesSrcDir}/build-scripts/substitute-local-appservices.gradle"
}
}
// Define a reusable task for updating the versions of our built-in web extensions. We automate this
// to make sure we never forget to update the version, either in local development or for releases.
// In both cases, we want to make sure the latest version of all extensions (including their latest
// changes) are installed on first start-up.
// We're using the A-C version here as we want to uplift all built-in extensions to A-C (Once that's
// done we can also remove the task below):
// https://github.com/mozilla-mobile/android-components/issues/7249
ext.updateExtensionVersion = { task, extDir ->
configure(task) {
from extDir
include 'manifest.template.json'
rename { 'manifest.json' }
into extDir
def values = ['version': Versions.mozilla_android_components + "." + new Date().format('MMddHHmmss')]
inputs.properties(values)
expand(values)
}
}
android.applicationVariants.configureEach { variant ->
tasks.register("apkSize${variant.name.capitalize()}", ApkSizeTask) {
variantName = variant.name
apks = variant.outputs.collect { output -> output.outputFile.name }
dependsOn "package${variant.name.capitalize()}"
}
}
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()
foundLocales.append("new String[]{")
fileTree("src/main/res").visit { FileVisitDetails details ->
if (details.file.path.endsWith("${File.separator}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(",")
}
}
foundLocales.append("}")
def foundLocalesString = foundLocales.toString().replaceAll(',}', '}')
return foundLocalesString
}