// Copyright (c) 2011 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_REMOTING_SETUP_FLOW_H_ #define CHROME_BROWSER_REMOTING_SETUP_FLOW_H_ #include "base/callback.h" #include "base/memory/scoped_ptr.h" #include "chrome/browser/ui/webui/html_dialog_ui.h" #include "chrome/common/remoting/chromoting_host_info.h" #include "content/browser/webui/web_ui.h" class ListValue; class ServiceProcessControl; namespace remoting { class SetupFlow; // SetupFlowStep represents a single step for SetupFlow, e.g. login or // host registration. When a step is finished, GetNextStep() is called // to get the step that must follow. class SetupFlowStep { public: typedef Callback0::Type DoneCallback; SetupFlowStep(); virtual ~SetupFlowStep(); // Start the step. Ownership of |done_callback| is given to the // function. |done_callback| is called when the step is finished, // The callback must be called on the same thread as Start(). virtual void Start(SetupFlow* flow, DoneCallback* done_callback) = 0; // Called to handle |message| received from UI. |args| may be set to // NULL. virtual void HandleMessage(const std::string& message, const Value* arg) = 0; // Called if user closes the dialog. virtual void Cancel() = 0; // Returns SetupFlowStep object that corresponds to the next // step. Must never return NULL. virtual SetupFlowStep* GetNextStep() = 0; private: DISALLOW_COPY_AND_ASSIGN(SetupFlowStep); }; // SetupFlowStepBase implements base functions common for all // SetupFlowStep implementations. class SetupFlowStepBase : public SetupFlowStep { public: SetupFlowStepBase(); ~SetupFlowStepBase(); // SetupFlowStep implementation. virtual void Start(SetupFlow* flow, DoneCallback* done_callback); virtual SetupFlowStep* GetNextStep(); protected: SetupFlow* flow() { return flow_; } void ExecuteJavascriptInIFrame(const std::wstring& iframe_xpath, const std::wstring& js); // Finish current step. Calls |done_callback| specified in Start(). // GetNextStep() will return the specified |next_step|. void FinishStep(SetupFlowStep* next_step); // Called from Start(). Child classes must override this method // instead of Start(). virtual void DoStart() = 0; private: SetupFlow* flow_; scoped_ptr done_callback_; bool done_; // Next step stored between Done() and GetNextStep(); SetupFlowStep* next_step_; DISALLOW_COPY_AND_ASSIGN(SetupFlowStepBase); }; // Base class for error steps. It shows the error message returned by // GetErrorMessage() and Retry button. class SetupFlowErrorStepBase : public SetupFlowStepBase { public: SetupFlowErrorStepBase(); virtual ~SetupFlowErrorStepBase(); // SetupFlowStep implementation. virtual void HandleMessage(const std::string& message, const Value* arg); virtual void Cancel(); protected: virtual void DoStart(); // Returns error message that is shown to the user. virtual string16 GetErrorMessage() = 0; // Called when user clicks Retry button. Normally this methoud just // calls FinishStep() with an appropriate next step. virtual void Retry() = 0; private: DISALLOW_COPY_AND_ASSIGN(SetupFlowErrorStepBase); }; // The last step in the setup flow. This step never finishes, user is // expected to close dialog after that. class SetupFlowDoneStep : public SetupFlowStepBase { public: SetupFlowDoneStep(); explicit SetupFlowDoneStep(const string16& message); virtual ~SetupFlowDoneStep(); // SetupFlowStep implementation. virtual void HandleMessage(const std::string& message, const Value* arg); virtual void Cancel(); protected: virtual void DoStart(); private: string16 message_; DISALLOW_COPY_AND_ASSIGN(SetupFlowDoneStep); }; // SetupFlowContext stores data that needs to be passed between // different setup flow steps. struct SetupFlowContext { SetupFlowContext(); ~SetupFlowContext(); std::string login; std::string remoting_token; std::string talk_token; ChromotingHostInfo host_info; }; // This class is responsible for showing a remoting setup dialog and // perform operations to fill the content of the dialog and handle // user actions in the dialog. // // Each page in the setup flow may send message to the current // step. In order to do that it must use send a RemotingSetup message // and specify message name as the first value in the argument // list. For example the following code sends Retry message to the // current step: // // chrome.send("RemotingSetup", ["Retry"]) // // Assitional message parameters may be provided via send value in the // arguments list, e.g.: // // chrome.send("RemotingSetup", ["SubmitAuth", auth_data]) // // In this case auth_data would be passed in // SetupFlowStep::HandleMessage(). class SetupFlow : public WebUIMessageHandler, public HtmlDialogUIDelegate { public: virtual ~SetupFlow(); static SetupFlow* OpenSetupDialog(Profile* profile); WebUI* web_ui() { return web_ui_; } Profile* profile() { return profile_; } SetupFlowContext* context() { return &context_; } private: explicit SetupFlow(const std::string& args, Profile* profile, SetupFlowStep* first_step); // HtmlDialogUIDelegate implementation. virtual GURL GetDialogContentURL() const; virtual void GetWebUIMessageHandlers( std::vector* handlers) const; virtual void GetDialogSize(gfx::Size* size) const; virtual std::string GetDialogArgs() const; virtual void OnDialogClosed(const std::string& json_retval); virtual void OnCloseContents(TabContents* source, bool* out_close_dialog); virtual std::wstring GetDialogTitle() const; virtual bool IsDialogModal() const; virtual bool ShouldShowDialogTitle() const; // WebUIMessageHandler implementation. virtual WebUIMessageHandler* Attach(WebUI* web_ui); virtual void RegisterMessages(); // Message handlers for the messages we receive from UI. void HandleSubmitAuth(const ListValue* args); void HandleUIMessage(const ListValue* args); void StartCurrentStep(); void OnStepDone(); // Pointer to the Web UI. This is provided by RemotingSetupMessageHandler // when attached. WebUI* web_ui_; // The args to pass to the initial page. std::string dialog_start_args_; Profile* profile_; SetupFlowContext context_; scoped_ptr current_step_; DISALLOW_COPY_AND_ASSIGN(SetupFlow); }; } // namespace remoting #endif // CHROME_BROWSER_REMOTING_SETUP_FLOW_H_