1buildDir "${topobjdir}/gradle/build/mobile/android/geckoview"
2
3import groovy.json.JsonOutput
4
5apply plugin: 'com.android.library'
6apply plugin: 'checkstyle'
7apply plugin: 'kotlin-android'
8
9apply from: "${topsrcdir}/mobile/android/gradle/product_flavors.gradle"
10
11// The SDK binding generation tasks depend on the JAR creation task of the
12// :annotations project.
13evaluationDependsOn(':annotations')
14
15android {
16    buildToolsVersion project.ext.buildToolsVersion
17    compileSdkVersion project.ext.compileSdkVersion
18
19    useLibrary 'android.test.runner'
20    useLibrary 'android.test.base'
21    useLibrary 'android.test.mock'
22
23    defaultConfig {
24        targetSdkVersion project.ext.targetSdkVersion
25        minSdkVersion project.ext.minSdkVersion
26        manifestPlaceholders = project.ext.manifestPlaceholders
27        multiDexEnabled true
28
29        versionCode project.ext.versionCode
30        versionName project.ext.versionName
31        consumerProguardFiles 'proguard-rules.txt'
32
33        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
34
35        buildConfigField 'String', "GRE_MILESTONE", "\"${mozconfig.substs.GRE_MILESTONE}\""
36        buildConfigField 'String', "MOZ_APP_BASENAME", "\"${mozconfig.substs.MOZ_APP_BASENAME}\"";
37
38        // For the benefit of future archaeologists:
39        // GRE_BUILDID is exactly the same as MOZ_APP_BUILDID unless you're running
40        // on XULRunner, which is never the case on Android.
41        buildConfigField 'String', "MOZ_APP_BUILDID", "\"${project.ext.buildId}\"";
42        buildConfigField 'String', "MOZ_APP_ID", "\"${mozconfig.substs.MOZ_APP_ID}\"";
43        buildConfigField 'String', "MOZ_APP_NAME", "\"${mozconfig.substs.MOZ_APP_NAME}\"";
44        buildConfigField 'String', "MOZ_APP_VENDOR", "\"${mozconfig.substs.MOZ_APP_VENDOR}\"";
45        buildConfigField 'String', "MOZ_APP_VERSION", "\"${mozconfig.substs.MOZ_APP_VERSION}\"";
46        buildConfigField 'String', "MOZ_APP_DISPLAYNAME", "\"${mozconfig.substs.MOZ_APP_DISPLAYNAME}\"";
47        buildConfigField 'String', "MOZ_APP_UA_NAME", "\"${mozconfig.substs.MOZ_APP_UA_NAME}\"";
48        buildConfigField 'String', "MOZ_UPDATE_CHANNEL", "\"${mozconfig.substs.MOZ_UPDATE_CHANNEL}\"";
49
50        // MOZILLA_VERSION is oddly quoted from autoconf, but we don't have to handle it specially in Gradle.
51        buildConfigField 'String', "MOZILLA_VERSION", "\"${mozconfig.substs.MOZILLA_VERSION}\"";
52        buildConfigField 'String', "OMNIJAR_NAME", "\"${mozconfig.substs.OMNIJAR_NAME}\"";
53
54        // Keep in sync with actual user agent in nsHttpHandler::BuildUserAgent
55        buildConfigField 'String', "USER_AGENT_GECKOVIEW_MOBILE", "\"Mozilla/5.0 (Android \" + android.os.Build.VERSION.RELEASE + \"; Mobile; rv:\" + ${mozconfig.defines.MOZILLA_UAVERSION} + \") Gecko/\" + ${mozconfig.defines.MOZILLA_UAVERSION} + \" Firefox/\" + ${mozconfig.defines.MOZILLA_UAVERSION}";
56        buildConfigField 'String', "USER_AGENT_GECKOVIEW_TABLET", "\"Mozilla/5.0 (Android \" + android.os.Build.VERSION.RELEASE + \"; Tablet; rv:\" + ${mozconfig.defines.MOZILLA_UAVERSION} + \") Gecko/\" + ${mozconfig.defines.MOZILLA_UAVERSION} + \" Firefox/\" + ${mozconfig.defines.MOZILLA_UAVERSION}";
57
58        buildConfigField 'int', 'MIN_SDK_VERSION', mozconfig.substs.MOZ_ANDROID_MIN_SDK_VERSION;
59
60        // Is the underlying compiled C/C++ code compiled with --enable-debug?
61        buildConfigField 'boolean', 'DEBUG_BUILD', mozconfig.substs.MOZ_DEBUG ? 'true' : 'false';
62
63        // See this wiki page for more details about channel specific build defines:
64        // https://wiki.mozilla.org/Platform/Channel-specific_build_defines
65        // This makes no sense for GeckoView and should be removed as soon as possible.
66        buildConfigField 'boolean', 'RELEASE_OR_BETA', mozconfig.substs.RELEASE_OR_BETA ? 'true' : 'false';
67        // This makes no sense for GeckoView and should be removed as soon as possible.
68        buildConfigField 'boolean', 'NIGHTLY_BUILD', mozconfig.substs.NIGHTLY_BUILD ? 'true' : 'false';
69        // This makes no sense for GeckoView and should be removed as soon as possible.
70        buildConfigField 'boolean', 'MOZ_CRASHREPORTER', mozconfig.substs.MOZ_CRASHREPORTER ? 'true' : 'false';
71
72        buildConfigField 'int', 'MOZ_ANDROID_CONTENT_SERVICE_COUNT', mozconfig.substs.MOZ_ANDROID_CONTENT_SERVICE_COUNT;
73
74        // Official corresponds, roughly, to whether this build is performed on
75        // Mozilla's continuous integration infrastructure. You should disable
76        // developer-only functionality when this flag is set.
77        // This makes no sense for GeckoView and should be removed as soon as possible.
78        buildConfigField 'boolean', 'MOZILLA_OFFICIAL', mozconfig.substs.MOZILLA_OFFICIAL ? 'true' : 'false';
79
80        // This env variable signifies whether we are running an isolated process build.
81        buildConfigField 'boolean', 'MOZ_ANDROID_CONTENT_SERVICE_ISOLATED_PROCESS', mozconfig.substs.MOZ_ANDROID_CONTENT_SERVICE_ISOLATED_PROCESS ? 'true' : 'false';
82    }
83
84    project.configureProductFlavors.delegate = it
85    project.configureProductFlavors()
86
87    compileOptions {
88        sourceCompatibility JavaVersion.VERSION_11
89        targetCompatibility JavaVersion.VERSION_11
90    }
91
92    dexOptions {
93        javaMaxHeapSize "32g"
94    }
95
96    lintOptions {
97        abortOnError false
98    }
99
100    sourceSets {
101        main {
102            java {
103                if (!mozconfig.substs.MOZ_ANDROID_HLS_SUPPORT) {
104                    exclude 'org/mozilla/gecko/media/GeckoHlsAudioRenderer.java'
105                    exclude 'org/mozilla/gecko/media/GeckoHlsPlayer.java'
106                    exclude 'org/mozilla/gecko/media/GeckoHlsRendererBase.java'
107                    exclude 'org/mozilla/gecko/media/GeckoHlsVideoRenderer.java'
108                    exclude 'org/mozilla/gecko/media/Utils.java'
109                }
110
111                if (mozconfig.substs.MOZ_WEBRTC) {
112                    srcDir "${topsrcdir}/dom/media/systemservices/android_video_capture/java/src"
113                    srcDir "${topsrcdir}/third_party/libwebrtc/sdk/android/api"
114                    srcDir "${topsrcdir}/third_party/libwebrtc/sdk/android/src"
115                    srcDir "${topsrcdir}/third_party/libwebrtc/rtc_base/java"
116                    srcDir "${topsrcdir}/third_party/libwebrtc/modules/audio_device/android/java"
117                }
118
119                srcDir "${topobjdir}/mobile/android/geckoview/src/main/java"
120            }
121
122            resources {
123                if (mozconfig.substs.MOZ_ASAN) {
124                    // If this is an ASAN build, include a `wrap.sh` for Android 8.1+ devices.  See
125                    // https://developer.android.com/ndk/guides/wrap-script.
126                    srcDir "${topsrcdir}/mobile/android/geckoview/src/asan/resources"
127                }
128            }
129
130            assets {
131            }
132
133            debug {
134                manifest.srcFile "${topobjdir}/mobile/android/geckoview/src/main/AndroidManifest_overlay.xml"
135            }
136
137            release {
138                manifest.srcFile "${topobjdir}/mobile/android/geckoview/src/main/AndroidManifest_overlay.xml"
139            }
140        }
141    }
142}
143
144tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) {
145    // Translate Kotlin messages like "w: ..." and "e: ..." into
146    // "...: warning: ..." and "...: error: ...", to make Treeherder understand.
147    def listener = {
148        if (it.startsWith("e: warnings found")) {
149            return
150        }
151
152        if (it.startsWith('w: ') || it.startsWith('e: ')) {
153            def matches = (it =~ /([ew]): (.+): \((\d+), (\d+)\): (.*)/)
154            if (!matches) {
155                logger.quiet "kotlinc message format has changed!"
156                if (it.startsWith('w: ')) {
157                    // For warnings, don't continue because we don't want to throw an
158                    // exception. For errors, we want the exception so that the new error
159                    // message format gets translated properly.
160                    return
161                }
162            }
163            def (_, type, file, line, column, message) = matches[0]
164            type = (type == 'w') ? 'warning' : 'error'
165            // Use logger.lifecycle, which does not go through stderr again.
166            logger.lifecycle "$file:$line:$column: $type: $message"
167        }
168    } as StandardOutputListener
169
170    kotlinOptions {
171        allWarningsAsErrors = true
172        jvmTarget = JavaVersion.VERSION_11
173    }
174
175    doFirst {
176        logging.addStandardErrorListener(listener)
177    }
178    doLast {
179        logging.removeStandardErrorListener(listener)
180    }
181}
182
183configurations {
184    withGeckoBinariesApi {
185        outgoing {
186            if (!mozconfig.substs.MOZ_ANDROID_GECKOVIEW_LITE) {
187                // The omni build provides glean-native
188                capability("org.mozilla.telemetry:glean-native:${project.ext.gleanVersion}")
189            }
190            afterEvaluate {
191                // Implicit capability
192                capability("org.mozilla.geckoview:${getArtifactId()}:${project.ext.versionNumber}")
193            }
194        }
195    }
196    // TODO: This is a workaround for a bug that was fixed in Gradle 7.
197    // The variant resolver _should_ pick the RuntimeOnly configuration when building
198    // the tests as those define the implicit :geckoview capability but it doesn't,
199    // so we manually define it here.
200    withGeckoBinariesRuntimeOnly {
201        outgoing {
202            afterEvaluate {
203                // Implicit capability
204                capability("org.mozilla.geckoview:geckoview:${project.ext.versionNumber}")
205            }
206        }
207    }
208}
209
210dependencies {
211    implementation "androidx.annotation:annotation:1.3.0"
212    implementation "androidx.legacy:legacy-support-v4:1.0.0"
213
214    implementation "com.google.android.gms:play-services-fido:18.1.0"
215    implementation "org.yaml:snakeyaml:1.24:android"
216
217    implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
218    implementation "androidx.lifecycle:lifecycle-common-java8:2.4.0"
219
220    if (mozconfig.substs.MOZ_ANDROID_HLS_SUPPORT) {
221        implementation project(":exoplayer2")
222    }
223
224    testImplementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
225    testImplementation 'junit:junit:4.13.1'
226    testImplementation 'org.robolectric:robolectric:4.7.3'
227    testImplementation 'org.mockito:mockito-core:3.11.2'
228
229    androidTestImplementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
230    androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2"
231    androidTestImplementation 'androidx.test:runner:1.4.0'
232    androidTestImplementation 'androidx.test:rules:1.4.0'
233    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
234    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
235
236    androidTestImplementation 'com.koushikdutta.async:androidasync:3.1.0'
237
238    androidTestImplementation 'androidx.multidex:multidex:2.0.1'
239}
240
241apply from: "${topsrcdir}/mobile/android/gradle/with_gecko_binaries.gradle"
242
243android.libraryVariants.all { variant ->
244    // See the notes in mobile/android/app/build.gradle for details on including
245    // Gecko binaries and the Omnijar.
246    if ((variant.productFlavors*.name).contains('withGeckoBinaries')) {
247        configureVariantWithGeckoBinaries(variant)
248    }
249
250    // Javadoc and Sources JAR configuration cribbed from
251    // https://github.com/mapbox/mapbox-gl-native/blob/d169ea55c1cfa85cd8bf19f94c5f023569f71810/platform/android/MapboxGLAndroidSDK/build.gradle#L85
252    // informed by
253    // https://code.tutsplus.com/tutorials/creating-and-publishing-an-android-library--cms-24582,
254    // and amended from numerous Stackoverflow posts.
255    def name = variant.name
256    def javadoc = task "javadoc${name.capitalize()}"(type: Javadoc) {
257        failOnError = false
258        description = "Generate Javadoc for build variant $name"
259        destinationDir = new File(destinationDir, variant.baseName)
260
261        // The javadoc task will not re-run if the previous run is still up-to-date,
262        // this is a problem for the javadoc lint, which needs to read the output of the task
263        // to determine if there are warnings or errors. To force that we pass a -Pandroid-lint
264        // parameter to all lints that can be used here to force running the task every time.
265        outputs.upToDateWhen {
266            !project.hasProperty('android-lint')
267        }
268
269        doFirst {
270            classpath = files(variant.javaCompileProvider.get().classpath.files)
271        }
272
273        def results = []
274        def listener = {
275            if (!it.toLowerCase().contains("warning:") && !it.toLowerCase().contains("error:")) {
276              // Likely not an error or a warning
277              return
278            }
279            // Like '/abs/path/to/topsrcdir/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/ContentBlocking.java:480: warning: no @return'
280            def matches = (it =~ /(.+):(\d+):.*(warning|error)(.*)/)
281            if (!matches) {
282                // could not parse, let's add it anyway since it's a warning or error
283                results << [path: "parsing-failed", lineno: 0, level: "error", message: it]
284                return
285            }
286            def (_, file, line, level, message) = matches[0]
287            results << [path: file, lineno: line, level: level, message: message]
288        } as StandardOutputListener
289
290        doFirst {
291            logging.addStandardErrorListener(listener)
292        }
293
294        doLast {
295            logging.removeStandardErrorListener(listener)
296
297            // We used to treat Javadoc warnings as errors here; now we rely on the
298            // `android-javadoc` linter to fail in the face of Javadoc warnings.
299            def resultsJson = JsonOutput.toJson(results)
300
301            file("$buildDir/reports").mkdirs()
302            file("$buildDir/reports/javadoc-results-${name}.json").write(resultsJson)
303        }
304
305        source = variant.sourceSets.collect({ it.java.srcDirs })
306        exclude '**/R.java', '**/BuildConfig.java'
307        include 'org/mozilla/geckoview/**.java'
308        options.addPathOption('sourcepath', ':').setValue(
309             variant.sourceSets.collect({ it.java.srcDirs }).flatten() +
310             variant.generateBuildConfigProvider.get().sourceOutputDir.asFile.get() +
311             variant.aidlCompileProvider.get().sourceOutputDir.asFile.get()
312        )
313        options.addStringOption("Xmaxwarns", "1000")
314
315        classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
316        classpath += variant.javaCompileProvider.get().classpath
317
318        options.memberLevel = JavadocMemberLevel.PROTECTED
319        options.source = 11
320        options.links("https://developer.android.com/reference")
321
322        options.docTitle = "GeckoView ${mozconfig.substs.MOZ_APP_VERSION} API"
323        options.header = "GeckoView ${mozconfig.substs.MOZ_APP_VERSION} API"
324        options.noTimestamp = true
325        options.noQualifiers = ['java.lang']
326        options.tags = ['hide:a:']
327    }
328
329    def javadocJar = task("javadocJar${name.capitalize()}", type: Jar, dependsOn: javadoc) {
330        archiveClassifier = 'javadoc'
331        from javadoc.destinationDir
332    }
333
334    // This task is used by `mach android geckoview-docs`.
335    task("javadocCopyJar${name.capitalize()}", type: Copy) {
336        from(javadocJar.destinationDirectory) {
337            include 'geckoview-*-javadoc.jar'
338            rename { _ -> 'geckoview-javadoc.jar' }
339        }
340        into javadocJar.destinationDirectory
341        dependsOn javadocJar
342    }
343
344    def sourcesJar = task("sourcesJar${name.capitalize()}", type: Jar) {
345        classifier 'sources'
346        description = "Generate Javadoc for build variant $name"
347        destinationDirectory =
348            file("${topobjdir}/mobile/android/geckoview/sources/${variant.baseName}")
349        from files(variant.sourceSets.collect({ it.java.srcDirs }).flatten())
350    }
351
352    task("checkstyle${name.capitalize()}", type: Checkstyle) {
353        classpath = variant.javaCompileProvider.get().classpath
354        // TODO: cleanup and include all sources
355        source = ['src/main/java/']
356        include '**/*.java'
357
358    }
359}
360
361checkstyle {
362    configDirectory = file(".")
363    configFile = file("checkstyle.xml")
364    toolVersion = "8.36.2"
365}
366
367android.libraryVariants.all { variant ->
368    if (variant.name == mozconfig.substs.GRADLE_ANDROID_GECKOVIEW_VARIANT_NAME) {
369        configureLibraryVariantWithJNIWrappers(variant, "Generated")
370    }
371}
372
373android.libraryVariants.all { variant ->
374    // At this point, the Android-Gradle plugin has created all the Android
375    // tasks and configurations.  This is the time for us to declare additional
376    // Glean files to package into AAR files.  This packs `metrics.yaml` in the
377    // root of the AAR, sibling to `AndroidManifest.xml` and `classes.jar`.  By
378    // default, consumers of the AAR will ignore this file, but consumers that
379    // look for it can find it (provided GeckoView is a `module()` dependency
380    // and not a `project()` dependency.)  Under the hood this uses that the
381    // task provided by `packageLibraryProvider` task is a Maven `Zip` task,
382    // and we can simply extend its inputs.  See
383    // https://android.googlesource.com/platform/tools/base/+/0cbe8846f7d02c0bb6f07156b9f4fde16d96d329/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/BundleAar.kt#94.
384    variant.packageLibraryProvider.get().from("${topsrcdir}/toolkit/components/telemetry/geckoview/streaming/metrics.yaml")
385}
386
387apply plugin: 'maven-publish'
388
389version = getVersionNumber()
390group = 'org.mozilla.geckoview'
391
392def getArtifactId() {
393    def id = "geckoview" + project.ext.artifactSuffix
394
395    if (!mozconfig.substs.MOZ_ANDROID_GECKOVIEW_LITE) {
396        id += "-omni"
397    }
398
399    if (mozconfig.substs.MOZILLA_OFFICIAL && !mozconfig.substs.MOZ_ANDROID_FAT_AAR_ARCHITECTURES) {
400        // In automation, per-architecture artifacts identify
401        // the architecture; multi-architecture artifacts don't.
402        // When building locally, we produce a "skinny AAR" with
403        // one target architecture masquerading as a "fat AAR"
404        // to enable Gradle composite builds to substitute this
405        // project into consumers easily.
406        id += "-${mozconfig.substs.ANDROID_CPU_ARCH}"
407    }
408
409    return id
410}
411
412publishing {
413    publications {
414        android.libraryVariants.all { variant ->
415            "${variant.name}"(MavenPublication) {
416                from components.findByName(variant.name)
417
418                pom {
419                    afterEvaluate {
420                        artifactId = getArtifactId()
421                    }
422
423                    url = 'https://geckoview.dev'
424
425                    licenses {
426                        license {
427                            name = 'The Mozilla Public License, v. 2.0'
428                            url = 'http://mozilla.org/MPL/2.0/'
429                            distribution = 'repo'
430                        }
431                    }
432
433                    scm {
434                        if (mozconfig.substs.MOZ_INCLUDE_SOURCE_INFO) {
435                            // URL is like "https://hg.mozilla.org/mozilla-central/rev/1e64b8a0c546a49459d404aaf930d5b1f621246a".
436                            connection = "scm::hg::${mozconfig.substs.MOZ_SOURCE_REPO}"
437                            url = mozconfig.substs.MOZ_SOURCE_URL
438                            tag = mozconfig.substs.MOZ_SOURCE_CHANGESET
439                        } else {
440                            // Default to mozilla-central.
441                            connection = 'scm::hg::https://hg.mozilla.org/mozilla-central/'
442                            url = 'https://hg.mozilla.org/mozilla-central/'
443                        }
444                    }
445                }
446
447                // Javadoc and sources for developer ergononomics.
448                artifact tasks["javadocJar${variant.name.capitalize()}"]
449                artifact tasks["sourcesJar${variant.name.capitalize()}"]
450            }
451        }
452    }
453    repositories {
454        maven {
455            url = "${topobjdir}/gradle/maven"
456        }
457    }
458}
459
460// This is all related to the withGeckoBinaries approach; see
461// mobile/android/gradle/with_gecko_binaries.gradle.
462afterEvaluate {
463    // The bundle tasks are only present when the particular configuration is
464    // being built, so this task might not exist.  (This is due to the way the
465    // Android Gradle plugin defines things during configuration.)
466    def bundleWithGeckoBinaries = tasks.findByName('bundleWithGeckoBinariesReleaseAar')
467    if (!bundleWithGeckoBinaries) {
468        return
469    }
470
471    // Remove default configuration, which is the release configuration, when
472    // we're actually building withGeckoBinaries.  This makes `gradle install`
473    // install the withGeckoBinaries artifacts, not the release artifacts (which
474    // are withoutGeckoBinaries and not suitable for distribution.)
475    def Configuration archivesConfig = project.getConfigurations().getByName('archives')
476    archivesConfig.artifacts.removeAll { it.extension.equals('aar') }
477
478    // For now, ensure Kotlin is only used in tests.
479    android.sourceSets.all { sourceSet ->
480        if (sourceSet.name.startsWith('test') || sourceSet.name.startsWith('androidTest')) {
481            return
482        }
483        (sourceSet.java.srcDirs + sourceSet.kotlin.srcDirs).each {
484            if (!fileTree(it, { include '**/*.kt' }).empty) {
485                throw new GradleException("Kotlin used in non-test directory ${it.path}")
486            }
487        }
488    }
489}
490
491// Bug 1353055 - Strip 'vars' debugging information to agree with moz.build.
492apply from: "${topsrcdir}/mobile/android/gradle/debug_level.gradle"
493android.libraryVariants.all configureVariantDebugLevel
494
495// There's nothing specific to the :geckoview project here -- this just needs to
496// be somewhere where the Android plugin is available so that we can fish the
497// path to "android.jar".
498task("generateSDKBindings", type: JavaExec) {
499    classpath project(':annotations').jar.archivePath
500    classpath project(':annotations').compileJava.classpath
501    classpath project(':annotations').sourceSets.main.runtimeClasspath
502
503    // To use the lint APIs: "Lint must be invoked with the System property
504    // com.android.tools.lint.bindir pointing to the ANDROID_SDK tools
505    // directory"
506    systemProperties = [
507        'com.android.tools.lint.bindir': "${android.sdkDirectory}/tools",
508    ]
509
510    mainClass = 'org.mozilla.gecko.annotationProcessors.SDKProcessor'
511    // We only want to generate bindings for the main framework JAR,
512    // but not any of the additional android.test libraries.
513    args android.bootClasspath.findAll { it.getName().startsWith('android.jar') }
514    args 16
515    args "${topobjdir}/widget/android/bindings"
516
517    // Configure the arguments at evaluation-time, not at configuration-time.
518    doFirst {
519        // From -Pgenerate_sdk_bindings_args=... on command line; missing in
520        // `android-gradle-dependencies` toolchain task.
521        if (project.hasProperty('generate_sdk_bindings_args')) {
522            args project.generate_sdk_bindings_args.split(';')
523        }
524    }
525
526    workingDir "${topsrcdir}/widget/android/bindings"
527
528    dependsOn project(':annotations').jar
529}
530
531apply plugin: 'org.mozilla.apilint'
532
533apiLint {
534    // TODO: Change this to `org` after hiding org.mozilla.gecko
535    packageFilter = 'org.mozilla.geckoview'
536    changelogFileName = 'src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md'
537    skipClassesRegex = [
538        '^org.mozilla.geckoview.BuildConfig$',
539        '^org.mozilla.geckoview.R$',
540    ]
541    lintFilters = ['GV']
542    deprecationAnnotation = 'org.mozilla.geckoview.DeprecationSchedule'
543    libraryVersion = mozconfig.substs.MOZILLA_VERSION.split('\\.')[0] as Integer
544    allowedPackages = [
545        'java',
546        'android',
547        'androidx',
548        'org.json',
549        'org.mozilla.geckoview',
550    ]
551}
552