State Machine
Service state machine
The finite state machine is implemented in the IPProtectionService class
and the states are defined in the IPProtectionStates object.
Service states
The service transitions across the following states:
UNINITIALIZED: Service not initialized or feature disabled.UNAVAILABLE: User not eligible (Nimbus), signed out with no eligibility, or the feature is not sufficiently localized for a user who never interacted with it; UI hidden.UNAUTHENTICATED: User signed out but eligible; UI shows login.READY: Ready to activate the proxy.
High‑level transitions
Feature disabled →
UNINITIALIZED.During startup, if initialization isn’t complete, use cached state from
IPPStartupCache.Not eligible, or not localized enough for a user who never opened the panel →
UNAVAILABLE.Not signed in →
UNAVAILABLEif not eligible, otherwiseUNAUTHENTICATED.If an entitlement is cached/valid →
READY.Otherwise, check enrollment with Guardian (via
IPPFxaActivateAuthProvider.updateEntitlement()): - Not enrolled →UNAVAILABLE(not eligible). - Enrolled → fetch entitlement; if successful →READY, elseUNAVAILABLEwhen not eligible.
Events and integration points
IPProtectionService:StateChangedis dispatched on state changes withdetail.stateanddetail.prevState.Helpers can call
IPProtectionService.updateState()to recompute the state immediately; update any helper-owned data first because the call is synchronous.Public actions:
start(userAction),stop(userAction).
Proxy manager state machine
The IPPProxyManager layers a proxy‑specific finite state machine on top of
IPProtectionService. It mirrors eligibility changes from the service and
drives the lifecycle of the proxy connection.
Proxy states
NOT_READY: Service is notREADYand UI should not offer activation.READY: Service isREADYand the proxy can be activated.ACTIVATING:start()is working on an activation: waiting for the service while holding traffic behind a channel filter, then fetching a proxy pass and selecting an endpoint.ACTIVE: Proxy connected. Usage and network observers are reporting metrics.ERROR: An unrecoverable error occurred while the proxy is connected such as failing when rotating credentials. Stop must be called to change states.PAUSED: Everything is working but the bandwidth limit has been reached so we can’t connect to the VPN. The bandwidth will reset next month.
Proxy transitions
IPProtectionService:StateChanged→IPPProxyManager.updateState(): - ServiceREADY→ proxyREADY(resets connection/error history). - Any other service state → proxyNOT_READY(stops active connections).start(userAction)registers the channel filter before it yields, so traffic is held for the whole activation rather than from after the server list and auth round-trips. - FromREADYit moves toACTIVATING. - FromNOT_READYit waits, as long as the service could still become ready: while the startup cache is open every non-READYstate is a guess carried over from the previous session, and a service that is merely initializing is not an answer either. Once the real state is known,UNAVAILABLEandUNAUTHENTICATEDneed the user andstart()reportsERRORS.NOT_READYinstead of holding traffic.browser.ipProtection.serviceWaitTimeoutis the backstop. - Successful activation →ACTIVEand telemetryipprotection.started. - Failures during activation (missing entitlement, server list, proxy pass…) callupdateState()to demote the proxy back to its previous state. - Errors after the proxy is connected →ERRORvia#setErrorState.stop(userAction)fromACTIVE→READYafter closing the channel filter and observers. It also cancels an activation that is in flight, including one still waiting for the service.reset()or helper‑driven recomputations callupdateState()which demotes the proxy back toREADY/NOT_READYand clears the credential cache.Network errors (
proxy-http-errorwith 401) trigger Proxy Pass rotation while stayingACTIVE; repeated failures bubble up through#setErrorState.
Proxy events and hooks
IPPProxyManager:StateChangedis dispatched withdetail.statewhenever the proxy state machine moves.IPPProxyManagerlistens toIPProtectionService:StateChangedand toproxy-http-errorfromIPPNetworkErrorObserver.Consumers can observe
IPPProxyManager.state(or listen for events) to synchronize UI/telemetry with the proxy lifecycle.