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_REMOTING_SETUP_FLOW_H_
6#define CHROME_BROWSER_REMOTING_SETUP_FLOW_H_
7
8#include "base/callback.h"
9#include "base/memory/scoped_ptr.h"
10#include "chrome/browser/ui/webui/html_dialog_ui.h"
11#include "chrome/common/remoting/chromoting_host_info.h"
12#include "content/browser/webui/web_ui.h"
13
14class ListValue;
15class ServiceProcessControl;
16
17namespace remoting {
18
19class SetupFlow;
20
21// SetupFlowStep represents a single step for SetupFlow, e.g. login or
22// host registration. When a step is finished, GetNextStep() is called
23// to get the step that must follow.
24class SetupFlowStep {
25 public:
26  typedef Callback0::Type DoneCallback;
27
28  SetupFlowStep();
29  virtual ~SetupFlowStep();
30
31  // Start the step. Ownership of |done_callback| is given to the
32  // function. |done_callback| is called when the step is finished,
33  // The callback must be called on the same thread as Start().
34  virtual void Start(SetupFlow* flow, DoneCallback* done_callback) = 0;
35
36  // Called to handle |message| received from UI. |args| may be set to
37  // NULL.
38  virtual void HandleMessage(const std::string& message, const Value* arg) = 0;
39
40  // Called if user closes the dialog.
41  virtual void Cancel() = 0;
42
43  // Returns SetupFlowStep object that corresponds to the next
44  // step. Must never return NULL.
45  virtual SetupFlowStep* GetNextStep() = 0;
46
47 private:
48  DISALLOW_COPY_AND_ASSIGN(SetupFlowStep);
49};
50
51// SetupFlowStepBase implements base functions common for all
52// SetupFlowStep implementations.
53class SetupFlowStepBase : public SetupFlowStep {
54 public:
55  SetupFlowStepBase();
56  ~SetupFlowStepBase();
57
58  // SetupFlowStep implementation.
59  virtual void Start(SetupFlow* flow, DoneCallback* done_callback);
60  virtual SetupFlowStep* GetNextStep();
61
62 protected:
63  SetupFlow* flow() { return flow_; }
64
65  void ExecuteJavascriptInIFrame(const std::wstring& iframe_xpath,
66                                 const std::wstring& js);
67
68  // Finish current step. Calls |done_callback| specified in Start().
69  // GetNextStep() will return the specified |next_step|.
70  void FinishStep(SetupFlowStep* next_step);
71
72  // Called from Start(). Child classes must override this method
73  // instead of Start().
74  virtual void DoStart() = 0;
75
76 private:
77  SetupFlow* flow_;
78  scoped_ptr<DoneCallback> done_callback_;
79  bool done_;
80
81  // Next step stored between Done() and GetNextStep();
82  SetupFlowStep* next_step_;
83
84  DISALLOW_COPY_AND_ASSIGN(SetupFlowStepBase);
85};
86
87// Base class for error steps. It shows the error message returned by
88// GetErrorMessage() and Retry button.
89class SetupFlowErrorStepBase : public SetupFlowStepBase {
90 public:
91  SetupFlowErrorStepBase();
92  virtual ~SetupFlowErrorStepBase();
93
94  // SetupFlowStep implementation.
95  virtual void HandleMessage(const std::string& message, const Value* arg);
96  virtual void Cancel();
97
98 protected:
99  virtual void DoStart();
100
101  // Returns error message that is shown to the user.
102  virtual string16 GetErrorMessage() = 0;
103
104  // Called when user clicks Retry button. Normally this methoud just
105  // calls FinishStep() with an appropriate next step.
106  virtual void Retry() = 0;
107
108 private:
109  DISALLOW_COPY_AND_ASSIGN(SetupFlowErrorStepBase);
110};
111
112// The last step in the setup flow. This step never finishes, user is
113// expected to close dialog after that.
114class SetupFlowDoneStep : public SetupFlowStepBase {
115 public:
116  SetupFlowDoneStep();
117  explicit SetupFlowDoneStep(const string16& message);
118  virtual ~SetupFlowDoneStep();
119
120  // SetupFlowStep implementation.
121  virtual void HandleMessage(const std::string& message, const Value* arg);
122  virtual void Cancel();
123
124 protected:
125  virtual void DoStart();
126
127 private:
128  string16 message_;
129
130  DISALLOW_COPY_AND_ASSIGN(SetupFlowDoneStep);
131};
132
133// SetupFlowContext stores data that needs to be passed between
134// different setup flow steps.
135struct SetupFlowContext {
136  SetupFlowContext();
137  ~SetupFlowContext();
138
139  std::string login;
140  std::string remoting_token;
141  std::string talk_token;
142
143  ChromotingHostInfo host_info;
144};
145
146// This class is responsible for showing a remoting setup dialog and
147// perform operations to fill the content of the dialog and handle
148// user actions in the dialog.
149//
150// Each page in the setup flow may send message to the current
151// step. In order to do that it must use send a RemotingSetup message
152// and specify message name as the first value in the argument
153// list. For example the following code sends Retry message to the
154// current step:
155//
156//     chrome.send("RemotingSetup", ["Retry"])
157//
158// Assitional message parameters may be provided via send value in the
159// arguments list, e.g.:
160//
161//     chrome.send("RemotingSetup", ["SubmitAuth", auth_data])
162//
163// In this case auth_data would be passed in
164// SetupFlowStep::HandleMessage().
165class SetupFlow : public WebUIMessageHandler,
166                  public HtmlDialogUIDelegate {
167 public:
168  virtual ~SetupFlow();
169
170  static SetupFlow* OpenSetupDialog(Profile* profile);
171
172  WebUI* web_ui() { return web_ui_; }
173  Profile* profile() { return profile_; }
174  SetupFlowContext* context() { return &context_; }
175
176 private:
177  explicit SetupFlow(const std::string& args, Profile* profile,
178                     SetupFlowStep* first_step);
179
180  // HtmlDialogUIDelegate implementation.
181  virtual GURL GetDialogContentURL() const;
182  virtual void GetWebUIMessageHandlers(
183      std::vector<WebUIMessageHandler*>* handlers) const;
184  virtual void GetDialogSize(gfx::Size* size) const;
185  virtual std::string GetDialogArgs() const;
186  virtual void OnDialogClosed(const std::string& json_retval);
187  virtual void OnCloseContents(TabContents* source, bool* out_close_dialog);
188  virtual std::wstring GetDialogTitle() const;
189  virtual bool IsDialogModal() const;
190  virtual bool ShouldShowDialogTitle() const;
191
192  // WebUIMessageHandler implementation.
193  virtual WebUIMessageHandler* Attach(WebUI* web_ui);
194  virtual void RegisterMessages();
195
196  // Message handlers for the messages we receive from UI.
197  void HandleSubmitAuth(const ListValue* args);
198  void HandleUIMessage(const ListValue* args);
199
200  void StartCurrentStep();
201  void OnStepDone();
202
203  // Pointer to the Web UI. This is provided by RemotingSetupMessageHandler
204  // when attached.
205  WebUI* web_ui_;
206
207  // The args to pass to the initial page.
208  std::string dialog_start_args_;
209  Profile* profile_;
210
211  SetupFlowContext context_;
212
213  scoped_ptr<SetupFlowStep> current_step_;
214
215  DISALLOW_COPY_AND_ASSIGN(SetupFlow);
216};
217
218}  // namespace remoting
219
220#endif  // CHROME_BROWSER_REMOTING_SETUP_FLOW_H_
221