Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/mobile/android/fenix/app/   (Android Betriebssystem Version 17©)  Datei vom 27.6.2026 mit Größe 34 kB image not shown  

Quelle  build.gradle   Sprache: unbekannt

 
Spracherkennung für: .gradle vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

import com.android.build.api.variant.FilterConfiguration

import java.time.format.DateTimeFormatter

import static org.mozilla.conventions.BuildConfigKt.getBuildId

buildscript {
    repositories {
        gradle.configureMavenRepositories(delegate)
    }

    dependencies {
        classpath libs.kotlin.serialization
    }
}

plugins {
    alias(libs.plugins.dependency.analysis)
    alias(libs.plugins.kotlin.android)
    alias(libs.plugins.kotlin.compose)
    alias(libs.plugins.python.envs.plugin)
    alias(libs.plugins.protobuf.plugin)
    id 'ApkSizePlugin'
    id 'org.mozilla.conventions.zip-test-reports'
    id 'org.mozilla.nimbus-gradle-plugin'
}

apply plugin: 'com.android.application'
apply plugin: 'kotlin-parcelize'
apply plugin: 'jacoco'
apply plugin: 'androidx.navigation.safeargs.kotlin'
apply plugin: 'kotlinx-serialization'
apply plugin: 'com.google.devtools.ksp'

// The OSS-licenses plugin is only needed for shipping builds, so skip it during
// `mach lint` (which always passes `-Pandroid-lint`) to avoid unnecessary overhead.
if (gradle.mozconfig.substs.MOZILLA_OFFICIAL && !project.hasProperty('android-lint')) {
    apply plugin: 'com.google.android.gms.oss-licenses-plugin'
}

apply from: 'benchmark.gradle'

def isAppBundle = gradle.startParameter.taskNames.any { it.toLowerCase().contains("bundle") }

