Commit e83bd826 authored by Marc Treib's avatar Marc Treib Committed by Commit Bot

Update and clean up components/invalidations/impl/README.md

Bug: 1054367
Change-Id: Ibb282217b3ac905d107035b020cbed1a33103cd0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2089752
Commit-Queue: Marc Treib <treib@chromium.org>
Reviewed-by: default avatarMaksim Moskvitin <mmoskvitin@google.com>
Cr-Commit-Position: refs/heads/master@{#747617}
parent 896b5b09
# Invalidations Component # Invalidations Component
### Introduction ## Introduction
Let's start with an example. On Chrome OS there exists a concept called Let's start with an example. On Chrome OS there exists a concept called
"policy" - one can think of them as dynamic flags that change Chrome's "policy" - one can think of them as dynamic flags that change Chrome's
behaviour. They are changed on the Admin Panel from where they get propagated behaviour. They are changed on the Admin Panel from where they get propagated
...@@ -22,157 +22,128 @@ the server, so should the copy of this object in the client device. All the ...@@ -22,157 +22,128 @@ the server, so should the copy of this object in the client device. All the
invalidation related interaction between client device and server is done invalidation related interaction between client device and server is done
through Invalidation Service. through Invalidation Service.
**Invalidation** (message to invalidate some object) is sent and received using An **Invalidation** (a message to invalidate some object) is sent and received
a publish/subscribe service. We have a couple of those publish/subscribe using a publish/subscribe service. In practice, this is Firebase Cloud Messaging
services, some of which are Tango - [go/tango](http://go/tango) and Fandango - (FCM, see
[go/fandango](http://go/fandango). [firebase.google.com/docs/cloud-messaging](https://firebase.google.com/docs/cloud-messaging)
or [go/fcm](http://go/fcm)) and Fandango (see
[go/fandango](http://go/fandango)).
In general the whole thing looks as follows: In general the whole thing looks as follows:
![Invalidations component UML](../images/InvalidationService.png) ![Invalidations component UML](../images/InvalidationService.png)
*** ***
### InvalidationHandler ## Terminology
* **InstanceID**: An identifier for "a specific app installed on a specific
device". The term comes from GMSCore on Android. Here, an "app" is a client of
invalidations, such as Sync, Drive, or Policy. It's just a mostly random
string of 8 bytes, created by Chrome.
* **Registration**: As in "registering with FCM"; means making an InstanceID
known to the FCM server. The result of registering is an **InstanceID token**
(note that this is different from an InstanceID).
* **Topic**: A "namespace" or "channel" of messages that clients can subscribe
to. For Sync, they correspond to data types. A topic can be either private
(i.e. GAIA-keyed) or public. For private topics, a unique ID derived from the
user's GAIA ID is appended to the topic name to make it unique (though this
is an implementation detail which is hidden from clients).
* **Subscription**: As in "subscribing to a topic", i.e. telling the server that
this client (identified by InstanceID token) is interested in a given topic.
* **ProjectID** (aka **SenderID**): An ID from the Google Cloud Platform console
that identifies a client of invalidations (such as Sync, Drive, or Policy).
E.g. for Sync its value is kInvalidationGCMSenderId. Note that (as opposed to
InstanceID) this is constant across all users and Chrome instances.
***
## Classes
**InvalidationHandler** - is a client of InvalidationService (see below). ### InvalidationHandler
Everyone who wants to use InvalidationService to receive Invalidation
(notification of change in some object) needs to implement
**InvalidationHandler** to receive those messages. **InvalidationHandler** has
the following methods (the list is not full):
* **OnIncomingInvalidation** - is called from InvalidationService to notify An **InvalidationHandler** is a client (receiver) of Invalidations. Every
about incoming Invalidation. feature that wants to receive Invalidations needs to implement an
InvalidationHandler and register it with InvalidationService (see below).
InvalidationHandler has the following methods (the list is not exhaustive):
At the end of documentation, one can find the additional material for adding * **OnIncomingInvalidation** is called from InvalidationService to notify
**InvalidationHandler**. about incoming Invalidation messages.
* **GetOwnerName** must return a unique name for this InvalidationHandler.
*** ***
### InvalidationService ### InvalidationService
Class **InvalidationService** is just an interface which provides the following **InvalidationService** is the main entry point for clients of the Invalidations
methods (the list is not exhaustive). system. This is where an InvalidationHandler registers/unregisters itself, and
where it registers the Topics it is interested in. When a message arrives,
InvalidationService calls OnIncomingInvalidation for the receiving
InvalidationHandler.
InvalidationService provides the following methods (the list is not exhaustive):
* **RegisterInvalidationHandler** - allows InvalidationHandler to register * **RegisterInvalidationHandler** allows an InvalidationHandler to register
itself as a observer for Invalidations. **InvalidationService** will only itself as a observer for Invalidations. InvalidationService will only
dispatch messages to registered handlers. dispatch messages to registered handlers.
* **UpdateInterestedTopics** allows InvalidationHandler to change the set of
Topics it is interested in.
* **UnregisterInvalidationHandler** lets an InvalidationHandler unregister
itself again, after which it stops receiving Invalidations.
* **UpdateRegisteredInvalidationIds** - allows InvalidationHandler to change the An InvalidationService instance is usually tied to a profile (via
ids of Objects it is interested in receiving Invalidations for. **ProfileInvalidationProviderFactory**), but on ChromeOS there is also a
device-scoped instance, managed by **AffiliatedInvalidationServiceProvider**
* **UnregisterInvalidationHandler** - when InvalidationHandler unregisters it (used for device policies, which must apply even before any user is signed in).
stops receiving Invalidations.
*** ***
### FCMInvalidationService ### FCMInvalidationService
**FCMInvalidationService** - is the implementation of InvalidationService that **FCMInvalidationService** is the only real (non-test) implementation of
uses [Fandango](http://go/fandango) as its publish/subscribe service. InvalidationService, using [FCM](http://go/fcm)+[Fandango](http://go/fandango)
as its publish/subscribe service. It delegates most of the work to
**FCMInvalidationService** is the main entry point for InvalidationHandler. This InvalidatorRegistrarWithMemory and FCMInvalidationListener.
is where InvalidationHandler registers/unregisters itself in
InvalidationService, and registers Objects to invalidate. When a message comes,
**FCMInvalidationService** calls OnIncomingInvalidation for the receiving
InvalidationHandler.
Actually **FCMInvalidationService** just provides the abstraction above for
InvalidationHandler, while in fact it just manages
InvalidatorRegistrarWithMemory and FCMInvalidationListener, who do the actual
work.
*** ***
### InvalidatorRegistrarWithMemory ### InvalidatorRegistrarWithMemory
**InvalidatorRegistrarWithMemory** stores registered InvalidationHandlers, **InvalidatorRegistrarWithMemory** maintains the mapping between Topics and
stores objects to invalidate and stores mapping between objects and InvalidationHandlers. When a message arrives via FCMInvalidationListener,
InvalidationHandlers to know which InvalidationHandlers are interested in which InvalidatorRegistrarWithMemory dispatches that message (invalidation) to the
objects. When a message comes from FCMInvalidationListener, appropriate InvalidationHandler.
**InvalidatorRegistrarWithMemory** dispatches that message (Invalidation) to the
receiving InvalidationHandler. InvalidatorRegistrarWithMemory also persists the set of Topics per handler, to
avoid redundant re-subscriptions after every Chrome restart.
*** ***
### FCMInvalidationListener ### FCMInvalidationListener
**FCMInvalidationListener** just gets the list of topics to subscribe from **FCMInvalidationListener** gets the list of interesting Topics from
FCMInvalidationService, and when **FCMInvalidationListener** receives FCMInvalidationService. It passes the Topics to PerUserTopicSubscriptionManager
Invalidations on those topics, it just passes them up to FCMInvalidationService. (see below) for subscription/unsubscription, receives Invalidation messages from
FCMNetworkHandler, and passes Invalidations for the interesting Topics back to
And again the description above is just a good abstraction of FCMInvalidationService.
**FCMInvalidationListener** for FCMInvalidationService, while in fact
**FCMInvalidationListener** manages PerUserTopicRegistrationManager and
FCMNetworkHandler who do the actual work.
*** ***
### PerUserTopicRegistrationManager ### PerUserTopicSubscriptionManager
**PerUserTopicRegistrationManager** manages subscriptions to topics. Topics in **PerUserTopicSubscriptionManager** manages subscriptions to Topics, sending
this case are objects we are interested in invalidating. subscription or unsubscriptions requests to the server as necessary. It persists
the set of subscribed Topics in prefs to avoid redundant re-subscriptions after
Chrome restarts.
*** ***
### FCMNetworkHandler ### FCMNetworkHandler
**FCMNetworkHandler** is the class responsible for communication via GCM **FCMNetworkHandler** is responsible for communication via GCM channel. It
channel. Provides the following functionality: provides the following functionality:
* Retrieves the auth token required for the subscription. When this token is
received, it is passed to PerUserTopicRegistrationManager which subscribes to
topics with the given auth token.
* Retrieves the InstanceID token required for the subscription. When this token
is received, it is passed to PerUserTopicSubscriptionManager which subscribes
to Topics with the given token.
* Receives messages from GCM driver and passes them up to * Receives messages from GCM driver and passes them up to
FCMInvalidationListener, where they are converted to Invalidations. FCMInvalidationListener, where they are converted to Invalidations.
***
### TiclInvalidationService (deprecated)
TiclInvalidationService - is the implementation of InvalidationService that uses
[Tango](http://go/tango) as its publish/subscribe service.
***
## For those who want to add InvalidationHandler
### Public vs. Private topics
FCMInvalidationService has a different registration process for public and
private topics. When registering with a public topic, publish/subscribe service
will fan out all outgoing messages to all devices subscribed to this topic. For
example: If a device subscribes to "DeviceGuestModeEnabled" public topic all
instances subscribed to this topic will receive all outgoing messages addressed
to topic "DeviceGuestModeEnabled". But if 2 devices with different InstanceID
subscribe to private topic "BOOKMARK", they will receive different set of
messages addressed to pair ("BOOKMARK", InstanceID) respectively.
### Project Id
In the UML diagram above there are 3 classes that inherit from
InvalidationHandler:
* SyncEngineImpl
* CloudPolicyInvalidator
* DriveNotificationManager
There is a notion of SenderId which is different for every InvalidationHandler.
SenderId is used when registering to topics, to receive a topic of a particular
sender. So for example server side logic of CloudPolicy posts messages using
SenderId of "1013309121859", and client side logic which is
CloudPolicyInvalidator should register to topics using the SenderId
"1013309121859".
### InvalidationService for profile and for device
Usually InvalidationService is bound to a profile which can be spinned up using
**ProfileInvalidationProviderFactory**, but sometimes there is no profile as in
the special case of CloudPolicyInvalidator. CloudPolicyInvalidator is interested
in receiving Invalidations on policies. Chrome OS team defines 2 types of
policies - User and Device. Device policies should be received even when there
is no one signed in to a Chrome OS device, thus there is no profile. For this
reason there is a special class **AffiliatedInvalidationServiceProvider** which
spawns InvalidationService even when there is no profile.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment