summaryrefslogtreecommitdiffstats
path: root/chrome/browser/remoting/remoting_setup_flow.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/remoting/remoting_setup_flow.cc')
-rw-r--r--chrome/browser/remoting/remoting_setup_flow.cc243
1 files changed, 177 insertions, 66 deletions
diff --git a/chrome/browser/remoting/remoting_setup_flow.cc b/chrome/browser/remoting/remoting_setup_flow.cc
index 9c71b9b..4a982db 100644
--- a/chrome/browser/remoting/remoting_setup_flow.cc
+++ b/chrome/browser/remoting/remoting_setup_flow.cc
@@ -19,8 +19,10 @@
#include "chrome/browser/profile.h"
#include "chrome/browser/remoting/remoting_resources_source.h"
#include "chrome/browser/remoting/remoting_setup_message_handler.h"
+#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/service/service_process_control.h"
#include "chrome/browser/service/service_process_control_manager.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/net/gaia/gaia_authenticator2.h"
#include "chrome/common/net/gaia/gaia_constants.h"
#include "chrome/common/net/gaia/google_service_auth_error.h"
@@ -29,14 +31,75 @@
#include "gfx/font.h"
#include "grit/locale_settings.h"
-// Use static Run method to get an instance.
+static const wchar_t kLoginIFrameXPath[] = L"//iframe[@id='login']";
+static const wchar_t kDoneIframeXPath[] = L"//iframe[@id='done']";
+
+////////////////////////////////////////////////////////////////////////////////
+// RemotingServiceProcessHelper
+//
+// This is a helper class to perform actions when the service process
+// is connected or launched. The events are sent back to RemotingSetupFlow
+// when the dialog is still active. RemotingSetupFlow can detach from this
+// helper class when the dialog is closed.
+class RemotingServiceProcessHelper :
+ public base::RefCountedThreadSafe<RemotingServiceProcessHelper> {
+ public:
+ RemotingServiceProcessHelper(RemotingSetupFlow* flow)
+ : flow_(flow) {
+ }
+
+ void Detach() {
+ flow_ = NULL;
+ }
+
+ void OnProcessLaunched() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+ // If the flow is detached then show the done page.
+ if (!flow_)
+ return;
+
+ flow_->OnProcessLaunched();
+ }
+
+ private:
+ RemotingSetupFlow* flow_;
+
+ DISALLOW_COPY_AND_ASSIGN(RemotingServiceProcessHelper);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// RemotingSetupFlow implementation.
+// static
+RemotingSetupFlow* RemotingSetupFlow::OpenDialog(Profile* profile) {
+ // Set the arguments for showing the gaia login page.
+ DictionaryValue args;
+ args.SetString("iframeToShow", "login");
+ args.SetString("user", "");
+ args.SetInteger("error", 0);
+ args.SetBoolean("editable_user", true);
+
+ if (profile->GetPrefs()->GetBoolean(prefs::kRemotingHasSetupCompleted)) {
+ args.SetString("iframeToShow", "done");
+ }
+
+ std::string json_args;
+ base::JSONWriter::Write(&args, false, &json_args);
+
+ Browser* b = BrowserList::GetLastActive();
+ if (!b)
+ return NULL;
+
+ RemotingSetupFlow* flow = new RemotingSetupFlow(json_args, profile);
+ b->BrowserShowHtmlDialog(flow, NULL);
+ return flow;
+}
+
RemotingSetupFlow::RemotingSetupFlow(const std::string& args, Profile* profile)
- : message_handler_(NULL),
+ : dom_ui_(NULL),
dialog_start_args_(args),
profile_(profile),
process_control_(NULL) {
- // TODO(hclam): We are currently leaking this objcet. Need to fix this!
- message_handler_ = new RemotingSetupMessageHandler(this);
+ // TODO(hclam): The data source should be added once.
ChromeThread::PostTask(
ChromeThread::IO, FROM_HERE,
NewRunnableMethod(Singleton<ChromeURLDataManager>::get(),
@@ -47,6 +110,25 @@ RemotingSetupFlow::RemotingSetupFlow(const std::string& args, Profile* profile)
RemotingSetupFlow::~RemotingSetupFlow() {
}
+void RemotingSetupFlow::Focus() {
+ // TODO(pranavk): implement this method.
+ NOTIMPLEMENTED();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// HtmlDialogUIDelegate implementation.
+GURL RemotingSetupFlow::GetDialogContentURL() const {
+ return GURL("chrome://remotingresources/setup");
+}
+
+void RemotingSetupFlow::GetDOMMessageHandlers(
+ std::vector<DOMMessageHandler*>* handlers) const {
+ // Create the message handler only after we are asked, the caller is
+ // responsible for deleting the objects.
+ handlers->push_back(
+ new RemotingSetupMessageHandler(const_cast<RemotingSetupFlow*>(this)));
+}
+
void RemotingSetupFlow::GetDialogSize(gfx::Size* size) const {
PrefService* prefs = profile_->GetPrefs();
gfx::Font approximate_web_font(
@@ -65,38 +147,37 @@ void RemotingSetupFlow::OnDialogClosed(const std::string& json_retval) {
// If we are fetching the token then cancel the request.
if (authenticator_.get())
authenticator_->CancelRequest();
+
+ // If the service process helper is still active then detach outself from it.
+ // This is because the dialog is closing and this object is going to be
+ // deleted but the service process launch is still in progress so we don't
+ // the service process helper to call us when the process is launched.
+ if (service_process_helper_.get())
+ service_process_helper_->Detach();
delete this;
}
-void RemotingSetupFlow::GetDOMMessageHandlers(
- std::vector<DOMMessageHandler*>* handlers) const {
- // Create the message handler only after we are asked.
- handlers->push_back(message_handler_);
+std::string RemotingSetupFlow::GetDialogArgs() const {
+ return dialog_start_args_;
}
-void RemotingSetupFlow::Focus() {
- // TODO(pranavk): implement this method.
- NOTIMPLEMENTED();
+void RemotingSetupFlow::OnCloseContents(TabContents* source,
+ bool* out_close_dialog) {
}
-void RemotingSetupFlow::OnUserSubmittedAuth(const std::string& user,
- const std::string& password,
- const std::string& captcha) {
- // Save the login name only.
- login_ = user;
+std::wstring RemotingSetupFlow::GetDialogTitle() const {
+ return l10n_util::GetString(IDS_REMOTING_SETUP_DIALOG_TITLE);
+}
- // Start the authenticator.
- authenticator_.reset(
- new GaiaAuthenticator2(this, GaiaConstants::kChromeSource,
- profile_->GetRequestContext()));
- authenticator_->StartClientLogin(user, password,
- GaiaConstants::kRemotingService,
- "", captcha);
+bool RemotingSetupFlow::IsDialogModal() const {
+ return true;
}
+///////////////////////////////////////////////////////////////////////////////
+// GaiaAuthConsumer implementation.
void RemotingSetupFlow::OnClientLoginFailure(
const GoogleServiceAuthError& error) {
- message_handler_->ShowGaiaFailed();
+ ShowGaiaFailed(error);
authenticator_.reset();
}
@@ -114,7 +195,7 @@ void RemotingSetupFlow::OnClientLoginSuccess(
void RemotingSetupFlow::OnIssueAuthTokenSuccess(const std::string& service,
const std::string& auth_token) {
// Show that Gaia login has succeeded.
- message_handler_->ShowGaiaSuccessAndSettingUp();
+ ShowGaiaSuccessAndSettingUp();
// Save the sync token.
sync_token_ = auth_token;
@@ -129,75 +210,105 @@ void RemotingSetupFlow::OnIssueAuthTokenSuccess(const std::string& service,
kServiceProcessRemoting);
if (process_control_->is_connected()) {
- OnProcessLaunched();
+ // TODO(hclam): Need to figure out what to do when the service process is
+ // already connected.
} else {
- // TODO(hclam): This is really messed up because I totally ignore the
- // lifetime of this object. I need a master cleanup on the lifetime of
- // objects.
+#if defined(OS_WIN)
// TODO(hclam): This call only works on Windows. I need to make it work
// on other platforms.
+ service_process_helper_ = new RemotingServiceProcessHelper(this);
process_control_->Launch(
- NewRunnableMethod(this, &RemotingSetupFlow::OnProcessLaunched));
+ NewRunnableMethod(service_process_helper_.get(),
+ &RemotingServiceProcessHelper::OnProcessLaunched));
+#else
+ ShowSetupDone();
+#endif
}
}
void RemotingSetupFlow::OnIssueAuthTokenFailure(const std::string& service,
const GoogleServiceAuthError& error) {
- // TODO(hclam): Do something to show the error.
+ ShowGaiaFailed(error);
authenticator_.reset();
}
-void RemotingSetupFlow::OnProcessLaunched() {
- if (!ChromeThread::CurrentlyOn(ChromeThread::UI)) {
- ChromeThread::PostTask(
- ChromeThread::UI,
- FROM_HERE,
- NewRunnableMethod(this, &RemotingSetupFlow::OnProcessLaunched));
- return;
- }
+///////////////////////////////////////////////////////////////////////////////
+// Methods called by RemotingSetupMessageHandler
+void RemotingSetupFlow::Attach(DOMUI* dom_ui) {
+ dom_ui_ = dom_ui;
+}
+void RemotingSetupFlow::OnUserSubmittedAuth(const std::string& user,
+ const std::string& password,
+ const std::string& captcha) {
+ // Save the login name only.
+ login_ = user;
+
+ // Start the authenticator.
+ authenticator_.reset(
+ new GaiaAuthenticator2(this, GaiaConstants::kChromeSource,
+ profile_->GetRequestContext()));
+ authenticator_->StartClientLogin(user, password,
+ GaiaConstants::kRemotingService,
+ "", captcha);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Method called by RemotingServicePRocessHelper
+void RemotingSetupFlow::OnProcessLaunched() {
DCHECK(process_control_->is_connected());
+ // TODO(hclam): Need to wait for an ACK to be sure that it is actually active.
process_control_->EnableRemotingWithTokens(login_, remoting_token_,
sync_token_);
- message_handler_->ShowSetupDone();
// Save the preference that we have completed the setup of remoting.
profile_->GetPrefs()->SetBoolean(prefs::kRemotingHasSetupCompleted, true);
+ ShowSetupDone();
}
-// static
-RemotingSetupFlow* RemotingSetupFlow::Run(Profile* profile) {
- // Set the arguments for showing the gaia login page.
+///////////////////////////////////////////////////////////////////////////////
+// Helper methods for showing contents of the DOM UI
+void RemotingSetupFlow::ShowGaiaLogin(const DictionaryValue& args) {
+ if (dom_ui_)
+ dom_ui_->CallJavascriptFunction(L"showGaiaLoginIframe");
+
+ std::string json;
+ base::JSONWriter::Write(&args, false, &json);
+ std::wstring javascript = std::wstring(L"showGaiaLogin") +
+ L"(" + UTF8ToWide(json) + L");";
+ ExecuteJavascriptInIFrame(kLoginIFrameXPath, javascript);
+}
+
+void RemotingSetupFlow::ShowGaiaSuccessAndSettingUp() {
+ ExecuteJavascriptInIFrame(kLoginIFrameXPath,
+ L"showGaiaSuccessAndSettingUp();");
+}
+
+void RemotingSetupFlow::ShowGaiaFailed(const GoogleServiceAuthError& error) {
DictionaryValue args;
args.SetString("iframeToShow", "login");
args.SetString("user", "");
- args.SetInteger("error", 0);
+ args.SetInteger("error", error.state());
args.SetBoolean("editable_user", true);
+ args.SetString("captchaUrl", error.captcha().image_url.spec());
+ ShowGaiaLogin(args);
+}
- if (profile->GetPrefs()->GetBoolean(prefs::kRemotingHasSetupCompleted)) {
- args.SetString("iframeToShow", "done");
- }
+void RemotingSetupFlow::ShowSetupDone() {
+ std::wstring javascript = L"setMessage('You are all set!');";
+ ExecuteJavascriptInIFrame(kDoneIframeXPath, javascript);
- std::string json_args;
- base::JSONWriter::Write(&args, false, &json_args);
+ if (dom_ui_)
+ dom_ui_->CallJavascriptFunction(L"showSetupDone");
- RemotingSetupFlow* flow = new RemotingSetupFlow(json_args, profile);
- Browser* b = BrowserList::GetLastActive();
- if (b) {
- b->BrowserShowHtmlDialog(flow, NULL);
- } else {
- delete flow;
- return NULL;
- }
- return flow;
+ ExecuteJavascriptInIFrame(kDoneIframeXPath, L"onPageShown();");
}
-// Global function to start the remoting setup dialog.
-void OpenRemotingSetupDialog(Profile* profile) {
- RemotingSetupFlow::Run(profile->GetOriginalProfile());
+void RemotingSetupFlow::ExecuteJavascriptInIFrame(
+ const std::wstring& iframe_xpath,
+ const std::wstring& js) {
+ if (dom_ui_) {
+ RenderViewHost* rvh = dom_ui_->tab_contents()->render_view_host();
+ rvh->ExecuteJavascriptInWebFrame(iframe_xpath, js);
+ }
}
-
-// TODO(hclam): Need to refcount RemotingSetupFlow. I need to fix
-// lifetime of objects.
-DISABLE_RUNNABLE_METHOD_REFCOUNT(RemotingSetupFlow);
-DISABLE_RUNNABLE_METHOD_REFCOUNT(RemotingSetupMessageHandler);