android {
    project.maybeConfigForJetpackBenchmark(it)
    if (project.hasProperty("testBuildType")) {
        // Allowing to configure the test build type via command line flag (./gradlew -PtestBuildType=beta ..)
        // in order to run UI tests against other build variants than debug in automation.
        testBuildType project.property("testBuildType")
    }

    compileSdk { version = release(config.compileSdkMajorVersion) { minorApiLevel = config.compileSdkMinorVersion } }

    defaultConfig {
        ksp {
            arg("room.schemaLocation", "$projectDir/schemas".toString())
        }

        applicationId "org.mozilla"
        minSdk config.minSdkVersion
        targetSdk config.targetSdkVersion
        versionCode 1
        versionName Config.generateDebugVersionName()
        vectorDrawables.useSupportLibrary = true
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        testInstrumentationRunnerArguments clearPackageData: 'true'
        testInstrumentationRunnerArguments "detect-leaks": 'true'
        resValue "bool", "IS_DEBUG", "false"
        buildConfigField "boolean", "USE_RELEASE_VERSIONING", "false"
        // Blank in debug builds so that tests are deterministic.
        buildConfigField "String", "VCS_HASH", "\"\""
        // This should be the "public" base URL of AMO.
        buildConfigField "String", "AMO_BASE_URL", "\"https://addons.mozilla.org\""
        buildConfigField "String", "AMO_COLLECTION_NAME", "\"Extensions-for-Android\""
        buildConfigField "String", "AMO_COLLECTION_USER", "\"mozilla\""
        // This should be the base URL used to call the AMO API.
        buildConfigField "String", "AMO_SERVER_URL", "\"https://services.addons.mozilla.org\""

        def deepLinkSchemeValue = "fenix-dev"
        buildConfigField "String", "DEEP_LINK_SCHEME", "\"$deepLinkSchemeValue\""

        manifestPlaceholders = [
                "deepLinkScheme": deepLinkSchemeValue
        ]

        buildConfigField "String[]", "SUPPORTED_LOCALE_ARRAY", getSupportedLocales()
        buildConfigField "boolean", "IS_BENCHMARK_BUILD", "false"
    }

    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)

        // Present in release builds.
        if (gradle.mozconfig.substs.MOZ_INCLUDE_SOURCE_INFO) {
            buildConfigField("String", "VCS_HASH", "\"" + gradle.mozconfig.source_repo.MOZ_SOURCE_STAMP + "\"")
        }

     // If building locally, just use debug signing. In official automation builds, the
     // files are signed using a separate service and not within gradle.
     // Also skip during buildconfig linting, and skip if the `disableDebugSigning` Gradle property is set.
        if (!project.hasProperty("disableDebugSigning") && !gradle.hasProperty("localProperties.disableDebugSigning") && !gradle.mozconfig.substs.MOZ_AUTOMATION && System.getenv("MOZ_BUILD_CONFIG_LINT") != "1") {
            signingConfig = signingConfigs.debug
        }

        if (gradle.hasProperty("localProperties.debuggable") ||
            gradle.mozconfig.substs.MOZ_ANDROID_DEBUGGABLE) {
            debuggable true
        }
    }

    buildTypes {
        debug {
            shrinkResources = false
            minifyEnabled = false
            applicationIdSuffix ".fenix.debug"
            resValue "bool", "IS_DEBUG", "true"
            pseudoLocalesEnabled = true
        }
        nightly releaseTemplate >> {
            applicationIdSuffix ".fenix"
            buildConfigField "boolean", "USE_RELEASE_VERSIONING", "true"
            def deepLinkSchemeValue = "fenix-nightly"
            buildConfigField "String", "DEEP_LINK_SCHEME", "\"$deepLinkSchemeValue\""
            manifestPlaceholders.putAll([
                    "deepLinkScheme": deepLinkSchemeValue
            ])
        }
        beta releaseTemplate >> {
            buildConfigField "boolean", "USE_RELEASE_VERSIONING", "true"
            applicationIdSuffix ".firefox_beta"
            def deepLinkSchemeValue = "fenix-beta"
            buildConfigField "String", "DEEP_LINK_SCHEME", "\"$deepLinkSchemeValue\""
            manifestPlaceholders.putAll([
                    // This release type is meant to replace Firefox (Beta channel) and therefore needs to inherit
                    // its sharedUserId for all eternity. See:
                    // https://searchfox.org/mozilla-esr68/search?q=moz_android_shared_id&case=false®exp=false&path=
                    // Shipping an app update without sharedUserId can have
                    // fatal consequences. For example see:
                    //  - https://issuetracker.google.com/issues/36924841
                    //  - https://issuetracker.google.com/issues/36905922
                    "sharedUserId": "org.mozilla.firefox.sharedID",
                    "deepLinkScheme": deepLinkSchemeValue,
            ])
        }
        release releaseTemplate >> {
            buildConfigField "boolean", "USE_RELEASE_VERSIONING", "true"
            applicationIdSuffix ".firefox"
            def deepLinkSchemeValue = "fenix"
            buildConfigField "String", "DEEP_LINK_SCHEME", "\"$deepLinkSchemeValue\""
            manifestPlaceholders.putAll([
                    // This release type is meant to replace Firefox (Release channel) and therefore needs to inherit
                    // its sharedUserId for all eternity. See:
                    // https://searchfox.org/mozilla-esr68/search?q=moz_android_shared_id&case=false®exp=false&path=
                    // Shipping an app update without sharedUserId can have
                    // fatal consequences. For example see:
                    //  - https://issuetracker.google.com/issues/36924841
                    //  - https://issuetracker.google.com/issues/36905922
                    "sharedUserId": "org.mozilla.firefox.sharedID",
                    "deepLinkScheme": deepLinkSchemeValue,
            ])
        }
        benchmark releaseTemplate >> {
            initWith buildTypes.nightly
            shrinkResources = false
            minifyEnabled = false
            applicationIdSuffix ".fenix"
            signingConfig = signingConfigs.debug
            debuggable false
            buildConfigField "boolean", "IS_BENCHMARK_BUILD", "true"
        }
    }

    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 {
        animationsDisabled = true
        execution = 'ANDROIDX_TEST_ORCHESTRATOR'
        testCoverage {
            jacocoVersion = libs.versions.jacoco.get()
        }
        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"
            }
            includeAndroidResources = true
            returnDefaultValues = true
        }
    }


    sourceSets {
        androidTest {
            resources.srcDirs += ['src/androidTest/resources']
            assets.srcDirs += files("$projectDir/schemas".toString())
        }
        if (project.hasProperty('baselineProfilePath')) {
            main {
                baselineProfiles.srcDirs(project.property('baselineProfilePath'))
            }
        }
    }

    splits {
        abi {
            enable = !isAppBundle

            reset()

            // As gradle is unable to pick the right apk to install when multiple apks are generated
            // while running benchmark tests or generating baseline profiles. To circumvent this,
            // this flag is passed to make sure only one apk is generated so gradle can pick that one.
            if (project.hasProperty("benchmarkTest")) {
                include "arm64-v8a"
            } else {
                include "armeabi-v7a", "arm64-v8a", "x86_64"
                if (gradle.mozconfig.substs.MOZILLA_OFFICIAL || System.getenv("MOZ_BUILD_CONFIG_LINT") == "1") {
                    universalApk true
                }
            }
        }
    }

    bundle {
        language {
            // Because we have runtime language selection we will keep all strings and languages
            // in the base APKs.
            enableSplit = false
        }
    }

    lint {
        lintConfig = file("lint.xml")
        baseline = file("lint-baseline.xml")
        sarifReport = true
        sarifOutput = file("../build/reports/lint/lint-report.sarif.json")
        abortOnError = false
    }

    // Exclude native libraries for unsupported architectures from third-party dependencies
    packaging {
        jniLibs {
            excludes += ["**/armeabi/*.so", "**/mips/*.so", "**/mips64/*.so", "**/x86/*.so"]
            if (!isAppBundle) {
                useLegacyPackaging = true
            }
        }
    }

    buildFeatures {
        compose = true
    }

    namespace = 'org.mozilla.fenix'
}

