Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions specifications/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -1051,6 +1051,7 @@ The core SDK provides an API for wrapper SDKs to supply Ably with analytics info
### Activation State Machine

- `(RSH3)` In platforms that support receiving push notifications, in order to connect the device's push features with Ably's, the library must perform the process described in the following abstract state machine. While this process should be implemented in whatever way better fits the concrete platform, it should be taken into account that its lifetime is that of the *app* that runs it, which outlives that of the `RestClient` instance or (typically) the process running the app. This typically forces some kind of on-disk storage to which the state machine's state must be persisted, so that it can be recovered later by new instances and processes running the app triggered by external events.
- `(RSH3h)` The Activation State Machine is initialised when first required (i.e. when an event first needs to be delivered to it). Initialisation comprises, in order: (1) the `LocalDevice` is initialised per [`RSH8a`](#RSH8a), which may, per [`RSH8a1`](#RSH8a1), discard the persisted Activation State Machine data; (2) the in-memory state machine is then constructed from the persisted Activation State Machine data, or starts in `NotActivated` if no such data is persisted. The state machine must not process any events before this initialisation has completed.
- `(RSH3a)` State `NotActivated` (the initial one).
- `(RSH3a1)` On event `CalledDeactivate`:
- `(RSH3a1a)` This clause has been deleted. It was valid up to and including specification version `3.0.0`.
Expand Down Expand Up @@ -1169,8 +1170,9 @@ The core SDK provides an API for wrapper SDKs to supply Ably with analytics info
- `(RSH8)` In platforms that support receiving push notifications, the `device` method on the `RestClient` or `RealtimeClient` interfaces returns an instance of `LocalDevice` that represents the current state of the device in respect of it being a target for push notifications.
- `(RSH8k)` `LocalDevice` has the following attributes:
- `(RSH8k1)` `deviceIdentityToken` string? -- populated as described in [RSH8c](#RSH8c)
- `(RSH8k2)` `deviceSecret` string -- populated as described in [RSH8b](#RSH8b). (Note: This property being non-nullable is not actually consistent with [`RSH3a2b`](#RSH3a2b); that spec point implies that `id` and `deviceSecret` both start off unset and are only set upon a `CalledActivate` event. However, since `deviceSecret` needs to have the same nullability as `id` --- since per `RSH3a2b` either both or neither should be set --- to reflect the behaviour described in the spec we would have to make `LocalDevice#id` nullable, but this is incompatible with the superclass `DeviceDetails`. In reality, our implementations of `LocalDevice` actually generate `id` and `deviceSecret` when the device is fetched, i.e. not following `RSH3a2b`. What we *should* do is either make `LocalDevice` stop inheriting from `DeviceDetails`, or change the specified behaviour for when to generate `id` and `deviceSecret` to match our implementations, or both. See spec issues [#180](https://github.com/ably/specification/issues/180) and [#25](https://github.com/ably/specification/issues/25). For now, this note exists to reduce confusion.)
- `(RSH8a)` The `LocalDevice` is initialised when first required, either as a result of a call to `RestClient#device` or `RealtimeClient#device`, or as a result of an operation involving the Activation State Machine. The `LocalDevice` `id`, `clientId`, `deviceSecret` and `deviceIdentityToken` attributes are populated, together with any `recipient`-related attributes, to the extent that they exist, from the persisted state.
- `(RSH8k2)` `deviceSecret` string -- populated as described in [RSH8b](#RSH8b). (Note: This property being non-nullable is not actually consistent with [`RSH3a2b`](#RSH3a2b); that spec point implies that `id` and `deviceSecret` both start off unset and are only set upon a `CalledActivate` event. However, since `deviceSecret` needs to have the same nullability as `id` --- since per [`RSH3a2b`](#RSH3a2b) either both or neither should be set --- to reflect the behaviour described in the spec we would have to make `LocalDevice#id` nullable, but this is incompatible with the superclass `DeviceDetails`. In reality, ably-cocoa and ably-js actually generate `id` and `deviceSecret` when the device is fetched, i.e. not following [`RSH3a2b`](#RSH3a2b). ably-java follows [`RSH3a2b`](#RSH3a2b), allowing `id` to be `null` (this doesn't affect the public API because nullability is not a concept in Java's type system). What we *should* do is either make `LocalDevice` stop inheriting from `DeviceDetails`, or change the specified behaviour for when to generate `id` and `deviceSecret` to match our implementations, or both. See spec issues [#180](https://github.com/ably/specification/issues/180) and [#25](https://github.com/ably/specification/issues/25). For now, this note exists to reduce confusion.)
- `(RSH8a)` The `LocalDevice` is initialised when first required, either as a result of a call to `RestClient#device` or `RealtimeClient#device`, or as a result of the Activation State Machine being initialised (see [`RSH3h`](#RSH3h)). The `LocalDevice` `id`, `clientId`, `deviceSecret` and `deviceIdentityToken` attributes are populated, together with any `recipient`-related attributes, to the extent that they exist, from the persisted state.
- `(RSH8a1)` If loading the `LocalDevice` `id` or `deviceSecret` attributes fails, then: (1) all persisted `LocalDevice` attributes must be discarded; (2) all persisted Activation State Machine data must be discarded — combined with [`RSH3h`](#RSH3h), this ensures that the state machine starts in `NotActivated`. (Non-normative: this clause imposes no requirement on when new `id` and `deviceSecret` attributes are generated; their generation is governed by [`RSH8b`](#RSH8b). SDKs that exhibit the non-conforming eager generation behaviour noted in [`RSH8k2`](#RSH8k2) will instead regenerate them as part of the same `LocalDevice` initialisation.)
- `(RSH8b)` The `LocalDevice` `id` and `deviceSecret` attributes are generated, and persisted as part of the `LocalDevice` state, when required by step [`RSH3a2b`](#RSH3a2b) in the Activation State Machine. At that time, the `clientId` attribute is also initialised, if the client is identified according to [`RSA7`](#RSA7).
- `(RSH8c)` Following successful registration of a `LocalDevice`, following the procedure in [`RSH3c2a`](#RSH3c2a), the now known `deviceIdentityToken` is set and persisted.
- `(RSH8d)` If the `LocalDevice` is created by an unidentified client (see [`RSA7`](#RSA7) ) and therefore has no `clientId` set, but the client subsequently becomes identified (as a result of [`RSA7b2`](#RSA7b2) or [`RSA7b3`](#RSA7b3) ), then the `LocalDevice` `clientId` is set and persisted.
Expand All @@ -1179,7 +1181,7 @@ The core SDK provides an API for wrapper SDKs to supply Ably with analytics info
- `(RSH8g)` Whenever any change arises of the push transport details for local device (eg an FCM registration token update triggered by the platform), a `GotPushDeviceDetails` event is sent to [the state machine](#RSH3).
- `(RSH8h)` If an attempt to obtain the push transport details for local device (eg an FCM registration token) fails, a `GettingPushDeviceDetailsFailed` event containing the indicated error is sent to [the state machine](#RSH3).
- `(RSH8i)` Each time the library is instantiated, if the LocalDevice has push device details (eg an APNS deviceToken), and if the platform supports it, it must verify the validity of those details (eg by requesting a token from the platform and comparing that with the already-known token). If as a result there are updated details, then an update to the Ably server is triggered by sending a `GotPushDeviceDetails` event to [the state machine](#RSH3).
- `(RSH8j)` If during library initialisation the `LocalDevice` `id` or `deviceSecret` attributes are not able to be loaded then those LocalDevice details must be discarded and the ActivationStateMachine machine should transition to the `NotActivated` state. New `LocalDevice` `id` and `deviceSecret` attributes should be generated on the next activation event.
- `(RSH8j)` This clause has been replaced by [`RSH8a1`](#RSH8a1).

## Types

Expand Down
Loading