text: // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
  #ifndef CHROME_BROWSER_CHROMEOS_MOBILE_MOBILE_ACTIVATOR_H_
  #define CHROME_BROWSER_CHROMEOS_MOBILE_MOBILE_ACTIVATOR_H_
  
  #include <map>
  #include <string>
  
  #include "base/files/file_path.h"
  #include "base/gtest_prod_util.h"
  #include "base/memory/scoped_ptr.h"
  #include "base/memory/singleton.h"
  #include "base/memory/weak_ptr.h"
  #include "base/observer_list.h"
  #include "base/timer/timer.h"
  #include "chromeos/network/network_handler_callbacks.h"
  #include "chromeos/network/network_state_handler_observer.h"
  
  namespace base {
  class DictionaryValue;
  }
  
  namespace chromeos {
  
  class NetworkState;
  class TestMobileActivator;
  
  // Cellular plan config document.
  class CellularConfigDocument
      : public base::RefCountedThreadSafe<CellularConfigDocument> {
   public:
    CellularConfigDocument();
  
    // Return error message for a given code.
    std::string GetErrorMessage(const std::string& code);
    void LoadCellularConfigFile();
    const std::string& version() { return version_; }
  
   private:
    friend class base::RefCountedThreadSafe<CellularConfigDocument>;
    typedef std::map<std::string, std::string> ErrorMap;
  
    virtual ~CellularConfigDocument();
  
    void SetErrorMap(const ErrorMap& map);
    bool LoadFromFile(const base::FilePath& config_path);
  
    std::string version_;
    ErrorMap error_map_;
    base::Lock config_lock_;
  
    DISALLOW_COPY_AND_ASSIGN(CellularConfigDocument);
  };
  
  // This class performs mobile plan activation process.
  class MobileActivator
      : public base::SupportsWeakPtr<MobileActivator>,
        public NetworkStateHandlerObserver {
   public:
    // Activation state.
    enum PlanActivationState {
      // Activation WebUI page is loading, activation not started.
      PLAN_ACTIVATION_PAGE_LOADING            = -1,
      // Activation process started.
      PLAN_ACTIVATION_START                   = 0,
      // Initial over the air activation attempt.
      PLAN_ACTIVATION_TRYING_OTASP            = 1,
      // Performing pre-activation process.
      PLAN_ACTIVATION_INITIATING_ACTIVATION   = 3,
      // Reconnecting to network. Used for networks activated over cellular
      // connection.
      PLAN_ACTIVATION_RECONNECTING            = 4,
      // Passively waiting for a network connection. Used for networks activated
      // over non-cellular network.
      PLAN_ACTIVATION_WAITING_FOR_CONNECTION  = 5,
      // Loading payment portal page.
      PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING  = 6,
      // Showing payment portal page.
      PLAN_ACTIVATION_SHOWING_PAYMENT         = 7,
      // Decides whether to load the portal again or call us done.
      PLAN_ACTIVATION_RECONNECTING_PAYMENT    = 8,
      // Delaying activation until payment portal catches up.
      PLAN_ACTIVATION_DELAY_OTASP             = 9,
      // Starting post-payment activation attempt.
      PLAN_ACTIVATION_START_OTASP             = 10,
      // Attempting activation.
      PLAN_ACTIVATION_OTASP                   = 11,
      // Finished activation.
      PLAN_ACTIVATION_DONE                    = 12,
      // Error occured during activation process.
      PLAN_ACTIVATION_ERROR                   = 0xFF,
    };
  
    // Activation process observer.
    class Observer {
     public:
      // Signals activation |state| change for given |network|.
      virtual void OnActivationStateChanged(
          const NetworkState* network,
          PlanActivationState state,
          const std::string& error_description) = 0;
  
     protected:
      Observer() {}
      virtual ~Observer() {}
    };
  
    static MobileActivator* GetInstance();
  
    // Add/remove activation process observer.
    void AddObserver(Observer* observer);
    void RemoveObserver(Observer* observer);
  
    // Activation is in process.
    bool RunningActivation() const;
    // Activation state.
    PlanActivationState state() const { return state_; }
    // Initiates activation process.  Can only be called from the UI thread.
    void InitiateActivation(const std::string& service_path);
    // Terminates activation process if already started.
    void TerminateActivation();
    // Process portal load attempt status.
    void OnPortalLoaded(bool success);
    // Process payment transaction status.
    void OnSetTransactionStatus(bool success);
  
   private:
    friend struct DefaultSingletonTraits<MobileActivator>;
    friend class TestMobileActivator;
    FRIEND_TEST_ALL_PREFIXES(MobileActivatorTest, BasicFlowForNewDevices);
    FRIEND_TEST_ALL_PREFIXES(MobileActivatorTest, OTASPScheduling);
    FRIEND_TEST_ALL_PREFIXES(MobileActivatorTest,
                             ReconnectOnDisconnectFromPaymentPortal);
    FRIEND_TEST_ALL_PREFIXES(MobileActivatorTest, StartAtStart);
    // We reach directly into the activator for testing purposes.
    friend class MobileActivatorTest;
  
    MobileActivator();
    virtual ~MobileActivator();
  
    // NetworkStateHandlerObserver overrides.
    virtual void DefaultNetworkChanged(const NetworkState* network) OVERRIDE;
    virtual void NetworkPropertiesUpdated(const NetworkState* network) OVERRIDE;
  
    // Continue activation after inital setup (config load). Makes an
    // asynchronous call to NetworkConfigurationHandler::GetProperties.
    void ContinueActivation();
    void GetPropertiesAndContinueActivation(
        const std::string& service_path,
        const base::DictionaryValue& properties);
    void GetPropertiesFailure(const std::string& error_name,
                              scoped_ptr<base::DictionaryValue> error_data);
    // Handles the signal that the payment portal has finished loading.
    void HandlePortalLoaded(bool success);
    // Handles the signal that the user has finished with the portal.
    void HandleSetTransactionStatus(bool success);
    // Starts activation.
    void StartActivation();
    // Called after we delay our OTASP (after payment).
    void RetryOTASP();
    // Continues activation process. This method is called after we disconnect
    // due to detected connectivity issue to kick off reconnection.
    void ContinueConnecting();
  
    // Sends message to host registration page with system/user info data.
    void SendDeviceInfo();
  
    // Starts OTASP process.
    void StartOTASP();
    // Called when an OTASP attempt times out.
    void HandleOTASPTimeout();
    // Forces disconnect / reconnect when we detect portal connectivity issues.
    void ForceReconnect(const NetworkState* network,
                        PlanActivationState next_state);
    // Called when ForceReconnect takes too long to reconnect.
    void ReconnectTimedOut();
  
    // Called on default network changes to update cellular network activation
    // state.
    void RefreshCellularNetworks();
  
    // Helper to get network state corresponding to service path. Provided
    // for easy mocking in unit tests.
    virtual const NetworkState* GetNetworkState(const std::string& service_path);
  
    // Verify the state of cellular network and modify internal state.
    virtual void EvaluateCellularNetwork(const NetworkState* network);
    // PickNextState selects the desired state based on the current state of the
    // modem and the activator.  It does not transition to this state however.
    PlanActivationState PickNextState(const NetworkState* network,
                                      std::string* error_description) const;
    // One of PickNext*State are called in PickNextState based on whether the
    // modem is online or not.
    PlanActivationState PickNextOnlineState(const NetworkState* network) const;
    PlanActivationState PickNextOfflineState(const NetworkState* network) const;
    // Check the current cellular network for error conditions.
    bool GotActivationError(const NetworkState* network,
                            std::string* error) const;
    // Sends status updates to WebUI page.
    void UpdatePage(const NetworkState* network,
                    const std::string& error_description);
  
    // Callback used to handle an activation error.
    void HandleActivationFailure(
        const std::string& service_path,
        PlanActivationState new_state,
        const std::string& error_name,
        scoped_ptr<base::DictionaryValue> error_data);
  
    // Request cellular activation for |network|.
    // On success, |success_callback| will be called.
    // On failure, |error_callback| will be called.
    virtual void RequestCellularActivation(
        const NetworkState* network,
        const base::Closure& success_callback,
        const network_handler::ErrorCallback& error_callback);
  
    // Changes internal state.
    virtual void ChangeState(const NetworkState* network,
                             PlanActivationState new_state,
                             std::string error_description);
    // Resets network devices after cellular activation process.
    void CompleteActivation();
    // Disables SSL certificate revocation checking mechanism. In the case
    // where captive portal connection is the only one present, such revocation
    // checks could prevent payment portal page from loading.
    void DisableCertRevocationChecking();
    // Reenables SSL certificate revocation checking mechanism.
    void ReEnableCertRevocationChecking();
    // Return error message for a given code.
    std::string GetErrorMessage(const std::string& code) const;
  
    // Performs activation state cellular device evaluation.
    // Returns false if device activation failed. In this case |error|
    // will contain error message to be reported to Web UI.
    static bool EvaluateCellularDeviceState(bool* report_status,
                                            std::string* state,
                                            std::string* error);
    // Starts the OTASP timeout timer.  If the timer fires, we'll force a
    // disconnect/reconnect cycle on this network.
    virtual void StartOTASPTimer();
  
    // Records information that cellular plan payment has happened.
    virtual void SignalCellularPlanPayment();
  
    // Returns true if cellular plan payment has been recorded recently.
    virtual bool HasRecentCellularPlanPayment() const;
  
    static const char* GetStateDescription(PlanActivationState state);
  
    scoped_refptr<CellularConfigDocument> cellular_config_;
    // Internal handler state.
    PlanActivationState state_;
    // MEID of cellular device to activate.
    std::string meid_;
    // ICCID of the SIM card on cellular device to activate.
    std::string iccid_;
    // Service path of network being activated. Note that the path can change
    // during the activation process while still representing the same service.
    std::string service_path_;
    // Device on which the network service is activated. While the service path
    // can change during activation due to modem resets, the device path stays
    // the same.
    std::string device_path_;
    // Flags that controls if cert_checks needs to be restored
    // after the activation of cellular network.
    bool reenable_cert_check_;
    // True if activation process has been terminated.
    bool terminated_;
    // True if an asynchronous activation request was dispatched to Shill
    // but the succcess or failure of the request is yet unknown.
    bool pending_activation_request_;
    // Connection retry counter.
    int connection_retry_count_;
    // Counters for how many times we've tried each OTASP step.
    int initial_OTASP_attempts_;
    int trying_OTASP_attempts_;
    int final_OTASP_attempts_;
    // Payment portal reload/reconnect attempt count.
    int payment_reconnect_count_;
    // Timer that monitors how long we spend in error-prone states.
    base::RepeatingTimer<MobileActivator> state_duration_timer_;
  
    // State we will return to if we are disconnected.
    PlanActivationState post_reconnect_state_;
    // Called to continue the reconnect attempt.
    base::RepeatingTimer<MobileActivator> continue_reconnect_timer_;
    // Called when the reconnect attempt times out.
    base::OneShotTimer<MobileActivator> reconnect_timeout_timer_;
    // Cellular plan payment time.
    base::Time cellular_plan_payment_time_;
  
    ObserverList<Observer> observers_;
    base::WeakPtrFactory<MobileActivator> weak_ptr_factory_;
  
    DISALLOW_COPY_AND_ASSIGN(MobileActivator);
  };
  
  }  // namespace chromeos
  
  #endif  // CHROME_BROWSER_CHROMEOS_MOBILE_MOBILE_ACTIVATOR_H_
  