// -------------------------------------------------------------------------------------------------
// Generate version codes for builds
// -------------------------------------------------------------------------------------------------

androidComponents {
    onVariants(selector().all()) { variant ->
        def buildType = variant.buildType

        project.logger.debug("----------------------------------------------")
        project.logger.debug("Variant name:      " + variant.name)
        project.logger.debug("Build type:        " + buildType)
        project.logger.debug("Flavor:            " + variant.flavorName)

        // This list must stay in sync with the build types that set USE_RELEASE_VERSIONING=true in
        // their buildConfigField. The legacy variant API exposed buildConfigFields on the build type
        // object so we could read the flag directly; onVariants only gives us the build type name, so
        // we gate on the names instead.
        if (buildType in ['nightly', 'beta', 'release', 'benchmark']) {
            // 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 = buildType == 'nightly' ?
                    "${Config.nightlyVersionName(project)}" :
                    "${Config.releaseVersionName(project)}"
            project.logger.debug("versionName override: $versionName")

            variant.outputs.each { output ->
                // 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 abi = output.filters.find { it.filterType == FilterConfiguration.FilterType.ABI }?.identifier ?: "universal"
                def versionCodeOverride = Config.generateFennecVersionCode(abi)
                project.logger.debug("versionCode for $abi = $versionCodeOverride")
                output.versionName.set(versionName)
                output.versionCode.set(versionCodeOverride)
            }
        } else if (gradle.hasProperty("localProperties.branchBuild.fenix.version")) {
            def versionName = gradle.getProperty("localProperties.branchBuild.fenix.version")
            project.logger.debug("versionName override: $versionName")
            variant.outputs.each { output ->
                output.versionName.set(versionName)
            }
        }
    }
}

