1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_SYNC_SYNC_SETUP_FLOW_H_
6#define CHROME_BROWSER_SYNC_SYNC_SETUP_FLOW_H_
7#pragma once
8
9#include <string>
10#include <vector>
11
12#include "base/gtest_prod_util.h"
13#include "base/time.h"
14#include "chrome/browser/sync/profile_sync_service.h"
15#include "chrome/browser/sync/sync_setup_wizard.h"
16#include "chrome/browser/sync/syncable/model_type.h"
17#include "chrome/browser/ui/webui/html_dialog_ui.h"
18#include "ui/base/l10n/l10n_util.h"
19#include "ui/gfx/native_widget_types.h"
20
21class SyncSetupFlowHandler;
22class SyncSetupFlowContainer;
23
24// A structure which contains all the configuration information for sync.
25// This can be stored or passed around when the configuration is managed
26// by multiple stages of the wizard.
27struct SyncConfiguration {
28  SyncConfiguration();
29  ~SyncConfiguration();
30
31  bool sync_everything;
32  syncable::ModelTypeSet data_types;
33  bool use_secondary_passphrase;
34  std::string secondary_passphrase;
35};
36
37// The state machine used by SyncSetupWizard, exposed in its own header
38// to facilitate testing of SyncSetupWizard.  This class is used to open and
39// run the sync setup overlay in tabbed options and deletes itself when the
40// overlay closes.
41class SyncSetupFlow {
42 public:
43  virtual ~SyncSetupFlow();
44
45  // Runs a flow from |start| to |end|, and does the work of actually showing
46  // the HTML dialog.  |container| is kept up-to-date with the lifetime of the
47  // flow (e.g it is emptied on dialog close).
48  static SyncSetupFlow* Run(ProfileSyncService* service,
49                            SyncSetupFlowContainer* container,
50                            SyncSetupWizard::State start,
51                            SyncSetupWizard::State end);
52
53  // Fills |args| with "user" and "error" arguments by querying |service|.
54  static void GetArgsForGaiaLogin(
55      const ProfileSyncService* service,
56      DictionaryValue* args);
57
58  // Fills |args| for the configure screen (Choose Data Types/Encryption)
59  static void GetArgsForConfigure(
60      ProfileSyncService* service,
61      DictionaryValue* args);
62
63  // Fills |args| for the enter passphrase screen.
64  static void GetArgsForEnterPassphrase(
65      bool tried_creating_explicit_passphrase,
66      bool tried_setting_explicit_passphrase,
67      DictionaryValue* args);
68
69  void AttachSyncSetupHandler(SyncSetupFlowHandler* handler);
70
71  // Triggers a state machine transition to advance_state.
72  void Advance(SyncSetupWizard::State advance_state);
73
74  // Focuses the dialog.  This is useful in cases where the dialog has been
75  // obscured by a browser window.
76  void Focus();
77
78  void OnUserSubmittedAuth(const std::string& username,
79                           const std::string& password,
80                           const std::string& captcha,
81                           const std::string& access_code);
82
83  void OnUserConfigured(const SyncConfiguration& configuration);
84
85  // The 'passphrase' screen is used when the user is prompted to enter
86  // an existing passphrase.
87  void OnPassphraseEntry(const std::string& passphrase);
88
89  // The user canceled the passphrase entry without supplying a passphrase.
90  void OnPassphraseCancel();
91
92  // The 'first passphrase' screen is for users migrating from a build
93  // without passwords, who are prompted to make a passphrase choice.
94  // TODO(jhawkins): This is no longer used; remove this method.
95  void OnFirstPassphraseEntry(const std::string& option,
96                              const std::string& passphrase);
97
98  void OnGoToDashboard();
99
100  void OnDialogClosed(const std::string& json_retval);
101
102 private:
103  FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest, InitialStepLogin);
104  FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest, ChooseDataTypesSetsPrefs);
105  FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest, DialogCancelled);
106  FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest, InvalidTransitions);
107  FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest, FullSuccessfulRunSetsPref);
108  FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest, AbortedByPendingClear);
109  FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest, DiscreteRunGaiaLogin);
110  FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest, DiscreteRunChooseDataTypes);
111  FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest,
112                           DiscreteRunChooseDataTypesAbortedByPendingClear);
113  FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest, EnterPassphraseRequired);
114  FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest, PassphraseMigration);
115
116  // Use static Run method to get an instance.
117  SyncSetupFlow(SyncSetupWizard::State start_state,
118                SyncSetupWizard::State end_state,
119                const std::string& args,
120                SyncSetupFlowContainer* container,
121                ProfileSyncService* service);
122
123  // Returns true if |this| should transition its state machine to |state|
124  // based on |current_state_|, or false if that would be nonsense or is
125  // a no-op.
126  bool ShouldAdvance(SyncSetupWizard::State state);
127
128  void ActivateState(SyncSetupWizard::State state);
129
130  SyncSetupFlowContainer* container_;  // Our container.  Don't own this.
131  std::string dialog_start_args_;  // The args to pass to the initial page.
132
133  SyncSetupWizard::State current_state_;
134  SyncSetupWizard::State end_state_;  // The goal.
135
136  // Time that the GAIA_LOGIN step was received.
137  base::TimeTicks login_start_time_;
138
139  // The handler needed for the entire flow. Weak reference.
140  SyncSetupFlowHandler* flow_handler_;
141
142  // We need this to propagate back all user settings changes. Weak reference.
143  ProfileSyncService* service_;
144
145  // Set to true if we've tried creating/setting an explicit passphrase, so we
146  // can appropriately reflect this in the UI.
147  bool tried_creating_explicit_passphrase_;
148  bool tried_setting_explicit_passphrase_;
149
150  DISALLOW_COPY_AND_ASSIGN(SyncSetupFlow);
151};
152
153// A really simple wrapper for a SyncSetupFlow so that we don't have to
154// add any public methods to the public SyncSetupWizard interface to notify it
155// when the dialog closes.
156class SyncSetupFlowContainer {
157 public:
158  SyncSetupFlowContainer() : flow_(NULL) { }
159  void set_flow(SyncSetupFlow* flow) {
160    DCHECK(!flow_ || !flow);
161    flow_ = flow;
162  }
163
164  SyncSetupFlow* get_flow() { return flow_; }
165 private:
166  SyncSetupFlow* flow_;
167
168  DISALLOW_COPY_AND_ASSIGN(SyncSetupFlowContainer);
169};
170
171#endif  // CHROME_BROWSER_SYNC_SYNC_SETUP_FLOW_H_
172