1.. -*- Mode: rst; fill-column: 80; -*-
2
3===========================
4GeckoView Contributor Guide
5===========================
6
7Table of contents
8=================
9
10.. contents:: :local:
11
12GeckoView Contributor Quick Start Guide
13=======================================
14
15This is a guide for developers who want to contribute to the GeckoView
16project. If you want to get started using GeckoView in your app then you
17should refer to the
18`wiki <https://wiki.mozilla.org/Mobile/GeckoView#Get_Started>`_.
19
20Get set up with Mozilla Central
21-------------------------------
22
23The GeckoView codebase is part of the main Firefox tree and can be found
24in ``mozilla-central``. You will need to get set up as a contributor to
25Firefox in order to contribute to GeckoView. To get set up with
26``mozilla-central``, follow the `Quick Start Guide for Git
27Users <mc-quick-start.html>`_, or the `Contributing to the Mozilla code
28base <https://developer.mozilla.org/docs/Mozilla/Developer_guide/Introduction>`_
29guide on `MDN <https://developer.mozilla.org/>`_ for Mercurial users.
30
31Once you have a copy of ``mozilla-central``, you will need to build
32GeckoView.
33
34Bootstrap Gecko
35---------------
36
37Bootstrap configures everything for GeckoView and Fennec (Firefox for Android) development.
38
39-  Ensure you have ``mozilla-central`` checked out. If this is the first
40   time you are doing this, it may take some time.
41
42.. code:: bash
43
44   git checkout central/default
45
46If you are on Windows, you will need to install the
47`Java 1.8 SDK <https://adoptopenjdk.net/?variant=openjdk8>`__.
48
49If you are on a mac, you will need to have the Xcode build tools
50installed. You can do this by either `installing
51Xcode <https://developer.apple.com/xcode/>`__ or installing only the
52tools from the command line by running ``xcode-select --install`` and
53following the on screen instructions. Use the ``--no-interactive``
54argument to automatically accept any license agreements.
55
56.. code:: bash
57
58   ./mach [--no-interactive] bootstrap
59
60-  Choose option \`4. Firefox for Android\` for GeckoView development.
61   This will give you a version of Gecko configured for Android that has
62   not bundled the native code into embedded libraries so you can amend
63   the code.
64-  Say Y to all configuration options
65-  Once ``mach bootstrap`` is complete, it will automatically write
66   the configuration into a new ``mozconfig`` file. If you already
67   have a ``mozconfig``, ``mach`` will instead output new configuration
68   that you should append to your existing file.
69
70Build from the command line
71---------------------------
72
73In order to pick up the configuration changes we just made we need to
74build from the command line. This will update generated sources, compile
75native code, and produce GeckoView AARs and example and test APKs.
76
77.. code:: bash
78
79   ./mach build
80
81Build Using Android Studio
82--------------------------
83
84-  Install `Android
85   Studio <https://developer.android.com/studio/install>`_.
86-  Disable Instant Run. This is because Fennec and the Geckoview Example
87   app cannot deploy with Instant Run on.
88
89   -  Select Android Studio > Preferences from the menu bar
90   -  Navigate to Build, Execution, Deployment > Instant Run.
91   -  Uncheck the box that reads
92      ``Enable Instant Run to hot swap code/resource changes on deploy``.
93
94   |alt text|
95-  Choose File->Open from the toolbar
96-  Navigate to the root of your ``mozilla-central`` source directory and
97   click “Open”
98-  Click yes if it asks if you want to use the gradle wrapper.
99
100   -  If the gradle sync does not automatically start, select File >
101      Sync Project with Gradle Files.
102
103-  Wait for the project to index and gradle to sync. Once synced, the
104   workspace will reconfigure to display the different projects.
105
106   -  annotations contains custom annotations used inside GeckoView and
107      Fennec.
108   -  app is Fennec - Firefox for Android. Here is where you will find
109      code specific to that app.
110   -  geckoview is the GeckoView project. Here is all the Java files
111      related to GeckoView
112   -  geckoview_example is an example browser built using GeckoView.
113   -  omnijar contains the parts of Gecko and GeckoView that are not
114      written in Java or Kotlin
115   -  thirdparty contains third party code that Fennec and GeckoView
116      use.
117
118   |alt text 1|
119
120Now you’re set up and ready to go.
121
122**Important: at this time, building from Android Studio or directly from
123Gradle does not (re-)compile native code, including C++ and Rust.** This
124means you will need to run ``mach build`` yourself to pick up changes to
125native code. `Bug
1261509539 <https://bugzilla.mozilla.org/show_bug.cgi?id=1509539>`_ tracks
127making Android Studio and Gradle do this automatically.
128
129Performing a bug fix
130--------------------
131
132One you have got GeckoView building and running, you will want to start
133contributing. There is a general guide to `Performing a Bug Fix for Git
134Developers <contributing-to-mc.html>`_ for you to follow. To contribute to
135GeckoView specifically, you will need the following additional
136information.
137
138Running tests and linter locally
139~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
140
141To ensure that your patch does not break existing functionality in
142GeckoView, you can run the junit test suite with the following command
143
144::
145
146   ./mach geckoview-junit
147
148This command also allows you to run individual tests or test classes,
149e.g.
150
151::
152
153   ./mach geckoview-junit org.mozilla.geckoview.test.NavigationDelegateTest
154   ./mach geckoview-junit org.mozilla.geckoview.test.NavigationDelegateTest#loadUnknownHost
155
156If your patch makes a GeckoView JavaScript module, you should run ESLint
157as well:
158
159::
160
161   ./mach lint -l eslint mobile/android/modules/geckoview/
162
163To see information on other options, simply run
164``./mach geckoview-junit --help``; of particular note for dealing with
165intermittent test failures are ``--repeat N`` and
166``--run-until-failure``, both of which do exactly what you’d expect.
167
168Updating the changelog and API documentation
169~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
170
171If the patch that you want to submit changes the public API for
172GeckoView, you must ensure that the API documentation is kept up to
173date. To check whether your patch has altered the API, run the following
174command.
175
176.. code:: bash
177
178   ./mach lint --linter android-api-lint
179
180The output of this command will inform you if any changes you have made
181break the existing API. Review the changes and follow the instructions
182it provides.
183
184If the linter asks you to update the changelog, please ensure that you
185follow the correct format for changelog entries. Under the heading for
186the next release version, add a new entry for the changes that you are
187making to the API, along with links to any relevant files, and bug
188number e.g.
189
190::
191
192   - Added [`GeckoRuntimeSettings.Builder#aboutConfigEnabled`][71.12] to control whether or
193     not `about:config` should be available.
194     ([bug 1540065]({{bugzilla}}1540065))
195
196   [71.12]: {{javadoc_uri}}/GeckoRuntimeSettings.Builder.html#aboutConfigEnabled-boolean-
197
198Submitting to the ``try`` server
199~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
200
201It is advisable to run your tests before submitting your patch. You can
202do this using Mozilla’s ``try`` server. To submit a GeckoView patch to
203``try`` before submitting it for review, type:
204
205.. code:: bash
206
207   ./mach try fuzzy -q "android"
208
209This will run all of the Android test suite. If your patch passes on
210``try`` you can be (fairly) confident that it will land successfully
211after review.
212
213Tagging a reviewer
214~~~~~~~~~~~~~~~~~~
215
216When submitting a patch to Phabricator, if you know who you want to
217review your patch, put their Phabricator handle against the
218``reviewers`` field.
219
220If you don’t know who to tag for a review in the Phabricator submission
221message, leave the field blank and, after submission, follow the link to
222the patch in Phabricator and scroll to the bottom of the screen until
223you see the comment box.
224
225- Select the ``Add Action`` drop down and pick the ``Change Reviewers`` option.
226- In the presented box, add ``geckoview-reviewers``. Selecting this group as the reviewer will notify all the members of the GeckoView team there is a patch to review.
227- Click ``Submit`` to submit the reviewer change request.
228
229Include GeckoView as a dependency
230---------------------------------
231
232If you want to include a development version of GeckoView as a
233dependency inside another app, you must link to a local copy. There are
234several ways to achieve this, but the preferred way is to use Gradle’s
235*dependency substitution* mechanism, for which there is first-class
236support in ``mozilla-central`` and a pattern throughout Mozilla’s
237GeckoView-consuming ecosystem.
238
239The good news is that ``mach build`` produces everything you need, so
240that after the configuration below, you should find that the following
241commands rebuild your local GeckoView and then consume your local
242version in the downstream project.
243
244.. code:: sh
245
246   cd /path/to/mozilla-central && ./mach build
247   cd /path/to/project && ./gradlew assembleDebug
248
249**Be sure that your ``mozconfig`` specifies the correct ``--target``
250argument for your target device.** Many projects use “ABI splitting” to
251include only the target device’s native code libraries in APKs deployed
252to the device. On x86-64 and aarch64 devices, this can result in
253GeckoView failing to find any libraries, because valid x86 and ARM
254libraries were not included in a deployed APK. Avoid this by setting
255``--target`` to the exact ABI that your device supports.
256
257Dependency substiting your local GeckoView into a Mozilla project
258~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
259
260Most GeckoView-consuming projects produced by Mozilla support dependency
261substitution via ``local.properties``. These projects include:
262
263- `Fenix <https://github.com/mozilla-mobile/fenix>`_
264- `reference-browser <https://github.com/mozilla-mobile/reference-browser>`_
265- `android-components <https://github.com/mozilla-mobile/android-components>`_
266- `Firefox Reality <https://github.com/MozillaReality/FirefoxReality>`_
267
268Simply edit (or create) the file ``local.properties`` in the project
269root and include a line like:
270
271.. code:: properties
272
273   dependencySubstitutions.geckoviewTopsrcdir=/path/to/mozilla-central
274
275The default object directory – the one that a plain ``mach build``
276discovers – will be used. You can optionally specify a particular object
277directory with an additional line like:
278
279.. code:: properties
280
281   dependencySubstitutions.geckoviewTopobjdir=/path/to/object-directory
282
283With these lines, the GeckoView-consuming project should use the
284GeckoView AAR produced by ``mach build`` in your local
285``mozilla-central``.
286
287**Remember to remove the lines in ``local.properties`` when you want to
288return to using the published GeckoView builds!**
289
290Dependency substituting your local GeckoView into a non-Mozilla project
291~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
292
293In projects that don’t have first-class support for dependency
294substitution already, you can do the substitution yourself. See the
295documentation in
296`substitue-local-geckoview.gradle <https://hg.mozilla.org/mozilla-central/file/tip/substitute-local-geckoview.gradle>`_,
297but roughly: in each Gradle project that consumes GeckoView, i.e., in
298each ``build.gradle`` with a
299``dependencies { ... 'org.mozilla.geckoview:geckoview-...' }`` block,
300include lines like:
301
302.. code:: groovy
303
304   ext.topsrcdir = "/path/to/mozilla-central"
305   ext.topobjdir = "/path/to/object-directory" // Optional.
306   apply from: "${topsrcdir}/substitute-local-geckoview.gradle"
307
308**Remember to remove the lines from all ``build.gradle`` files when you
309want to return to using the published GeckoView builds!**
310
311Next Steps
312----------
313
314-  Get started with `Native Debugging <native-debugging.html>`_
315
316.. |alt text| image:: ../assets/DisableInstantRun.png
317.. |alt text 1| image:: ../assets/GeckoViewStructure.png
318