// -------------------------------------------------------------------------------------------------
// BuildConfig: Sentry, Crash Reporting, Telemetry, and various tokens.
//
// Non-debug values are set on defaultConfig; the debug build type (the only IS_DEBUG build type)
// overrides the ones that differ. These were previously set per-variant via the legacy
// applicationVariants API, which AGP 9 removes.
// -------------------------------------------------------------------------------------------------

android.defaultConfig.with {
    buildConfigField 'boolean', 'CRASH_REPORTING', 'true'
    buildConfigField 'boolean', 'TELEMETRY', 'true'

    // Reading the sentry token from a local file (if it exists). In a release task on taskcluster it will be available.
    buildConfigField 'String', 'SENTRY_TOKEN', 'null'
    try {
        def token = new File("${rootDir}/.sentry_token").text.trim()
        buildConfigField 'String', 'SENTRY_TOKEN', '"' + token + '"'
    } catch (FileNotFoundException ignored) {}

    // Setting buildDate with every build ID changes the generated BuildConfig and slows down the
    // build, so debug builds (overridden below) use a fixed string instead.
    def buildDate = LocalDateTime.parse(getBuildId(gradle.mozconfig.topobjdir), DateTimeFormatter.ofPattern("yyyyMMddHHmmss")).toString()
    buildConfigField 'String', 'BUILD_DATE', '"' + buildDate + '"'

    try {
        def token = new File("${rootDir}/.adjust_token").text.trim()
        buildConfigField 'String', 'ADJUST_TOKEN', '"' + token + '"'
    } catch (FileNotFoundException ignored) {
        buildConfigField 'String', 'ADJUST_TOKEN', 'null'
    }

    try {
        def url = new File("${rootDir}/.nimbus").text.trim()
        buildConfigField 'String', 'NIMBUS_ENDPOINT', '"' + url + '"'
    } catch (FileNotFoundException ignored) {
        buildConfigField 'String', 'NIMBUS_ENDPOINT', 'null'
    }

    buildConfigField 'boolean', 'LEAKCANARY', 'false'

    // The remaining fields do not depend on the build type.
    try {
        def token = new File("${rootDir}/.mls_token").text.trim()
        buildConfigField 'String', 'MLS_TOKEN', '"' + token + '"'
    } catch (FileNotFoundException ignored) {
        buildConfigField 'String', 'MLS_TOKEN', '""'
    }

    try {
        def token = new File("${rootDir}/.gps_integrity_token").text.trim()
        buildConfigField 'String', 'GPS_INTEGRITY_TOKEN', '"' + token + '"'
    } catch (FileNotFoundException ignored) {
        buildConfigField 'String', 'GPS_INTEGRITY_TOKEN', '""'
    }

    if (gradle.hasProperty("localProperties.glean.custom.server.url")) {
        def url = gradle.getProperty("localProperties.glean.custom.server.url")
        buildConfigField 'String', 'GLEAN_CUSTOM_URL', url
    } else {
        buildConfigField 'String', 'GLEAN_CUSTOM_URL', 'null'
    }

    if (project.hasProperty("official") || gradle.hasProperty("localProperties.official")) {
        buildConfigField 'Boolean', 'MOZILLA_OFFICIAL', 'true'
    } else {
        buildConfigField 'Boolean', 'MOZILLA_OFFICIAL', 'false'
    }

    try {
        def token = new File("${rootDir}/.wallpaper_url").text.trim()
        buildConfigField 'String', 'WALLPAPER_URL', '"' + token + '"'
    } catch (FileNotFoundException ignored) {
        buildConfigField 'String', 'WALLPAPER_URL', '""'
    }
}

