1 // Allow installing Gradle plugins from the Mozilla Maven repositories
5 url "https://nightly.maven.mozilla.org/maven2"
8 url "https://maven.mozilla.org/maven2"
12 classpath "org.mozilla.components:tooling-glean-gradle:${Versions.mozilla_android_components}"
18 id "com.jetbrains.python.envs" version "0.0.26"
21 apply plugin: 'com.android.application'
22 apply plugin: 'kotlin-android'
23 apply plugin: 'kotlin-android-extensions'
24 apply plugin: 'kotlin-kapt'
25 apply plugin: 'jacoco'
26 apply from: "$project.rootDir/automation/gradle/versionCode.gradle"
27 apply plugin: 'androidx.navigation.safeargs.kotlin'
28 apply plugin: 'com.google.android.gms.oss-licenses-plugin'
31 import com.android.build.OutputFile
32 import org.gradle.internal.logging.text.StyledTextOutput.Style
33 import org.gradle.internal.logging.text.StyledTextOutputFactory
34 import org.mozilla.fenix.gradle.tasks.LintUnitTestRunner
36 import static org.gradle.api.tasks.testing.TestResult.ResultType
41 applicationId "org.mozilla"
42 minSdkVersion Config.minSdkVersion
43 targetSdkVersion Config.targetSdkVersion
45 versionName Config.generateDebugVersionName()
46 vectorDrawables.useSupportLibrary = true
47 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
48 testInstrumentationRunnerArguments clearPackageData: 'true'
49 resValue "bool", "IS_DEBUG", "false"
50 buildConfigField "boolean", "USE_RELEASE_VERSIONING", "false"
51 buildConfigField "String", "AMO_COLLECTION", "\"7e8d6dc651b54ab385fb8791bf9dac\""
52 manifestPlaceholders = [
53 "isRaptorEnabled": "false",
54 "deepLinkScheme": "fenix-dev"
58 def releaseTemplate = {
61 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
62 matchingFallbacks = ['release'] // Use on the "release" build type in dependencies (AARs)
69 applicationIdSuffix ".fenix.debug"
70 manifestPlaceholders.isRaptorEnabled = "true"
71 resValue "bool", "IS_DEBUG", "true"
72 pseudoLocalesEnabled true
74 forPerformanceTest releaseTemplate >> { // the ">>" concatenates the raptor-specific options with the template
75 manifestPlaceholders.isRaptorEnabled = "true"
76 applicationIdSuffix ".fenix.performancetest"
78 manifestPlaceholders = [
79 // Since we configure this build to behave like a "fennec" flavored build, we need
80 // to set a shared user id for the manifest. The actual values does not matter.
81 // However we pick a unique value to not "clash" with other Fenix/Fennec builds
82 // installed on the device.
83 "sharedUserId": "org.mozilla.fenix.performancetest.sharedID"
86 fenixNightly releaseTemplate >> {
87 applicationIdSuffix ".fenix.nightly"
88 buildConfigField "boolean", "USE_RELEASE_VERSIONING", "true"
89 manifestPlaceholders = ["deepLinkScheme": "fenix-nightly"]
91 fenixBeta releaseTemplate >> {
92 applicationIdSuffix ".fenix.beta"
93 buildConfigField "boolean", "USE_RELEASE_VERSIONING", "true"
94 manifestPlaceholders = ["deepLinkScheme": "fenix-beta"]
96 fenixProduction releaseTemplate >> {
97 applicationIdSuffix ".fenix"
98 buildConfigField "boolean", "USE_RELEASE_VERSIONING", "true"
99 manifestPlaceholders = ["deepLinkScheme": "fenix"]
101 fennecProduction releaseTemplate >> {
102 buildConfigField "boolean", "USE_RELEASE_VERSIONING", "true"
103 applicationIdSuffix ".firefox"
104 manifestPlaceholders = [
105 // This release type is meant to replace Firefox (Release channel) and therefore needs to inherit
106 // its sharedUserId for all eternity. See:
107 // https://searchfox.org/mozilla-central/search?q=moz_android_shared_id&case=false®exp=false&path=
108 // Shipping an app update without sharedUserId can have
109 // fatal consequences. For example see:
110 // - https://issuetracker.google.com/issues/36924841
111 // - https://issuetracker.google.com/issues/36905922
112 "sharedUserId": "org.mozilla.firefox.sharedID",
113 "deepLinkScheme": "fenix"
116 fennecBeta releaseTemplate >> {
117 buildConfigField "boolean", "USE_RELEASE_VERSIONING", "true"
118 applicationIdSuffix ".firefox_beta"
119 manifestPlaceholders = [
120 // This release type is meant to replace Firefox (Release channel) and therefore needs to inherit
121 // its sharedUserId for all eternity. See:
122 // https://searchfox.org/mozilla-central/search?q=moz_android_shared_id&case=false®exp=false&path=
123 // Shipping an app update without sharedUserId can have
124 // fatal consequences. For example see:
125 // - https://issuetracker.google.com/issues/36924841
126 // - https://issuetracker.google.com/issues/36905922
127 "sharedUserId": "org.mozilla.firefox.sharedID",
128 "deepLinkScheme": "fenix-beta"
131 fennecNightly releaseTemplate >> {
132 buildConfigField "boolean", "USE_RELEASE_VERSIONING", "true"
133 applicationIdSuffix ".fennec_aurora"
134 manifestPlaceholders = [
135 // This release type is meant to replace Firefox (Release channel) and therefore needs to inherit
136 // its sharedUserId for all eternity. See:
137 // https://searchfox.org/mozilla-central/search?q=moz_android_shared_id&case=false®exp=false&path=
138 // Shipping an app update without sharedUserId can have
139 // fatal consequences. For example see:
140 // - https://issuetracker.google.com/issues/36924841
141 // - https://issuetracker.google.com/issues/36905922
142 "sharedUserId": "org.mozilla.fennec.sharedID",
143 "deepLinkScheme": "fenix-nightly"
148 variantFilter { // There's a "release" build type that exists by default that we don't use (it's replaced by "nightly" and "beta")
149 if (buildType.name == 'release') {
153 // Current build variant setup:
155 // | geckoNightly | geckoBeta |
156 // |--------------------|---------------|-----------|
157 // | debug | ✅ | ✅ | Both variants for testing and development.
158 // | forPerformanceTest | ✅ | ✅ | Both variants unless the perf team only cares about Nightly (TBD).
159 // | fenixNightly | ✅ | ✅ | Built with both, but only the "geckoNightly" one is published to Google Play
160 // | fenixBeta | ❌ | ✅ | Fenix Beta ships with GV Beta
161 // | fenixProduction | ❌ | ✅ | Fenix Production ships with GV Beta
162 // | fennecProduction | ❌ | ✅ | Fenix build to replace production Firefox builds
163 // | fennecBeta | ❌ | ✅ | Fenix build to replace beta Firefox builds
164 // | fennecNightly | ✅ | ❌ | Fenix build to replace Nightly Firefox builds
166 def flavors = flavors*.name.toString().toLowerCase()
168 if (buildType.name == 'fenixBeta' && flavors.contains("geckonightly")) {
172 if (buildType.name == 'fenixProduction' && flavors.contains("geckonightly")) {
176 if ((buildType.name == 'fennecProduction' || buildType.name == 'fennecBeta') && flavors.contains("geckonightly")) {
180 if (buildType.name == 'fennecNightly' && flavors.contains("geckobeta")) {
186 // All JavaScript code used internally by GeckoView is packaged in a
187 // file called omni.ja. If this file is compressed in the APK,
188 // GeckoView must uncompress it before it can do anything else which
189 // causes a significant delay on startup.
194 execution 'ANDROIDX_TEST_ORCHESTRATOR'
195 unitTests.includeAndroidResources = true
196 animationsDisabled = true
199 flavorDimensions "engine"
203 resources.srcDirs += ['src/androidTest/resources']
206 java.srcDirs = ['src/migration/java']
207 manifest.srcFile "src/migration/AndroidManifest.xml"
210 java.srcDirs = ['src/migration/java']
211 manifest.srcFile "src/migration/AndroidManifest.xml"
214 java.srcDirs = ['src/migration/java']
215 manifest.srcFile "src/migration/AndroidManifest.xml"
218 // We want our performance test builds to use the same code as our "fennec" flavor builds
219 // since those builds will ship to our large user base.
220 java.srcDirs = ['src/migration/java']
221 manifest.srcFile "src/migration/AndroidManifest.xml"
241 include "x86", "armeabi-v7a", "arm64-v8a", "x86_64"
246 sourceCompatibility JavaVersion.VERSION_1_8
247 targetCompatibility JavaVersion.VERSION_1_8
251 lintConfig file("lint.xml")
255 exclude 'META-INF/atomicfu.kotlin_module'
259 unitTests.returnDefaultValues = true
263 def baseVersionCode = generatedVersionCode
265 android.applicationVariants.all { variant ->
267 // -------------------------------------------------------------------------------------------------
268 // Set up kotlin-allopen plugin for writing tests
269 // -------------------------------------------------------------------------------------------------
271 boolean hasTest = gradle.startParameter.taskNames.find { it.contains("test") || it.contains("Test") } != null
273 apply plugin: 'kotlin-allopen'
275 annotation("org.mozilla.fenix.utils.OpenClass")
279 // -------------------------------------------------------------------------------------------------
280 // Generate version codes for builds
281 // -------------------------------------------------------------------------------------------------
283 def isDebug = variant.buildType.resValues['IS_DEBUG']?.value ?: false
284 def useReleaseVersioning = variant.buildType.buildConfigFields['USE_RELEASE_VERSIONING']?.value ?: false
285 def versionName = Config.releaseVersionName(project)
287 println("----------------------------------------------")
288 println("Variant name: " + variant.name)
289 println("Application ID: " + [variant.mergedFlavor.applicationId, variant.buildType.applicationIdSuffix].findAll().join())
290 println("Build type: " + variant.buildType.name)
291 println("Flavor: " + variant.flavorName)
292 println("Telemetry enabled: " + !isDebug)
294 if (useReleaseVersioning) {
295 // The Google Play Store does not allow multiple APKs for the same app that all have the
296 // same version code. Therefore we need to have different version codes for our ARM and x86
299 // Our generated version code now has a length of 9 (See automation/gradle/versionCode.gradle).
300 // Our x86 builds need a higher version code to avoid installing ARM builds on an x86 device
301 // with ARM compatibility mode.
303 variant.outputs.each { output ->
304 def abi = output.getFilter(OutputFile.ABI)
306 def versionCodeOverride
307 if (variant.name.contains("Fennec")) {
308 versionCodeOverride = Config.generateFennecVersionCode(abi)
309 } else if (abi == "x86_64") {
310 versionCodeOverride = baseVersionCode + 3
311 } else if (abi == "x86") {
312 versionCodeOverride = baseVersionCode + 2
313 } else if (abi == "arm64-v8a") {
314 versionCodeOverride = baseVersionCode + 1
315 } else if (abi == "armeabi-v7a") {
316 versionCodeOverride = baseVersionCode
318 throw RuntimeException("Unknown ABI: $abi")
321 println("versionCode for $abi = $versionCodeOverride")
323 output.versionNameOverride = versionName
324 output.versionCodeOverride = versionCodeOverride
328 // -------------------------------------------------------------------------------------------------
329 // BuildConfig: Set variables for Sentry, Crash Reporting, and Telemetry
330 // -------------------------------------------------------------------------------------------------
332 buildConfigField 'String', 'SENTRY_TOKEN', 'null'
334 buildConfigField 'boolean', 'CRASH_REPORTING', 'true'
335 // Reading sentry token from local file (if it exists). In a release task on taskcluster it will be available.
337 def token = new File("${rootDir}/.sentry_token").text.trim()
338 buildConfigField 'String', 'SENTRY_TOKEN', '"' + token + '"'
339 } catch (FileNotFoundException ignored) {}
341 buildConfigField 'boolean', 'CRASH_REPORTING', 'false'
345 buildConfigField 'boolean', 'TELEMETRY', 'true'
347 buildConfigField 'boolean', 'TELEMETRY', 'false'
350 def buildDate = Config.generateBuildDate()
351 buildConfigField 'String', 'BUILD_DATE', '"' + buildDate + '"'
353 def variantName = variant.getName()
355 // -------------------------------------------------------------------------------------------------
356 // Adjust: Read token from local file if it exists (Only release builds)
357 // -------------------------------------------------------------------------------------------------
359 print("Adjust token: ")
363 def token = new File("${rootDir}/.adjust_token").text.trim()
364 buildConfigField 'String', 'ADJUST_TOKEN', '"' + token + '"'
365 println "(Added from .adjust_token file)"
366 } catch (FileNotFoundException ignored) {
367 buildConfigField 'String', 'ADJUST_TOKEN', 'null'
371 buildConfigField 'String', 'ADJUST_TOKEN', 'null'
375 // -------------------------------------------------------------------------------------------------
376 // Leanplum: Read token from local file if it exists
377 // -------------------------------------------------------------------------------------------------
379 print("Leanplum token: ")
382 def parts = new File("${rootDir}/.leanplum_token").text.trim().split(":")
385 buildConfigField 'String', 'LEANPLUM_ID', '"' + id + '"'
386 buildConfigField 'String', 'LEANPLUM_TOKEN', '"' + key + '"'
387 println "(Added from .leanplum_token file)"
388 } catch (FileNotFoundException ignored) {
389 buildConfigField 'String', 'LEANPLUM_ID', 'null'
390 buildConfigField 'String', 'LEANPLUM_TOKEN', 'null'
394 // -------------------------------------------------------------------------------------------------
395 // Digital Asset Links: Read token from local file if it exists
396 // -------------------------------------------------------------------------------------------------
398 print("Digital Asset Links token: ")
401 def token = new File("${rootDir}/.digital_asset_links_token").text.trim()
402 buildConfigField 'String', 'DIGITAL_ASSET_LINKS_TOKEN', '"' + token + '"'
403 println "(Added from .digital_asset_links_token file)"
404 } catch (FileNotFoundException ignored) {
405 buildConfigField 'String', 'DIGITAL_ASSET_LINKS_TOKEN', 'null'
409 // -------------------------------------------------------------------------------------------------
410 // MLS: Read token from local file if it exists
411 // -------------------------------------------------------------------------------------------------
416 def token = new File("${rootDir}/.mls_token").text.trim()
417 buildConfigField 'String', 'MLS_TOKEN', '"' + token + '"'
418 println "(Added from .mls_token file)"
419 } catch (FileNotFoundException ignored) {
420 buildConfigField 'String', 'MLS_TOKEN', '""'
429 // Generate Kotlin code and markdown docs for the Fenix Glean metrics.
430 ext.gleanGenerateMarkdownDocs = true
431 ext.gleanDocsDirectory = "$rootDir/docs"
432 apply plugin: "org.mozilla.telemetry.glean-gradle-plugin"
435 geckoNightlyImplementation Deps.mozilla_browser_engine_gecko_nightly
436 geckoBetaImplementation Deps.mozilla_browser_engine_gecko_beta
438 implementation Deps.kotlin_stdlib
439 implementation Deps.kotlin_coroutines
440 implementation Deps.kotlin_coroutines_android
441 testImplementation Deps.kotlin_coroutines_test
442 implementation Deps.androidx_appcompat
443 implementation Deps.androidx_constraintlayout
444 implementation Deps.androidx_coordinatorlayout
446 implementation Deps.sentry
447 implementation Deps.osslicenses_library
449 implementation Deps.leanplum_core
450 implementation Deps.leanplum_fcm
452 implementation Deps.mozilla_concept_engine
453 implementation Deps.mozilla_concept_push
454 implementation Deps.mozilla_concept_storage
455 implementation Deps.mozilla_concept_sync
456 implementation Deps.mozilla_concept_toolbar
458 implementation Deps.mozilla_browser_awesomebar
459 implementation Deps.mozilla_feature_downloads
460 implementation Deps.mozilla_browser_domains
461 implementation Deps.mozilla_browser_icons
462 implementation Deps.mozilla_browser_menu
463 implementation Deps.mozilla_browser_search
464 implementation Deps.mozilla_browser_session
465 implementation Deps.mozilla_browser_state
466 implementation Deps.mozilla_browser_storage_sync
467 implementation Deps.mozilla_browser_toolbar
469 implementation Deps.mozilla_support_extensions
470 implementation Deps.mozilla_feature_addons
472 implementation Deps.mozilla_feature_accounts
473 implementation Deps.mozilla_feature_app_links
474 implementation Deps.mozilla_feature_awesomebar
475 implementation Deps.mozilla_feature_contextmenu
476 implementation Deps.mozilla_feature_customtabs
477 implementation Deps.mozilla_feature_downloads
478 implementation Deps.mozilla_feature_intent
479 implementation Deps.mozilla_feature_media
480 implementation Deps.mozilla_feature_prompts
481 implementation Deps.mozilla_feature_push
482 implementation Deps.mozilla_feature_pwa
483 implementation Deps.mozilla_feature_qr
484 implementation Deps.mozilla_feature_search
485 implementation Deps.mozilla_feature_session
486 implementation Deps.mozilla_feature_toolbar
487 implementation Deps.mozilla_feature_tabs
488 implementation Deps.mozilla_feature_findinpage
489 implementation Deps.mozilla_feature_site_permissions
490 implementation Deps.mozilla_feature_readerview
491 implementation Deps.mozilla_feature_tab_collections
492 implementation Deps.mozilla_feature_top_sites
493 implementation Deps.mozilla_feature_share
494 implementation Deps.mozilla_feature_accounts_push
495 implementation Deps.mozilla_feature_webcompat
496 implementation Deps.mozilla_feature_webnotifications
498 implementation Deps.mozilla_service_sync_logins
499 implementation Deps.mozilla_service_firefox_accounts
500 implementation Deps.mozilla_service_glean
501 implementation Deps.mozilla_service_experiments
502 implementation Deps.mozilla_service_location
505 implementation Deps.mozilla_support_base
506 implementation Deps.mozilla_support_ktx
507 implementation Deps.mozilla_support_rustlog
508 implementation Deps.mozilla_support_utils
509 implementation Deps.mozilla_support_locale
511 implementation Deps.mozilla_support_migration
513 implementation Deps.mozilla_ui_colors
514 implementation Deps.mozilla_ui_icons
515 implementation Deps.mozilla_ui_publicsuffixlist
517 implementation Deps.mozilla_lib_crash
518 implementation Deps.mozilla_lib_push_firebase
519 implementation Deps.mozilla_lib_dataprotect
520 debugImplementation Deps.leakcanary
522 implementation Deps.androidx_legacy
523 implementation Deps.androidx_biometric
524 implementation Deps.androidx_paging
525 implementation Deps.androidx_preference
526 implementation Deps.androidx_fragment
527 implementation Deps.androidx_navigation_fragment
528 implementation Deps.androidx_navigation_ui
529 implementation Deps.androidx_recyclerview
530 implementation Deps.androidx_lifecycle_livedata
531 implementation Deps.androidx_lifecycle_runtime
532 implementation Deps.androidx_lifecycle_viewmodel
533 implementation Deps.androidx_core
534 implementation Deps.androidx_core_ktx
535 implementation Deps.androidx_transition
536 implementation Deps.androidx_work_ktx
537 implementation Deps.google_material
539 implementation Deps.google_flexbox
541 implementation Deps.lottie
543 implementation Deps.adjust
544 implementation Deps.installreferrer // Required by Adjust
546 implementation Deps.google_ads_id // Required for the Google Advertising ID
548 androidTestImplementation Deps.uiautomator
549 // Removed pending AndroidX fixes
550 androidTestImplementation "tools.fastlane:screengrab:2.0.0"
551 // androidTestImplementation "br.com.concretesolutions:kappuccino:1.2.1"
553 androidTestImplementation Deps.espresso_core, {
554 exclude group: 'com.android.support', module: 'support-annotations'
557 androidTestImplementation(Deps.espresso_contrib) {
558 exclude module: 'appcompat-v7'
559 exclude module: 'support-v4'
560 exclude module: 'support-annotations'
561 exclude module: 'recyclerview-v7'
562 exclude module: 'design'
563 exclude module: 'espresso-core'
566 androidTestImplementation Deps.androidx_test_core
567 androidTestImplementation Deps.espresso_idling_resources
568 androidTestImplementation Deps.espresso_intents
570 androidTestImplementation Deps.tools_test_runner
571 androidTestImplementation Deps.tools_test_rules
572 androidTestUtil Deps.orchestrator
573 androidTestImplementation Deps.espresso_core, {
574 exclude group: 'com.android.support', module: 'support-annotations'
577 androidTestImplementation Deps.androidx_junit
578 androidTestImplementation Deps.androidx_work_testing
579 androidTestImplementation Deps.mockwebserver
580 testImplementation Deps.mozilla_support_test
581 testImplementation Deps.androidx_junit
582 testImplementation Deps.androidx_work_testing
583 testImplementation (Deps.robolectric) {
584 exclude group: 'org.apache.maven'
587 testImplementation 'org.apache.maven:maven-ant-tasks:2.1.3'
588 implementation Deps.mozilla_support_rusthttp
590 testImplementation Deps.mockito_core
591 androidTestImplementation Deps.mockito_android
592 testImplementation Deps.mockk
594 // For the initial release of Glean 19, we require consumer applications to
595 // depend on a separate library for unit tests. This will be removed in future releases.
596 testImplementation "org.mozilla.telemetry:glean-forUnitTests:${project.ext.glean_version}"
598 lintChecks project(":mozilla-lint-rules")
601 if (project.hasProperty("raptor")) {
602 android.defaultConfig.manifestPlaceholders.isRaptorEnabled = "true"
605 if (project.hasProperty("coverage")) {
606 tasks.withType(Test) {
607 jacoco.includeNoLocationClasses = true
610 android.applicationVariants.all { variant ->
611 task "jacoco${variant.name.capitalize()}TestReport"(type: JacocoReport, dependsOn: "test${variant.name.capitalize()}UnitTest") {
617 def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*',
618 '**/*Test*.*', 'android/**/*.*', '**/*$[0-9].*']
619 def kotlinDebugTree = fileTree(dir: "$project.buildDir/tmp/kotlin-classes/${variant.name}", excludes: fileFilter)
620 def javaDebugTree = fileTree(dir: "$project.buildDir/intermediates/classes/${variant.flavorName}/${variant.buildType.name}",
621 excludes: fileFilter)
622 def mainSrc = "$project.projectDir/src/main/java"
624 sourceDirectories = files([mainSrc])
625 classDirectories = files([kotlinDebugTree, javaDebugTree])
626 executionData = fileTree(dir: project.buildDir, includes: [
627 "jacoco/test${variant.name.capitalize()}UnitTest.exec", 'outputs/code-coverage/connected/*coverage.ec'
635 testCoverageEnabled true
641 // -------------------------------------------------------------------------------------------------
642 // Task for printing APK information for the requested variant
643 // Usage: "./gradlew printVariants
644 // -------------------------------------------------------------------------------------------------
647 def variants = android.applicationVariants.collect {[
648 apks: it.variantData.outputScope.apkDatas.collect {[
649 abi: it.filters.find { it.filterType == 'ABI' }.identifier,
650 fileName: it.outputFileName,
652 build_type: it.buildType.name,
653 engine: it.productFlavors.find { it.dimension == 'engine' }.name,
656 // AndroidTest is a special case not included above
660 fileName: 'app-geckoNightly-debug-androidTest.apk',
662 build_type: 'androidTest',
663 engine: 'geckoNightly',
666 println 'variants: ' + groovy.json.JsonOutput.toJson(variants)
670 task buildTranslationArray {
671 def foundLocales = new StringBuilder()
672 foundLocales.append("new String[]{")
674 fileTree("src/main/res").visit { FileVisitDetails details ->
675 if(details.file.path.endsWith("/strings.xml")){
676 def languageCode = details.file.parent.tokenize('/').last().replaceAll('values-','').replaceAll('-r','-')
677 languageCode = (languageCode == "values") ? "en-US" : languageCode
678 foundLocales.append("\"").append(languageCode).append("\"").append(",")
682 foundLocales.append("}")
683 def foundLocalesString = foundLocales.toString().replaceAll(',}','}')
684 android.defaultConfig.buildConfigField "String[]", "SUPPORTED_LOCALE_ARRAY", foundLocalesString
687 task lintUnitTestRunner(type: LintUnitTestRunner)
691 // Format test output. Ported from AC #2401
692 tasks.matching {it instanceof Test}.all {
693 systemProperty "robolectric.logging", "stdout"
694 systemProperty "logging.test-mode", "true"
696 testLogging.events = []
698 def out = services.get(StyledTextOutputFactory).create("tests")
700 beforeSuite { descriptor ->
701 if (descriptor.getClassName() != null) {
702 out.style(Style.Header).println("\nSUITE: " + descriptor.getClassName())
706 beforeTest { descriptor ->
707 out.style(Style.Description).println(" TEST: " + descriptor.getName())
710 onOutput { descriptor, event ->
711 logger.lifecycle(" " + event.message.trim())
714 afterTest { descriptor, result ->
715 switch (result.getResultType()) {
716 case ResultType.SUCCESS:
717 out.style(Style.Success).println(" SUCCESS")
720 case ResultType.FAILURE:
721 out.style(Style.Failure).println(" FAILURE")
722 logger.lifecycle("", result.getException())
725 case ResultType.SKIPPED:
726 out.style(Style.Info).println(" SKIPPED")
734 if (gradle.hasProperty('localProperties.dependencySubstitutions.geckoviewTopsrcdir')) {
735 if (gradle.hasProperty('localProperties.dependencySubstitutions.geckoviewTopobjdir')) {
736 ext.topobjdir = gradle."localProperties.dependencySubstitutions.geckoviewTopobjdir"
738 ext.topsrcdir = gradle."localProperties.dependencySubstitutions.geckoviewTopsrcdir"
739 apply from: "${topsrcdir}/substitute-local-geckoview.gradle"
742 if (gradle.hasProperty('localProperties.autoPublish.android-components.dir')) {
743 ext.acSrcDir = gradle."localProperties.autoPublish.android-components.dir"
744 apply from: "../${acSrcDir}/substitute-local-ac.gradle"
747 if (gradle.hasProperty('localProperties.autoPublish.application-services.dir')) {
748 ext.appServicesSrcDir = gradle."localProperties.autoPublish.application-services.dir"
749 apply from: "../${appServicesSrcDir}/build-scripts/substitute-local-appservices.gradle"