зеркало из https://github.com/mozilla/gecko-dev.git
78 строки
4.2 KiB
ReStructuredText
78 строки
4.2 KiB
ReStructuredText
.. -*- Mode: rst; fill-column: 100; -*-
|
|
|
|
===================================
|
|
Shutting down Firefox for Android
|
|
===================================
|
|
|
|
Background
|
|
==========
|
|
|
|
Normally, apps on Android don't need to provide any support for explicit quitting, instead they are
|
|
just sent into the background where they eventually get killed by the OS's low-memory killer.
|
|
|
|
Nevertheless, Firefox on Android allows explicit quitting to support the use case of users wanting
|
|
to clear part or all of their private data after finishing a browsing session. When this option to
|
|
"Clear private data on exit" is activated from the settings, a "Quit" button is provided in the menu.
|
|
|
|
Because Firefox on Android uses a native UI (written in Java), which also holds some of the user's
|
|
browsing data, this creates some additional complications when compared to quitting on desktop.
|
|
|
|
Technical details
|
|
=================
|
|
|
|
When the "Quit" button is used, the UI sends a ``Browser:Quit`` notification to Gecko's ``BrowserApp``,
|
|
which initiates the normal Gecko shutdown procedure. At the same time however, the native UI needs to
|
|
shutdown as well, so as to
|
|
|
|
1) provide an immediate visual feedback to the user that Firefox is indeed quitting
|
|
|
|
2) avoid a state where the UI is still running "normally" while the rendering engine is already
|
|
shutting down, which could lead to losing incoming external tabs if they were to arrive within
|
|
that period.
|
|
|
|
Therefore, shutdown of the native UI was originally started simultaneously with notifying Gecko.
|
|
Because the clearing of private data during shutdown is handled by Gecko's ``Sanitizer``, while some
|
|
private data, e.g. the browsing history, is held in a database by the native UI, this means that
|
|
Gecko needs to message the native UI during shutdown if the user wants the browsing history to be
|
|
cleared on quitting.
|
|
Shutting down the UI simultaneously with Gecko therefore introduced a race condition where the data
|
|
clearing could fail because the native UI thread responsible for receiving Gecko's sanitization
|
|
messages had already exited by the time Gecko's ``Sanitizer`` was attempting to e.g. clear the
|
|
user's browsing history (for further reading, compare `bug 1266594
|
|
<https://bugzilla.mozilla.org/show_bug.cgi?id=1266594>`_).
|
|
|
|
To fix this issue, the native UI (in ``GeckoApp``) now waits for the ``Sanitizer`` to run and
|
|
message all necessary sanitization handlers and only starts its shutdown after receiving a
|
|
``Sanitize:Finished`` message with a ``shutdown: true`` parameter set. While this introduces a
|
|
certain delay in closing the UI, it is still faster than having to wait for Gecko to exit completely
|
|
before starting to close the UI.
|
|
|
|
Currently, quitting Firefox therefore proceeds roughly as follows:
|
|
|
|
1) The user presses the "Quit" button in the main menu, which sends a ``Browser:Quit`` notification
|
|
to ``BrowserApp``. This notification also contains additional parameters indicating which types
|
|
of private user data - if any - to clear during shutdown.
|
|
|
|
2) ``BrowserApp.quit`` runs, which initiates Gecko shutdown by sending out a
|
|
``quit-application-requested`` notification.
|
|
|
|
3) If nobody cancelled shutdown in response to the ``quit-application-requested`` notification,
|
|
quitting proceeds and the ``SessionStore`` enters shutdown mode (``STATE_QUITTING``), which
|
|
basically means that no new (asynchronous) writes are started to prevent any interference with
|
|
the final flushing of data.
|
|
|
|
4) ``BrowserApp`` calls the ``Sanitizer`` to clear up any private user data that might need cleaning.
|
|
After the ``Sanitizer`` has invoked all required sanitization handlers (including any on the
|
|
native Java UI side, e.g. for the browsing history) and finished running, it sends a
|
|
``Sanitize:Finished`` message back to the native UI.
|
|
|
|
5) On receiving the ``Sanitize:Finished`` message, ``GeckoApp`` starts the shutdown of the native UI
|
|
as well by calling ``doShutdown()``.
|
|
|
|
6) After sending the ``Sanitize:Finished`` message, Gecko's ``Sanitizer`` runs the callback provided
|
|
by ``BrowserApp.quit``, which is ``appStartup.quit(Ci.nsIAppStartup.eForceQuit)``, thereby
|
|
starting the actual and final shutting down of Gecko.
|
|
|
|
7) On receiving the final ``quit-application`` notification, the ``SessionStore`` synchronously
|
|
writes its current state to disk.
|