android.buildTypes.debug.with {
    buildConfigField 'boolean', 'CRASH_REPORTING', 'false'
    buildConfigField 'boolean', 'TELEMETRY', 'false'
    buildConfigField 'String', 'BUILD_DATE', '"debug build"'
    buildConfigField 'String', 'SENTRY_TOKEN', 'null'
    buildConfigField 'String', 'ADJUST_TOKEN', 'null'

    if (gradle.hasProperty("localProperties.nimbus.remote-settings.url")) {
        def url = gradle.getProperty("localProperties.nimbus.remote-settings.url")
        buildConfigField 'String', 'NIMBUS_ENDPOINT', '"' + url + '"'
    } else {
        buildConfigField 'String', 'NIMBUS_ENDPOINT', 'null'
    }

    if (project.hasProperty("disableLeakCanary") || gradle.hasProperty("localProperties.disableLeakCanary")) {
        buildConfigField "boolean", "LEAKCANARY", "false"
    } else {
        buildConfigField "boolean", "LEAKCANARY", "true"
    }
}

// Generate Kotlin code for the Fenix Glean metrics.
ext {
    // Enable expiration by major version.
    gleanExpireByVersion = Config.majorVersion(project)
    gleanNamespace = "mozilla.telemetry.glean"
    gleanPythonEnvDir = gradle.mozconfig.substs.GRADLE_GLEAN_PARSER_VENV
}
apply plugin: "org.mozilla.telemetry.glean-gradle-plugin"

nimbus {
    // The path to the Nimbus feature manifest file
    manifestFile = "nimbus.fml.yaml"
    // The fully qualified class name for the generated features.
    // Map from the variant name to the channel as experimenter and nimbus understand it.
    // If nimbus's channels were accurately set up well for this project, then this
    // shouldn't be needed.
    channels = [
            debug: "developer",
            nightly: "nightly",
            beta: "beta",
            release: "release",
            benchmark: "nightly",
    ]
    // This is generated by the FML and should be checked into git.
    // It will be fetched by Experimenter (the Nimbus experiment website)
    // and used to inform experiment configuration.
    experimenterManifest = ".experimenter.yaml"
    applicationServicesDir = gradle.hasProperty('localProperties.autoPublish.application-services.dir')
            ? gradle.getProperty('localProperties.autoPublish.application-services.dir') : null
}

