mobile/android/base/fxa/login/FxAccountLoginStateMachine.java

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/mobile/android/base/fxa/login/FxAccountLoginStateMachine.java	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,84 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +package org.mozilla.gecko.fxa.login;
     1.9 +
    1.10 +import java.security.NoSuchAlgorithmException;
    1.11 +import java.util.HashSet;
    1.12 +import java.util.Set;
    1.13 +
    1.14 +import org.mozilla.gecko.background.fxa.FxAccountClient;
    1.15 +import org.mozilla.gecko.browserid.BrowserIDKeyPair;
    1.16 +import org.mozilla.gecko.fxa.login.FxAccountLoginTransition.Transition;
    1.17 +import org.mozilla.gecko.fxa.login.State.StateLabel;
    1.18 +
    1.19 +public class FxAccountLoginStateMachine {
    1.20 +  public static final String LOG_TAG = FxAccountLoginStateMachine.class.getSimpleName();
    1.21 +
    1.22 +  public interface LoginStateMachineDelegate {
    1.23 +    public FxAccountClient getClient();
    1.24 +    public long getCertificateDurationInMilliseconds();
    1.25 +    public long getAssertionDurationInMilliseconds();
    1.26 +    public void handleTransition(Transition transition, State state);
    1.27 +    public void handleFinal(State state);
    1.28 +    public BrowserIDKeyPair generateKeyPair() throws NoSuchAlgorithmException;
    1.29 +  }
    1.30 +
    1.31 +  public static class ExecuteDelegate {
    1.32 +    protected final LoginStateMachineDelegate delegate;
    1.33 +    protected final StateLabel desiredStateLabel;
    1.34 +    // It's as difficult to detect arbitrary cycles as repeated states.
    1.35 +    protected final Set<StateLabel> stateLabelsSeen = new HashSet<StateLabel>();
    1.36 +
    1.37 +    protected ExecuteDelegate(StateLabel initialStateLabel, StateLabel desiredStateLabel, LoginStateMachineDelegate delegate) {
    1.38 +      this.delegate = delegate;
    1.39 +      this.desiredStateLabel = desiredStateLabel;
    1.40 +      this.stateLabelsSeen.add(initialStateLabel);
    1.41 +    }
    1.42 +
    1.43 +    public FxAccountClient getClient() {
    1.44 +      return delegate.getClient();
    1.45 +    }
    1.46 +
    1.47 +    public long getCertificateDurationInMilliseconds() {
    1.48 +      return delegate.getCertificateDurationInMilliseconds();
    1.49 +    }
    1.50 +
    1.51 +    public long getAssertionDurationInMilliseconds() {
    1.52 +      return delegate.getAssertionDurationInMilliseconds();
    1.53 +    }
    1.54 +
    1.55 +    public BrowserIDKeyPair generateKeyPair() throws NoSuchAlgorithmException {
    1.56 +      return delegate.generateKeyPair();
    1.57 +    }
    1.58 +
    1.59 +    public void handleTransition(Transition transition, State state) {
    1.60 +      // Always trigger the transition callback.
    1.61 +      delegate.handleTransition(transition, state);
    1.62 +
    1.63 +      // Possibly trigger the final callback. We trigger if we're at our desired
    1.64 +      // state, or if we've seen this state before.
    1.65 +      StateLabel stateLabel = state.getStateLabel();
    1.66 +      if (stateLabel == desiredStateLabel || stateLabelsSeen.contains(stateLabel)) {
    1.67 +        delegate.handleFinal(state);
    1.68 +        return;
    1.69 +      }
    1.70 +
    1.71 +      // If this wasn't the last state, leave a bread crumb and move on to the
    1.72 +      // next state.
    1.73 +      stateLabelsSeen.add(stateLabel);
    1.74 +      state.execute(this);
    1.75 +    }
    1.76 +  }
    1.77 +
    1.78 +  public void advance(State initialState, final StateLabel desiredStateLabel, final LoginStateMachineDelegate delegate) {
    1.79 +    if (initialState.getStateLabel() == desiredStateLabel) {
    1.80 +      // We're already where we want to be!
    1.81 +      delegate.handleFinal(initialState);
    1.82 +      return;
    1.83 +    }
    1.84 +    ExecuteDelegate executeDelegate = new ExecuteDelegate(initialState.getStateLabel(), desiredStateLabel, delegate);
    1.85 +    initialState.execute(executeDelegate);
    1.86 +  }
    1.87 +}

mercurial