Bug 1330151 - Push Architecture docs recovered from Bug 1207714 r=nalexander

Nick's original docs copy-pasted verbatim.

MozReview-Commit-ID: PPVXwoL6He

--HG--
extra : rebase_source : 3e59b34b2e1aceb9672dc5f5ec5be8461d8ed6a7
This commit is contained in:
Grigory Kruglov 2017-01-10 15:29:11 -08:00
Родитель cf9bae6821
Коммит 68302b82af
2 изменённых файлов: 157 добавлений и 0 удалений

Просмотреть файл

@ -17,6 +17,7 @@ Contents:
defaultdomains
bouncer
shutdown
push
Indices and tables
==================

Просмотреть файл

@ -0,0 +1,156 @@
.. -*- Mode: rst; fill-column: 80; -*-
=======================================================
The architecture of the Fennec Webpush implementation
=======================================================
Overview of the Push API
========================
The *Push API* is a Web API that allows web applications to "wake up" the User
Agent (the browser, Fennec), even when the application is not visible (or even
loaded in a tab). The Push API can only be used by secure sites that register a
Service Worker.
There are four major components in Push:
1. A *web application*;
2. The User Agent (Fennec);
3. An *app server* associated to the web application;
4. A *push service backend*.
These are listed roughly in the order that they appear in a successful push
message. First, the web application registers a Service Worker and requests a
*push subscription*. Fennec arranges a push channel and returns a subscription,
including a User-Agent-specific *push endpoint* URL to the web application. The
web application then provides that push endpoint URL to its app server. When
the app server wishes to push a message to the web application, it posts the
message and some additional meta-data to the provided push endpoint URL. The
message is received by the *push service backend* and delivered by some
unspecified out-of-band mechanism to the User Agent.
Two notes on terminology
------------------------
"Push notifications" mean many things to many people. In this system, "push
notifications" may or may not notify the user. Therefore, we use the term "push
messages" exclusively. This avoids confusing the push system with the "Web
Notification" API, which provides the familiar pop-up and system notification
based user interface.
Throughout, we use Fennec to refer to the Java-and-Android application shell,
and Gecko to refer to the embedded Gecko platform.
Overview of the Fennec Push implementation
==========================================
Fennec uses the Google Cloud Messaging (GCM) service to deliver messages to the
User Agent. Fennec registers for Google Cloud Messaging directly, like any
other Android App; however, consumers do not interact with GCM directly. To
provide a uniform interface to all consumers across all implementations, Fennec
intermediates through the Mozilla-specific *autopush* service. Autopush
maintains User Agent identification and authentication, provides per-web
application messaging channels, and bridges unauthenticated push messages to the
GCM delivery queue.
The Fennec Push implementation is designed to address the following technical
challenge: **GCM events, including incoming push messages, can occur when Gecko
is not running**.
In the future, Fennec will be able to start Gecko (more accurately, a particular
Gecko profile) in order to service incoming push messages. Right now, if a push
message is received and Gecko is not running (with the correct profile) to
service the message, it will be dropped on the floor (with
helpful-but-unsatisfying diagnostic messages). In particular, **neither the
sending application server nor the receiving web application are informed of the
failed delivery at any time!** (We may, at some point, choose to queue messages
on the device until Gecko can service them; and we may add support for
*receipts* to allow web applications to acknowledge successful message
delivery.)
It's worth noting that Fennec uses push to implement internal functionality like
Sync and Firefox Accounts, and that these background services are *not* tied to
Gecko being available.
Therefore, the principal constraints and requirements are:
1) Fennec must be able to service GCM events, including incoming push messages,
independently of Gecko.
2) Gecko must be able to maintain push subscriptions across its entire
life-cycle.
3) Fennec must be able to use push messages for non-Gecko purposes independently
of Gecko.
Significant previous experience building Fennec background services has shown
that configuring such services across the Gecko-Fennec interface is both
valuable and difficult. Therefore, we add the following requirement:
4) Gecko must own the push configuration details where appropriate and possible.
We explicitly do not care to support push messages across multiple processes.
This means that we **do not support the Push API in APK-based Web Apps that run
in a separate process**. (Such Web Apps are scheduled to be removed from Fennec
in the Nightly 46 development cycle.)
Push component architecture
===========================
Fennec components
-----------------
The two major components are the `PushManager` and the associated
`PushManagerStorage`. The `PushManager` interacts with the GCM system on the
device and the autopush service, updating the `PushManagerStorage` as the system
state changes.
There is a unique `PushManagerStorage` instance per-App that may only be
accessed by the main process. The `PushManagerStorage` maintains two mappings.
The first is a one-to-one mapping from a Gecko profile to a `PushRegistration`:
a datum of User Agent state. The `PushManager` maintains each profile's
registration across Android life-cycle events, Gecko events, and GCM events.
Each `PushRegistration` includes:
* autopush server configuration details;
* debug settings;
* profile details;
* access tokens and invalidation timestamps.
The second mapping is a one-to-many mapping from push registrations to
`PushSubscription` instances. A push subscription corresponds to a unique push
message channel from the autopush server to Fennec. Each `PushSubscription`
includes:
* a Fennec service identifier, like "webpush" or "Sync" or "Firefox Accounts";
* an associated Gecko profile;
* a unique channel identifier.
The `PushManager` uses the `PushSubscription` service and profile maintained in
the `PushManagerStorage` to determine how to deliver incoming GCM push messages.
Each `PushRegistration` corresponds to a unique *uaid* (User-Agent ID) on the
autopush server. Each *uaid* is long-lived; a healthy client will maintain the
same *uaid* until the client's configuration changes or the service expires the
registration due to inactivity or an unexpected server event. Each
`PushSubscription` is associated to a given *uaid* and correponds to a unique
(per-*uaid*) *chid* (Channel ID) on the autopush server. An individual *chid*
is potentially long-lived, but clients must expect the service to expire *chid*s
as part of regular maintainence. The `PushManager` uses an `AutopushClient`
instance to interact with the autopush server.
Between the `PushManager`, the `PushManagerStorage`, and assorted GCM event
broadcast receivers, push messages that do not target Gecko can be implemented.
Gecko components
----------------
The Gecko side of the architecture is implemented in JavaScript by the
`PushServiceAndroidGCM.jsm` module. This registers a PushService, like the Web
Socket and HTTP2 backed services, which simply delegates to the Fennec
`PushManager` using `Messaging.jsm` and friends.
There are some complications: first, Gecko must maintain the autopush
configuration; and second, it is possible for the push system to change while
Gecko is not running. Therefore, the communication is bi-directional
throughout, so that Gecko can react to Fennec events after-the-fact.