dependencies {
    implementation project('longfox')
    implementation project(':components:browser-engine-gecko')
    implementation project(':components:compose-awesomebar')
    implementation project(':components:compose-base')
    implementation project(':components:compose-browser-toolbar')
    implementation project(':components:compose-cfr')
    implementation project(':components:concept-awesomebar')
    implementation project(':components:concept-base')
    implementation project(':components:concept-engine')
    implementation project(':components:concept-menu')
    implementation project(':components:concept-push')
    implementation project(':components:concept-storage')
    implementation project(':components:concept-sync')
    implementation project(':components:concept-tabstray')
    implementation project(':components:concept-toolbar')
    implementation project(':components:browser-domains')
    implementation project(':components:browser-icons')
    implementation project(':components:browser-menu')
    implementation project(':components:browser-session-storage')
    implementation project(':components:browser-state')
    implementation project(':components:browser-storage-sync')
    implementation project(':components:browser-tabstray')
    implementation project(':components:browser-thumbnails')
    implementation project(':components:browser-toolbar')
    implementation project(':components:feature-accounts')
    implementation project(':components:feature-accounts-push')
    implementation project(':components:feature-addons')
    implementation project(':components:feature-app-links')
    implementation project(':components:feature-autofill')
    implementation project(':components:feature-awesomebar')
    implementation project(':components:feature-contextmenu')
    implementation project(':components:feature-customtabs')
    implementation project(':components:feature-downloads')
    implementation project(':components:feature-findinpage')
    implementation project(':components:feature-fxsuggest')
    implementation project(':components:feature-importer')
    implementation project(':components:feature-password-importer')
    implementation project(':components:feature-intent')
    implementation project(':components:feature-ipprotection')
    implementation project(':components:feature-logins')
    implementation project(':components:feature-media')
    implementation project(':components:feature-privatemode')
    implementation project(':components:feature-prompts')
    implementation project(':components:feature-protection-dashboard')
    implementation project(':components:feature-push')
    implementation project(':components:feature-pwa')
    implementation project(':components:feature-qr')
    implementation project(':components:feature-readerview')
    implementation project(':components:feature-recentlyclosed')
    implementation project(':components:feature-search')
    implementation project(':components:feature-session')
    implementation project(':components:feature-share')
    implementation project(':components:feature-sitepermissions')
    implementation project(':components:feature-summarize')
    implementation project(':components:feature-syncedtabs')
    implementation project(':components:feature-toolbar')
    implementation project(':components:feature-tab-collections')
    implementation project(':components:feature-tabs')
    implementation project(':components:feature-top-sites')
    implementation project(':components:feature-webauthn')
    implementation project(':components:feature-webcompat')
    implementation project(':components:feature-webcompat-reporter')
    implementation project(':components:feature-webnotifications')
    implementation project(':components:service-digitalassetlinks')
    implementation project(':components:service-firefox-accounts')
    implementation project(":components:service-firefox-relay")
    implementation project(':components:service-glean')
    implementation project(':components:service-location')
    implementation project(':components:service-mars')
    implementation project(':components:service-merino-manifest')
    implementation project(':components:service-nimbus')
    implementation project(':components:service-pocket')
    implementation project(':components:service-sync-autofill')
    implementation project(':components:service-sync-logins')
    implementation project(':components:support-appservices')
    implementation project(':components:support-base')
    implementation project(':components:support-images')
    implementation project(':components:support-ktx')
    implementation project(':components:support-license')
    implementation project(':components:support-locale')
    implementation project(':components:support-remotesettings')
    implementation project(':components:support-utils')
    implementation project(':components:support-webextensions')
    implementation project(':components:lib-publicsuffixlist')
    implementation project(':components:ui-icons')
    implementation project(':components:ui-colors')
    implementation project(':components:ui-tabcounter')
    implementation project(':components:ui-widgets')
    implementation project(':components:lib-bookmarks-file')
    implementation project(':components:lib-bookmark-parser-jsoup')
    implementation project(':components:lib-passwords-file')
    implementation project(':components:lib-crash')
    implementation project(':components:lib-crash-sentry')
    implementation project(':components:lib-dataprotect')
    implementation project(':components:lib-push-firebase')
    implementation project(':components:lib-state')
    implementation project(':components:lib-accelerometer-sensormanager')
    implementation project(':components:lib-integrity-googleplay')
    implementation project(':components:lib-llm-mlpa')
    implementation project(':components:lib-shake')
    implementation project(':components:lib-ai-controls')

    implementation ComponentsDependencies.mozilla_appservices_syncmanager
    implementation ComponentsDependencies.mozilla_appservices_merino

    implementation libs.accompanist.drawablepainter
    implementation libs.adjust
    implementation libs.androidx.activity
    implementation libs.androidx.annotation
    implementation libs.androidx.appcompat
    implementation libs.androidx.biometric
    implementation platform(libs.androidx.compose.bom)
    implementation libs.androidx.compose.animation
    implementation libs.androidx.compose.foundation
    implementation libs.androidx.compose.material.icons
    implementation libs.androidx.compose.material3
    implementation libs.androidx.compose.material3.adaptive
    implementation libs.androidx.compose.material3.adaptivelayout
    implementation libs.androidx.compose.material3.adaptivenavigation
    implementation libs.androidx.compose.material3.adaptivenavigationsuite
    implementation libs.androidx.compose.material3.windowsizeclass
    implementation libs.androidx.compose.ui
    implementation libs.androidx.compose.ui.tooling.preview
    implementation libs.androidx.constraintlayout
    implementation libs.androidx.coordinatorlayout
    implementation libs.androidx.core
    implementation libs.androidx.core.ktx
    implementation libs.androidx.core.splashscreen
    implementation libs.androidx.datastore
    implementation libs.androidx.datastore.preferences
    implementation libs.androidx.emoji2
    implementation libs.androidx.exifinterface
    implementation libs.androidx.fragment
    implementation libs.androidx.fragment.compose
    implementation libs.androidx.lifecycle.common
    implementation libs.androidx.lifecycle.livedata
    implementation libs.androidx.lifecycle.process
    implementation libs.androidx.lifecycle.runtime
    implementation libs.androidx.lifecycle.service
    implementation libs.androidx.lifecycle.viewmodel
    implementation libs.androidx.navigation.compose
    implementation libs.androidx.navigation.fragment
    implementation libs.androidx.navigation.ui
    implementation libs.androidx.navigation3.runtime
    implementation libs.androidx.navigation3.ui
    implementation libs.androidx.paging
    implementation libs.androidx.preference
    implementation libs.androidx.profileinstaller
    implementation libs.androidx.recyclerview
    implementation libs.androidx.swiperefreshlayout
    implementation libs.androidx.transition
    implementation libs.androidx.viewpager2
    implementation libs.androidx.work.runtime
    implementation libs.google.material
    implementation libs.installreferrer
    implementation libs.kotlinx.coroutines
    implementation libs.kotlinx.serialization.json
    implementation libs.mozilla.glean
    implementation libs.play.review
    implementation libs.play.review.ktx
    implementation libs.play.services.ads.id
    implementation libs.protobuf.javalite
    implementation libs.sentry
    implementation libs.androidx.documentfile
    implementation libs.zxing

    implementation libs.androidx.room.runtime
    ksp libs.androidx.room.compiler

    debugImplementation libs.androidx.compose.ui.tooling
    debugImplementation libs.leakcanary

    // Exclude Mockito to prevent classpath conflicts with MockK in tests.
    testImplementation (project(':components:support-test')) {
        exclude group: 'org.mockito'
    }
    testImplementation project(':components:support-test-fakes')
    testImplementation project(':components:support-test-libstate')
    testImplementation testFixtures(project(':components:support-utils'))

    testImplementation ComponentsDependencies.mozilla_appservices_full_megazord_libsForTests

    testImplementation libs.androidx.compose.ui.test
    testImplementation libs.androidx.test.core
    testImplementation libs.androidx.test.junit
    testImplementation libs.androidx.test.runner
    testImplementation libs.androidx.work.testing
    testImplementation libs.kotlin.test
    testImplementation libs.kotlinx.coroutines.test
    testImplementation libs.mockk
    testImplementation libs.mozilla.glean.forUnitTests
    testImplementation libs.robolectric

    androidTestImplementation project(':components:support-android-test')
    androidTestImplementation libs.androidx.benchmark.junit4
    // We need a version constraint due to AGP silently trying to downgrade the version otherwise.
    // https://issuetracker.google.com/issues/349628366
    constraints {
        implementation(libs.androidx.concurrent)
    }
    androidTestImplementation libs.androidx.concurrent
    androidTestImplementation platform(libs.androidx.compose.bom)
    androidTestImplementation libs.androidx.compose.ui.test
    androidTestImplementation libs.androidx.test.core
    androidTestImplementation(libs.androidx.test.espresso.contrib) {
        exclude module: 'protobuf-lite'
    }
    androidTestImplementation libs.androidx.test.espresso.core
    androidTestImplementation libs.androidx.test.espresso.idling.resource
    androidTestImplementation libs.androidx.test.espresso.intents
    androidTestImplementation libs.androidx.test.junit
    androidTestImplementation libs.androidx.test.monitor
    androidTestImplementation libs.androidx.test.rules
    androidTestImplementation libs.androidx.test.runner
    androidTestImplementation libs.androidx.test.uiautomator
    androidTestImplementation libs.androidx.work.testing
    androidTestImplementation libs.kotlin.test
    androidTestImplementation libs.androidx.room.testing
    androidTestImplementation libs.leakcanary.instrumentation
    androidTestImplementation libs.mockk.android
    androidTestImplementation libs.mockwebserver
    androidTestImplementation libs.okhttp
    androidTestRuntimeOnly libs.okio
    constraints {
        // Various AndroidX dependencies pull in 1.1.1 transitively; OkHttp 5 requires 1.2.0.
        implementation(libs.androidx.startup.runtime)
        // okhttp is test-only; prevents older releases being resolved on the main classpath.
        implementation(libs.okio)
    }

    androidTestUtil libs.androidx.test.orchestrator

    lintChecks project(':components:tooling-lint')
}

