tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

geckoview-architecture.rst (36299B)


      1 .. -*- Mode: rst; fill-column: 80; -*-
      2 
      3 =====================
      4 Architecture overview
      5 =====================
      6 
      7 .. contents:: Table of Contents
      8   :depth: 2
      9   :local:
     10 
     11 Introduction
     12 ============
     13 
     14 *Gecko* is a Web engine developed by Mozilla and used to power Firefox on
     15 various platforms. A Web engine is roughly comprised of a JavaScript engine, a
     16 Rendering engine, HTML parser, a Network stack, various media encoders, a
     17 Graphics engine, a Layout engine and more.
     18 
     19 Code that is part of a browser itself is usually referred to as "chrome" code
     20 (from which the popular Chrome browser takes its name) as opposed to code part
     21 of a Web site, which is usually referred to "content" code or content Web page.
     22 
     23 *GeckoView* is an Android library that can be used to embed Gecko into Android
     24 apps. Android apps that embed Gecko this way are usually referred to by
     25 "embedders" or simply "apps".
     26 
     27 GeckoView powers all currently active Mozilla browsers on Android, like Firefox
     28 for Android and Firefox Focus.
     29 
     30 API
     31 ===
     32 
     33 The following sections describe parts of the GeckoView API that are public and
     34 exposed to embedders.
     35 
     36   |api-diagram|
     37 
     38 Overall tenets
     39 --------------
     40 
     41 GeckoView is an opinionated library that contains a minimal UI and makes no
     42 assumption about the type of app that is being used by. Its main consumers
     43 inside Mozilla are browsers, so a lot of features of GeckoView are geared
     44 towards browsers, but there is no assumption that the embedder is actually a
     45 browser (e.g. there is no concept of "tab" in GeckoView).
     46 
     47 The GeckoView API tries to retain as little data as possible, delegating most
     48 data storage to apps. Notable exceptions to this rule are: permissions,
     49 extensions and cookies.
     50 
     51 View, Runtime and Session
     52 -------------------------
     53 
     54    |view-runtime-session|
     55 
     56 There are three main classes in the GeckoView API:
     57 
     58 - ``GeckoRuntime`` represents an instance of Gecko running in an app. Normally,
     59  apps have only one instance of the runtime which lives for as long as the app
     60  is alive. Any object in the API that is not specific to a *session*
     61  (more to this later) is usually reachable from the runtime.
     62 - ``GeckoSession`` represents a web site *instance*. You can think of it as a
     63  *tab* in a browser or a Web view in an app. Any object related to the
     64  specific session will be reachable from this object. Normally, embedders
     65  would have many instances of ``GeckoSession`` representing each tab that is
     66  currently open. Internally, a session is represented as a "window" with one
     67  single tab in it.
     68 - ``GeckoView`` is an Android ``View`` that embedders can use to paint a
     69  ``GeckoSession`` in the app. Normally, only ``GeckoSession`` s associated to
     70  a ``GeckoView`` are actually *alive*, i.e. can receive events, fire timers,
     71  etc.
     72 
     73 Delegates
     74 ---------
     75 
     76 Because GeckoView has no UI elements and doesn't store a lot of data, it needs
     77 a way to *delegate* behavior when Web sites need functionality that requires
     78 these features.
     79 
     80 To do that, GeckoView exposes Java interfaces to the embedders, called
     81 Delegates. Delegates are normally associated to either the runtime, when they
     82 don't refer to a specific session, or a session, when they are
     83 session-specific.
     84 
     85 The most important delegates are:
     86 
     87 - ``Autocomplete.StorageDelegate`` Which is used by embedders to implement
     88  autocomplete functionality for logins, addresses and credit cards.
     89 - ``ContentDelegate`` Which receives events from the content Web page like
     90  "open a new window", "on fullscreen request", "this tab crashed" etc.
     91 - ``HistoryDelegate`` Which receives events about new or modified history
     92  entries. GeckoView itself does not store history so the app is required to
     93  listen to history events and store them permanently.
     94 - ``NavigationDelegate`` Informs the embedder about navigation events and
     95  requests.
     96 - ``PermissionDelegate`` Used to prompt the user for permissions like
     97  geolocation, notifications, etc.
     98 - ``PromptDelegate`` Implements content-side prompts like alert(), confirm(),
     99  basic HTTP auth, etc.
    100 - ``MediaSession.Delegate`` Informs the embedder about media elements currently
    101  active on the page and allows the embedder to pause, resume, receive playback
    102  state etc.
    103 - ``WebExtension.MessageDelegate`` Used by the embedder to exchange messages
    104  with built-in extensions. See also `Interacting with Web Content <../consumer/web-extensions.html>`_.
    105 
    106 
    107 .. _GeckoDisplay:
    108 
    109 GeckoDisplay
    110 ------------
    111 
    112 GeckoView can paint to either a ``SurfaceView`` or a ``TextureView``.
    113 
    114 - ``SufaceView`` is what most apps will use and it's the default, it provides a
    115  barebone wrapper around a GL surface where GeckoView can paint on.
    116  SurfaceView is not part of normal Android compositing, which means that
    117  Android is not able to paint (partially) on top of a SurfaceView or apply
    118  transformations and animations to it.
    119 - ``TextureView`` offers a surface which can be transformed and animated but
    120  it's slower and requires more memory because it's `triple-buffered
    121  <https://en.wikipedia.org/wiki/Multiple_buffering#Triple_buffering>`_
    122  (which is necessary to offer animations).
    123 
    124 Most apps will use the ``GeckoView`` class to paint the web page. The
    125 ``GeckoView`` class is an Android ``View`` which takes part in the Android view
    126 hierarchy.
    127 
    128 Android recycles the ``GeckoView`` whenever the app is not visible, releasing
    129 the associated ``SurfaceView`` or ``TextureView``. This triggers a few actions
    130 on the Gecko side:
    131 
    132 - The GL Surface is released, and Gecko is notified in
    133  `SyncPauseCompositor <https://searchfox.org/mozilla-central/rev/ead7da2d9c5400bc7034ff3f06a030531bd7e5b9/widget/android/nsWindow.cpp#1114>`_.
    134 - The ``<browser>`` associated to the ``GeckoSession`` is `set to inactive <https://searchfox.org/mozilla-central/rev/ead7da2d9c5400bc7034ff3f06a030531bd7e5b9/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java#553>`_,
    135  which essentially freezes the JavaScript engine.
    136 
    137 Apps that do not use ``GeckoView``, because e.g. they cannot use
    138 ``SurfaceView``, need to manage the active state manually and call
    139 ``GeckoSession.setActive`` whenever the session is not being painted on the
    140 screen.
    141 
    142 Thread safety
    143 -------------
    144 
    145 Apps will inevitably have to deal with the Android UI in a significant way.
    146 Most of the Android UI toolkit operates on the UI thread, and requires
    147 consumers to execute method calls on it. The Android UI thread runs an event
    148 loop that can be used to schedule tasks on it from other threads.
    149 
    150 Gecko, on the other hand, has its own main thread where a lot of the front-end
    151 interactions happen, and many methods inside Gecko expect to be called on the
    152 main thread.
    153 
    154 To not overburden the App with unnecessary multi-threaded code, GeckoView will
    155 always bridge the two "main threads" and redirect method calls as appropriate.
    156 Most GeckoView delegate calls will thus happen on the Android UI thread and
    157 most APIs are expected to be called on the UI thread as well.
    158 
    159 This can sometimes create unexpected performance considerations, as illustrated
    160 in later sections.
    161 
    162 GeckoResult
    163 -----------
    164 
    165 An ubiquitous tool in the GeckoView API is ``GeckoResult``. GeckoResult is a
    166 promise-like class that can be used by apps and by Gecko to return values
    167 asynchronously in a thread-safe way. Internally, ``GeckoResult`` will keep
    168 track of what thread it was created on, and will execute callbacks on the same
    169 thread using the thread's ``Handler``.
    170 
    171 When used in Gecko, ``GeckoResult`` can be converted to ``MozPromise`` using
    172 ``MozPromise::FromGeckoResult``.
    173 
    174 Page load
    175 ---------
    176 
    177    |pageload-diagram|
    178 
    179 GeckoView offers several entry points that can be used to react to the various
    180 stages of a page load. The interactions can be tricky and surprising so we will
    181 go over them in details in this section.
    182 
    183 For each page load, the following delegate calls will be issued:
    184 ``onLoadRequest``, ``onPageStart``, ``onLocationChange``,
    185 ``onProgressChange``, ``onSecurityChange``, ``onSessionStateChange``,
    186 ``onCanGoBack``, ``onCanGoForward``, ``onLoadError``, ``onPageStop``.
    187 
    188 Most of the method calls are self-explanatory and offer the App a chance to
    189 update the UI in response to a change in the page load state. The more
    190 interesting delegate calls will be described below.
    191 
    192 onPageStart and onPageStop
    193 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    194 
    195 ``onPageStart`` and ``onPageStop`` are guaranteed to appear in pairs and in
    196 order, and denote the beginning and the end of a page load. In between a start
    197 and stop event, multiple ``onLoadRequest`` and ``onLocationChange`` call can be
    198 executed, denoting redirects.
    199 
    200 onLoadRequest
    201 ~~~~~~~~~~~~~
    202 
    203 ``onLoadRequest``, which is perhaps the most important, can be used by the App
    204 to intercept page loads. The App can either *deny* the load, which will stop
    205 the page from loading, and handle it internally, or *allow* the
    206 load, which will load the page in Gecko. ``onLoadRequest`` is called for all
    207 page loads, regardless of whether they were initiated by the app itself, by Web
    208 content, or as a result of a redirect.
    209 
    210 When the page load originates in Web content, Gecko has to synchronously
    211 wait for the Android UI thread to schedule the call to ``onLoadRequest`` and
    212 for the App to respond. This normally takes a negligible amount of time, but
    213 when the Android UI thread is busy, e.g. because the App is being painted for
    214 the first time, the delay can be substantial. This is an area of GeckoView that
    215 we are actively trying to improve.
    216 
    217 onLoadError
    218 ~~~~~~~~~~~
    219 
    220 ``onLoadError`` is called whenever the page does not load correctly, e.g.
    221 because of a network error or a misconfigured HTTPS server. The App can return
    222 a URL to a local HTML file that will be used as error page internally by Gecko.
    223 
    224 onLocationChange
    225 ~~~~~~~~~~~~~~~~
    226 
    227 ``onLocationChange`` is called whenever Gecko commits to a navigation and the
    228 URL can safely displayed in the URL bar.
    229 
    230 onSessionStateChange
    231 ~~~~~~~~~~~~~~~~~~~~
    232 
    233 ``onSessionStateChange`` is called whenever any piece of the session state
    234 changes, e.g. form content, scrolling position, zoom value, etc. Changes are
    235 batched to avoid calling this API too frequently.
    236 
    237 Apps can use ``onSessionStateChange`` to store the serialized state to
    238 disk to support restoring the session at a later time.
    239 
    240 Third-party root certificates
    241 -----------------------------
    242 
    243 Gecko maintains its own Certificate Authority store and does not use the
    244 platform's CA store. GeckoView follows the same policy and will not, by
    245 default, read Android's CA store to determine root certificates.
    246 
    247 However, GeckoView provides a way to import all third-party CA roots added to
    248 the Android CA store by setting the `enterpriseRootsEnabled
    249 <https://mozilla.github.io/geckoview/javadoc/mozilla-central/org/mozilla/geckoview/GeckoRuntimeSettings.Builder.html#enterpriseRootsEnabled(boolean)>`_
    250 runtime setting to ``true``, this feature is implemented in `EnterpriseRoots
    251 <https://searchfox.org/mozilla-central/rev/26a6a38fb515dbab0bb459c40ec4b877477eefef/mobile/android/geckoview/src/main/java/org/mozilla/gecko/EnterpriseRoots.java>`_
    252 
    253 There is not currently any API for an app to manually specify additional CA
    254 roots, although this might change with `Bug 1522162
    255 <https://bugzilla.mozilla.org/show_bug.cgi?id=1522162>`_.
    256 
    257 Lite and Omni builds
    258 ---------------------
    259 
    260 A variation of the default GeckoView build, dubbed `Omni` in the codebase,
    261 provides additional libraries that can be helpful when building a browser app.
    262 Currently, the `Glean
    263 <https://docs.telemetry.mozilla.org/concepts/glean/glean.html>`_ library is
    264 included in the ``geckoview-omni`` package.  The default build ``geckoview``,
    265 which does not contain such libraries, is similarly dubbed `Lite` in the
    266 codebase.
    267 
    268 The additional libraries in the Omni package are directly built into Gecko's
    269 main ``.so`` file, ``libxul.so``. These libraries are then declared in the
    270 ``.module`` package inside the ``maven`` repository, e.g. see the ``.module``
    271 file for `geckoview-omni
    272 <https://maven.mozilla.org/maven2/org/mozilla/geckoview/geckoview-omni/102.0.20220623063721/geckoview-omni-102.0.20220623063721.module>`_:
    273 
    274 .. code-block:: json
    275 
    276      "capabilities": [
    277        {
    278          "group": "org.mozilla.geckoview",
    279          "name": "geckoview-omni",
    280          "version": "102.0.20220623063721"
    281        },
    282        {
    283          "group": "org.mozilla.telemetry",
    284          "name": "glean-native",
    285          "version": "44.1.1"
    286        }
    287      ]
    288 
    289 Notice the ``org.mozilla.telemetry:glean-native`` capability is declared
    290 alongside ``org.mozilla.geckoview``.
    291 
    292 The main Glean library then depends on ``glean-native`` which is either
    293 provided in a standalone package (for apps that do not include GeckoView) or by
    294 the GeckoView capability above.
    295 
    296 In Treeherder, the Lite build is denoted with ``Lite``, while the Omni builds
    297 don't have extra denominations as they are the default build, so e.g. for
    298 ``x86_64`` the platform names would be:
    299 
    300 - ``Android 7.0 x86-64`` for the Omni build
    301 - ``Android 7.0 x86-64 Lite`` for the Lite build
    302 
    303 Extensions
    304 ----------
    305 
    306 Extensions can be installed using ``WebExtensionController::install`` and
    307 ``WebExtensionController::installBuiltIn``, which asynchronously returns a
    308 ``WebExtension`` object that can be used to set delegates for
    309 extension-specific behavior.
    310 
    311 The ``WebExtension`` object is immutable, and will be replaced every time a
    312 property changes. For instance, to disable an extension, apps can use the
    313 ``disable`` method, which will return an updated version of the
    314 ``WebExtension`` object.
    315 
    316 Internally, all ``WebExtension`` objects representing one extension share the
    317 same delegates, which are stored in ``WebExtensionController``.
    318 
    319 Given the extensive sprawling amount of data associated to extensions,
    320 extension installation persists across restarts. Existing extensions can be
    321 listed using ``WebExtensionController::list``.
    322 
    323 In addition to ordinary WebExtension APIs, GeckoView allows ``builtIn``
    324 extensions to communicate to the app via native messaging. Apps can register
    325 themselves as native apps and extensions will be able to communicate to the app
    326 using ``connectNative`` and ``sendNativeMessage``. Further information can be
    327 found `here <../consumer/web-extensions.html>`__.
    328 
    329 Internals
    330 =========
    331 
    332 The following sections describe how Gecko and GeckoView are implemented. These
    333 parts of GeckoView are not normally exposed to embedders.
    334 
    335 Process Model
    336 -------------
    337 
    338 Internally, Gecko uses a multi-process architecture, most of the chrome code
    339 runs in the *main* process, while content code runs in *child* processes also
    340 called *content* processes. There are additional types of specialized processes
    341 like the *socket* process, which runs parts of the networking code, the *gpu*
    342 process which executes GPU commands, the *extension* process which runs most
    343 extension content code, etc.
    344 
    345 We intentionally do not expose our process model to embedders.
    346 
    347 To learn more about the multi-process architecture see `Fission for GeckoView
    348 engineers <https://gist.github.com/agi/c900f3e473ff681158c0c907e34780e4>`_.
    349 
    350 The majority of the GeckoView Java code runs on the main process, with a thin
    351 glue layer on the child processes, mostly contained in ``GeckoThread``.
    352 
    353 Process priority on Android
    354 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    355 
    356 On Android, each process is assigned a given priority. When the device is
    357 running low on memory, or when the system wants to conserve resources, e.g.
    358 when the screen has been off for a long period of time, or the battery is low,
    359 Android will sort all processes in reverse priority order and kill, using a
    360 ``SIGKILL`` event, enough processes until the given free memory and resource
    361 threshold is reached.
    362 
    363 Processes that are necessary to the function of the device get the highest
    364 priority, followed by apps that are currently visible and focused on the
    365 screen, then apps that are visible (but not on focus), background processes and
    366 so on.
    367 
    368 Processes that do not have a UI associated to it, e.g. background services,
    369 will normally have the lowest priority, and thus will be killed most
    370 frequently.
    371 
    372 To increase the priority of a service, an app can ``bind`` to it. There are
    373 three possible ``bind`` priority values
    374 
    375 - ``BIND_IMPORTANT``: The process will be *as important* as the process binding
    376  to it
    377 - default priority: The process will have lower priority than the process
    378  binding to it, but still higher priority than a background service
    379 - ``BIND_WAIVE_PRIORITY``: The bind will be ignored for priority
    380  considerations.
    381 
    382 It's important to note that the priority of each service is only relative to
    383 the priority of the app binding to it. If the app is not visible, the app
    384 itself and all services attached to it, regardless of binding, will get
    385 background priority (i.e. the lowest possible priority).
    386 
    387 Process management
    388 ~~~~~~~~~~~~~~~~~~
    389 
    390 Each Gecko process corresponds to an Android ``service`` instance, which has to
    391 be declared in GeckoView's ``AndroidManifest.xml``.
    392 
    393 For example, this is the definition of the ``media`` process:
    394 
    395 .. rstcheck: ignore-languages=xml
    396 .. code-block:: xml
    397 
    398  <service
    399          android:name="org.mozilla.gecko.media.MediaManager"
    400          android:enabled="true"
    401          android:exported="false"
    402          android:isolatedProcess="false"
    403          android:process=":media">
    404 
    405 Process creation is controlled by Gecko which interfaces to Android using
    406 ``GeckoProcessManager``, which translates Gecko's priority to Android's
    407 ``bind`` values.
    408 
    409 Because all priorities are waived when the app is in the background, it's not
    410 infrequent that Android kills some of GeckoView's services, while still leaving
    411 the main process alive.
    412 
    413 It is therefore very important that Gecko is able to recover from process
    414 disappearing at any moment at runtime.
    415 
    416 Priority Hint
    417 ~~~~~~~~~~~~~
    418 
    419 Internally, GeckoView ties the lifetime of the ``Surface`` associated to a
    420 ``GeckoSession`` and the process priority of the process where the session
    421 lives.
    422 
    423 The underlying assumption is that a session that is not visible doesn't have a
    424 surface associated to it and it's not being used by the user so it shouldn't
    425 receive high priority status.
    426 
    427 The way this is implemented is `by setting
    428 <https://searchfox.org/mozilla-central/rev/5b2d2863bd315f232a3f769f76e0eb16cdca7cb0/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java#114,123>`_
    429 the ``active`` property on the ``browser`` object to ``false``, which causes
    430 Gecko to de-prioritize the process, assuming that no other windows in the same
    431 process have ``active=true``. See also `GeckoDisplay`_.
    432 
    433 However, there are use cases where just looking at the surface is not enough.
    434 For instance, when the user opens the settings menu, the currently selected tab
    435 becomes invisible, but the user will still expect the browser to retain that
    436 tab state with a higher priority than all the other tabs. Similarly, when the
    437 browser is put in the background, the surface associated to the current tab
    438 gets destroyed, but the current tab is still more important than the other
    439 tabs, but because it doesn't have a surface associated to it, we have no way to
    440 differentiate it from all the other tabs.
    441 
    442 To solve the above problem, we expose an API for consumers to *boost* a session
    443 priority, `setPriorityHint
    444 <https://mozilla.github.io/geckoview/javadoc/mozilla-central/org/mozilla/geckoview/GeckoSession.html#setPriorityHint(int)>`_.
    445 The priority hint is taken into consideration when calculating the
    446 priority of a process.  Any process that contains either an active session or a
    447 session with the priority hint `is boosted
    448 <https://searchfox.org/mozilla-central/rev/5b2d2863bd315f232a3f769f76e0eb16cdca7cb0/dom/ipc/BrowserParent.cpp#3593>`_
    449 to the highest priority.
    450 
    451 Shutdown
    452 --------
    453 
    454 Android does not provide apps with a notification whenever the app is shutting
    455 down. As explained in the section above, apps will simply be killed whenever
    456 the system needs to reclaim resources. This means that Gecko on Android will
    457 never shutdown cleanly, and that shutdown actions will never execute.
    458 
    459 .. _principals:
    460 
    461 Principals
    462 ----------
    463 
    464 In Gecko, a *website* loaded in a session is represented by an abstraction
    465 called `principal
    466 <https://searchfox.org/mozilla-central/rev/5b2d2863bd315f232a3f769f76e0eb16cdca7cb0/caps/nsIPrincipal.idl>`_.
    467 Principals contain information that is used to determine what permissions have
    468 been granted to the website instance, what APIs are available to it, which
    469 container the page is loaded in, is the page in private browsing or not, etc.
    470 
    471 Principals are used throughout the Gecko codebase, GeckoView, however, does not
    472 expose the concept to the API. This is intentional, as exposing it would
    473 potentially expose the app to various security sensitive concepts, which would
    474 violate the "secure" requirement for the GeckoView API.
    475 
    476 The absence of principals from the API is, e.g., why GeckoView does not offer a
    477 way to set permissions given a URL string, as permissions are internally stored
    478 by principal. See also `Setting Permissions`_.
    479 
    480 To learn more about principals see `this talk by Bobby Holley
    481 <https://www.youtube.com/watch?v=28FPetl5Fl4>`_.
    482 
    483 Window model
    484 ------------
    485 
    486 Internally, Gecko has the concept of *window* and *tab*. Given that GeckoView
    487 doesn't have the concept of tab (since it might be used to build something that
    488 is *not* a browser) we hide Gecko tabs from the GeckoView API.
    489 
    490 Each ``GeckoSession`` corresponds to a Gecko ``window`` object with exactly one
    491 ``tab`` in it. Because of this you might see ``window`` and ``session`` used
    492 interchangeably in the code.
    493 
    494 Internally, Gecko uses ``window`` s for other things other than
    495 ``GeckoSession``, so we have to sometime be careful about knowing which windows
    496 belong to GeckoView and which don't. For example, the background extension page
    497 is implemented as a ``window`` object that doesn't paint to a surface.
    498 
    499 EventDispatcher
    500 ---------------
    501 
    502 The GeckoView codebase is written in C++, JavaScript and Java, it runs across
    503 processes and often deals with asynchronous and garbage-collected code with
    504 complex lifetime dependencies. To make all of this work together, GeckoView
    505 uses a cross-language event-driven architecture.
    506 
    507 The main orchestrator of this event-driven architecture is ``EventDispatcher``.
    508 Each language has an implementation of ``EventDispatcher`` that can be used to
    509 fire events that are reachable from any language.
    510 
    511 Each window (i.e. each session) has its own ``EventDispatcher`` instance, which
    512 is also present on the content process. There is also a global
    513 ``EventDispatcher`` that is used to send and receive events that are not
    514 related to a specific session.
    515 
    516 Events can have data associated to it, which is represented as a
    517 ``GeckoBundle`` (essentially a ``String``-keyed variant map) on the Java and
    518 C++ side, and a plain object on the JavaScript side. Data is automatically
    519 converted back and forth by ``EventDispatcher``.
    520 
    521 In Java, events are fired in the same thread where the listener was registered,
    522 which allows us to ensure that events are received in a consistent order and
    523 data is kept consistent, so that we by and large don't have to worry about
    524 multi-threaded issues.
    525 
    526 JNI
    527 ---
    528 
    529 GeckoView code uses the Java Native Interface or JNI to communicate between
    530 Java and C++ directly. Our JNI exports are generated from the Java source code
    531 whenever the ``@WrapForJNI`` annotation is present. For non-GeckoView code, the
    532 list of classes for which we generate imports is defined at
    533 ``widget/android/bindings``.
    534 
    535 The lifetime of JNI objects depends on their native implementation:
    536 
    537 - If the class implements ``mozilla::SupportsWeakPtr``, the Java object will
    538  store a ``WeakPtr`` to the native object and will not own the lifetime of the
    539  object.
    540 - If the class implements ``AddRef`` and ``Release`` from ``nsISupports``, the
    541  Java object will store a ``RefPtr`` to the native object and will hold a
    542  strong reference until the Java object releases the object using
    543  ``DisposeNative``.
    544 - If neither cases apply, the Java object will store a C++ pointer to the
    545  native object.
    546 
    547 Calling Runtime delegates from native code
    548 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    549 
    550 Runtime delegates can be reached directly using the ``GeckoRuntime`` singleton.
    551 A common pattern is to expose a ``@WrapForJNI`` method on ``GeckoRuntime`` that
    552 will call the delegate, that than can be used on the native side. E.g.
    553 
    554 .. code:: java
    555 
    556  @WrapForJNI
    557  private void featureCall() {
    558    ThreadUtils.runOnUiThread(() -> {
    559      if (mFeatureDelegate != null) {
    560        mFeatureDelegate.feature();
    561      }
    562    });
    563  }
    564 
    565 And then, on the native side:
    566 
    567 .. code:: cpp
    568 
    569  java::GeckoRuntime::LocalRef runtime = java::GeckoRuntime::GetInstance();
    570  if (runtime != nullptr) {
    571    runtime->FeatureCall();
    572  }
    573 
    574 Session delegates
    575 ~~~~~~~~~~~~~~~~~
    576 
    577 ``GeckoSession`` delegates require a little more care, as there's a copy of a
    578 delegate for each ``window``. Normally, a method on ``android::nsWindow`` is
    579 added which allows Gecko code to call it. A reference to ``nsWindow`` can be
    580 obtained from a ``nsIWidget`` using ``nsWindow::From``:
    581 
    582 .. code:: cpp
    583 
    584  RefPtr<nsWindow> window = nsWindow::From(widget);
    585  window->SessionDelegateFeature();
    586 
    587 The ``nsWindow`` implementation can then forward the call to
    588 ``GeckoViewSupport``, which is the JNI native side of ``GeckoSession.Window``.
    589 
    590 .. code:: cpp
    591 
    592  void nsWindow::SessionDelegateFeature() {
    593    auto acc(mGeckoViewSupport.Access());
    594    if (!acc) {
    595      return;
    596    }
    597    acc->SessionDelegateFeature(aResponse);
    598  }
    599 
    600 Which can in turn forward the call to the Java side using the JNI stubs.
    601 
    602 .. code:: cpp
    603 
    604  auto GeckoViewSupport::SessionDelegateFeature() {
    605    GeckoSession::Window::LocalRef window(mGeckoViewWindow);
    606    if (!window) {
    607      return;
    608    }
    609    window->SessionDelegateFeature();
    610  }
    611 
    612 And finally, the Java implementation calls the session delegate.
    613 
    614 .. code:: java
    615 
    616  @WrapForJNI
    617  private void sessionDelegateFeature() {
    618    final GeckoSession session = mOwner.get();
    619    if (session == null) {
    620      return;
    621    }
    622    ThreadUtils.postToUiThread(() -> {
    623      final FeatureDelegate delegate = session.getFeatureDelegate();
    624      if (delegate == null) {
    625          return;
    626      }
    627      delegate.feature();
    628    });
    629  }
    630 
    631 .. _permissions:
    632 
    633 Permissions
    634 -----------
    635 
    636 There are two separate but related permission concepts in GeckoView: `Content`
    637 permissions and `Android` permissions. See also the related `consumer doc
    638 <../consumer/permissions.html>`_ on permissions.
    639 
    640 Content permissions
    641 ~~~~~~~~~~~~~~~~~~~
    642 
    643 Content permissions are granted to individual web sites (more precisely,
    644 `principals`_) and are managed internally using ``nsIPermissionManager``.
    645 Content permissions are used by Gecko to keep track which website is allowed to
    646 access a group of Web APIs or functionality. The Web has the concept of
    647 permissions, but not all Gecko permissions map to Web-exposed permissions.
    648 
    649 For instance, the ``Notification`` permission, which allows websites to fire
    650 notifications to the user, is exposed to the Web through
    651 `Notification.requestPermission
    652 <https://developer.mozilla.org/en-US/docs/Web/API/Notification/requestPermission>`_,
    653 while the `autoplay` permission, which allows websites to play video and audio
    654 without user interaction, is not exposed to the Web and websites have no way to
    655 set or request this permission.
    656 
    657 GeckoView retains content permission data, which is an explicit violation of
    658 the design principle of not storing data. This is done because storing
    659 permissions is very complex, making a mistake when dealing with permissions
    660 often ends up being a security vulnerability, and because permissions depend on
    661 concepts that are not exposed to the GeckoView API like `principals`_.
    662 
    663 Android permissions
    664 ~~~~~~~~~~~~~~~~~~~
    665 
    666 Consumers of GeckoView are Android apps and therefore they have to receive
    667 permission to use certain features on behalf of websites.
    668 
    669 For instance, when a website requests Geolocation permission for the first
    670 time, the app needs to request the corresponding Geolocation Android permission
    671 in order to receive position data.
    672 
    673 You can read more about Android permissions on `this doc
    674 <https://developer.android.com/guide/topics/permissions/overview>`_.
    675 
    676 
    677 Implementation
    678 ~~~~~~~~~~~~~~
    679 
    680 The main entry point from Gecko is ``nsIContentPermissionPrompt.prompt``, which
    681 is handled in the `Permission module
    682 <https://searchfox.org/mozilla-central/rev/256f84391cf5d4e3a4d66afbbcd744a5bec48956/mobile/android/components/geckoview/GeckoViewPermission.jsm#21>`_
    683 in the same process where the request is originated.
    684 
    685 The permission module calls the child actor `GeckoViewPermission
    686 <https://searchfox.org/mozilla-central/rev/9dc5ffe42635b602d4ddfc9a4b8ea0befc94975a/mobile/android/actors/GeckoViewPermissionChild.jsm#47>`_
    687 which issues a `GeckoView:ContentPermission
    688 <https://searchfox.org/mozilla-central/rev/9dc5ffe42635b602d4ddfc9a4b8ea0befc94975a/mobile/android/actors/GeckoViewPermissionChild.jsm#75>`_
    689 request to the Java front-end as needed.
    690 
    691 Media permissions are requested using a global observer, and therefore are
    692 handled in a `Process actor
    693 <https://searchfox.org/mozilla-central/rev/9dc5ffe42635b602d4ddfc9a4b8ea0befc94975a/mobile/android/actors/GeckoViewPermissionProcessChild.jsm#41>`_,
    694 media permissions requests have enough information to redirect the request to
    695 the corresponding window child actor, with the exception of requests that are
    696 not associated with a window, which are redirected to the `current active
    697 window
    698 <https://searchfox.org/mozilla-central/rev/9dc5ffe42635b602d4ddfc9a4b8ea0befc94975a/mobile/android/actors/GeckoViewPermissionProcessParent.jsm#28-35>`_.
    699 
    700 Setting permissions
    701 ~~~~~~~~~~~~~~~~~~~
    702 
    703 Permissions are stored in a map between a `principal <#principals>`_ and a list
    704 of permission (key, value) pairs. To prevent security vulnerabilities, GeckoView
    705 does not provide a way to set permissions given an arbitrary URL and requires
    706 consumers to get hold of the `ContentPermission
    707 <https://mozilla.github.io/geckoview/javadoc/mozilla-central/org/mozilla/geckoview/GeckoSession.PermissionDelegate.ContentPermission.html>`_
    708 object. The ContentPermission object is returned in `onLocationChange
    709 <https://mozilla.github.io/geckoview/javadoc/mozilla-central/org/mozilla/geckoview/GeckoSession.NavigationDelegate.html#onLocationChange(org.mozilla.geckoview.GeckoSession,java.lang.String,java.util.List)>`_
    710 upon navigation, making it unlikely to have confusion bugs whereby the
    711 permission is given to the wrong website.
    712 
    713 Internally, some permissions are only present when a certain override is set,
    714 e.g. Tracking Protection override permissions are only present when the page
    715 has been given a TP override. Because the only way to set the value of a
    716 permission is to get hold of the ``ContentPermission`` object, `we manually insert
    717 <https://searchfox.org/mozilla-central/rev/5b2d2863bd315f232a3f769f76e0eb16cdca7cb0/mobile/android/modules/geckoview/GeckoViewNavigation.jsm#605-625>`_
    718 a `trackingprotection` permission on every page load.
    719 
    720 Autofill Support
    721 ----------------
    722 
    723 GeckoView supports third-party autofill providers through Android's `autofill framework <https://developer.android.com/guide/topics/text/autofill>`_. Internally, this support is referred to as `autofill`.
    724 
    725 Document tree
    726 ~~~~~~~~~~~~~
    727 
    728 The autofill Java front-end is located in the `Autofill class
    729 <https://searchfox.org/mozilla-central/rev/9dc5ffe42635b602d4ddfc9a4b8ea0befc94975a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/Autofill.java#37>`_.
    730 GeckoView maintains a virtual tree structure of the current document for each
    731 ``GeckoSession``.
    732 
    733 The virtual tree structure is composed of `Node
    734 <https://searchfox.org/mozilla-central/rev/9dc5ffe42635b602d4ddfc9a4b8ea0befc94975a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/Autofill.java#593>`_
    735 objects which are immutable. Data associated to a node, including mutable data
    736 like the current value, is stored in a separate `NodeData
    737 <https://searchfox.org/mozilla-central/rev/9dc5ffe42635b602d4ddfc9a4b8ea0befc94975a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/Autofill.java#171>`_
    738 class. Only HTML nodes that are relevant to autofilling are referenced in the
    739 virtual structure and each node is associated to a root node, e.g. the root
    740 ``<form>`` element. All root nodes are children of the autofill `mRoot
    741 <https://searchfox.org/mozilla-central/rev/9dc5ffe42635b602d4ddfc9a4b8ea0befc94975a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/Autofill.java#210>`_
    742 node, hence making the overall structure a tree rather than a collection of
    743 trees. Note that the root node is the only node in the virtual structure that
    744 does not correspond to an actual element on the page.
    745 
    746 Internally, nodes are assigned a unique ``UUID`` string, which is used to match
    747 nodes between the Java front-end and the data stored in GeckoView's chrome
    748 Javascript. The autofill framework itself requires integer IDs for nodes, so we
    749 store a mapping between UUIDs and integer IDs in the associated ``NodeData``
    750 object. The integer IDs are used only externally, while internally only the
    751 UUIDs are used. The reason why we use a separate ID structure from the autofill
    752 framework is that this allows us to `generate UUIDs
    753 <https://searchfox.org/mozilla-central/rev/7e34cb7a0094a2f325a0c9db720cec0a2f2aca4f/mobile/android/actors/GeckoViewAutoFillChild.jsm#217-220>`_
    754 directly in the isolated content processes avoiding an IPC roundtrip to the
    755 main process.
    756 
    757 Each ``Node`` object is associated to an ``EventCallback`` object which is
    758 invoked whenever the node is autofilled by the autofill framework.
    759 
    760 Detecting autofillable nodes
    761 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    762 
    763 GeckoView scans every web page for password ``<input>`` elements whenever the
    764 ``pageshow`` event `fires
    765 <https://searchfox.org/mozilla-central/rev/9dc5ffe42635b602d4ddfc9a4b8ea0befc94975a/mobile/android/actors/GeckoViewAutoFillChild.jsm#74-78>`_.
    766 
    767 It also uses ``DOMFormHasPassword`` and ``DOMInputPasswordAdded`` to detect
    768 whenever a password element is added to the DOM after the ``pageshow`` event.
    769 
    770 Prefs
    771 -----
    772 
    773 `Preferences </modules/libpref/index.html>`_ (or prefs) are used throughout
    774 Gecko to configure the browser, enable custom features, etc.
    775 
    776 GeckoView does not directly expose prefs to Apps. A limited set configuration
    777 options is exposed through ``GeckoRuntimeSettings``.
    778 
    779 ``GeckoRuntimeSettings`` can be easily mapped to a Gecko ``pref`` using
    780 ``Pref``, e.g.
    781 
    782 .. code:: java
    783 
    784  /* package */ final Pref<Boolean> mPrefExample =
    785     new Pref<Boolean>("example.pref", false);
    786 
    787 The value of the pref can then be read internally using ``mPrefExample.get``
    788 and written to using ``mPrefExample.commit``.
    789 
    790 Front-end and back-end
    791 ----------------------
    792 
    793    |code-layers|
    794 
    795 Gecko and GeckoView code can be divided in five layers:
    796 
    797 - **Java API** the outermost code layer that is publicly accessible to
    798  GeckoView embedders.
    799 - **Java Front-End** All the Java code that supports the API and talks directly
    800  to the Android APIs and to the JavaScript and C++ front-ends.
    801 - **JavaScript Front-End** The main interface to the Gecko back-end (or Gecko
    802  proper) in GeckoView is JavaScript, we use this layer to call into Gecko and
    803  other utilities provided by Gecko, code lives in ``mobile/android``
    804 - **C++ Front-End** A smaller part of GeckoView is written in C++ and interacts
    805  with Gecko directly, most of this code is lives in ``widget/android``.
    806 - **C++/Rust Back-End** This is often referred to as "platform", includes all
    807  core parts of Gecko and is usually accessed to in GeckoView from the C++
    808  front-end or the JavaScript front-end.
    809 
    810 Modules and Actors
    811 ------------------
    812 
    813 GeckoView's JavaScript Front-End is largely divided into units called modules
    814 and actors. For each feature, each window will have an instance of a Module, a
    815 parent-side Actor and (potentially many) content-side Actor instances. For a
    816 detailed description of this see `here <https://gist.github.com/agi/c900f3e473ff681158c0c907e34780e4#actors>`__.
    817 
    818 Testing infrastructure
    819 ----------------------
    820 
    821 For a detailed description of our testing infrastructure see `GeckoView junit
    822 Test Framework <junit.html>`_.
    823 
    824 .. |api-diagram| image:: ../assets/api-diagram.png
    825 .. |view-runtime-session| image:: ../assets/view-runtime-session.png
    826 .. |pageload-diagram| image:: ../assets/pageload-diagram.png
    827 .. |code-layers| image:: ../assets/code-layers.png