protobuf {
    protoc {
        artifact = libs.protobuf.compiler.get()
    }

    // Generates the java Protobuf-lite code for the Protobufs in this project. See
    // https://github.com/google/protobuf-gradle-plugin#customizing-protobuf-compilation
    // for more information.
    generateProtoTasks {
        all().each { task ->
            task.builtins {
                java {
                    option 'lite'
                }
            }
        }
    }
}

if (project.hasProperty("coverage")) {
    tasks.withType(Test).configureEach {
        jacoco.includeNoLocationClasses = true
        jacoco.excludes = ['jdk.internal.*']
    }

    androidComponents {
        onVariants(selector().all()) { variant ->
            tasks.register("jacoco${variant.name.capitalize()}TestReport", JacocoReport) {
                dependsOn "test${variant.name.capitalize()}UnitTest"

                reports {
                    xml.required = true
                    html.required = true
                }

                def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*',
                                  '**/*Test*.*', 'android/**/*.*', '**/*$[0-9].*']
                def kotlinDebugTree = fileTree(dir: "$project.layout.buildDirectory/tmp/kotlin-classes/${variant.name}", excludes: fileFilter)
                def javaDebugTree = fileTree(dir: "$project.layout.buildDirectory/intermediates/classes/${variant.flavorName ?: ''}/${variant.buildType}",
                        excludes: fileFilter)
                def mainSrc = "$project.projectDir/src/main/java"

                sourceDirectories.setFrom(files([mainSrc]))
                classDirectories.setFrom(files([kotlinDebugTree, javaDebugTree]))
                executionData.setFrom(fileTree(dir: project.layout.buildDirectory, includes: [
                    "jacoco/test${variant.name.capitalize()}UnitTest.exec",
                    'outputs/code-coverage/connected/*coverage.ec'
                ]))
            }
        }
    }

    android {
        buildTypes {
            debug {
                testCoverageEnabled = true
            }
        }
    }
}

// Work around generated SafeArgs code hitting USELESS_CAST warnings with Kotlin 2.3+
// (https://issuetracker.google.com/issues/458082829). Suppress as generateSafeArgs' own
// final action, not a separate finalizedBy task: finalizedBy isn't ordered before the
// Kotlin compile that consumes the output, so it races and fails under -Werror.
tasks.matching { it.name.startsWith("generateSafeArgs") }.configureEach {
    doLast {
        outputs.files.asFileTree.matching { include "**/*.kt" }.each { File f ->
            if (!f.text.contains('@file:Suppress("USELESS_CAST")')) {
                f.text =
"""@file:Suppress("USELESS_CAST")

${f.text}"""
            }
        }
    }
}

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
}

mozilla {
    ktlintSourcePaths = ["src/**/*.kt", "!**/build/**/*.kt"]
}

tasks.register("detekt", Exec) {
    group = "verification"
    description = "Run detekt static analysis."
    workingDir file("${gradle.mozconfig.topsrcdir}")
    commandLine "./mach", "gradle", "-p", "mobile/android/fenix", ":detekt"
}

[Dauer der Verarbeitung: 0.30 Sekunden, vorverarbeitet 2026-08-26]