Index: chrome/browser/views/sync/sync_setup_flow.cc |
=================================================================== |
--- chrome/browser/views/sync/sync_setup_flow.cc (revision 0) |
+++ chrome/browser/views/sync/sync_setup_flow.cc (revision 0) |
@@ -0,0 +1,240 @@ |
+// Copyright (c) 2009 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. |
+ |
+#ifdef CHROME_PERSONALIZATION |
+ |
+#include "base/json_reader.h" |
+#include "base/json_writer.h" |
+#include "base/string_util.h" |
+#include "base/values.h" |
+#include "chrome/browser/browser.h" |
+#include "chrome/browser/browser_list.h" |
+#include "chrome/browser/renderer_host/render_view_host.h" |
+#include "chrome/browser/sync/auth_error_state.h" |
+#include "chrome/browser/sync/profile_sync_service.h" |
+#include "chrome/browser/tab_contents/tab_contents.h" |
+#include "chrome/browser/views/sync/sync_setup_flow.h" |
+#include "chrome/common/pref_service.h" |
+ |
+static const int kSyncDialogWidth = 267; |
+static const int kSyncDialogHeight = 369; |
+ |
+// XPath expression for finding specific iframes. |
+static const wchar_t* kLoginIFrameXPath = L"//iframe[@id='login']"; |
+static const wchar_t* kMergeIFrameXPath = L"//iframe[@id='merge']"; |
+ |
+// Helper function to read the JSON string from the Value parameter. |
+static std::string GetJsonResponse(const Value* content) { |
+ if (!content || !content->IsType(Value::TYPE_LIST)) { |
+ NOTREACHED(); |
+ return std::string(); |
+ } |
+ const ListValue* args = static_cast<const ListValue*>(content); |
+ if (args->GetSize() != 1) { |
+ NOTREACHED(); |
+ return std::string(); |
+ } |
+ |
+ std::string result; |
+ Value* value = NULL; |
+ if (!args->Get(0, &value) || !value->GetAsString(&result)) { |
+ NOTREACHED(); |
+ return std::string(); |
+ } |
+ |
+ return result; |
+} |
+ |
+void FlowHandler::RegisterMessages() { |
+ dom_ui_->RegisterMessageCallback("SubmitAuth", |
+ NewCallback(this, &FlowHandler::HandleSubmitAuth)); |
+ dom_ui_->RegisterMessageCallback("SubmitMergeAndSync", |
+ NewCallback(this, &FlowHandler::HandleSubmitMergeAndSync)); |
+} |
+ |
+static bool GetUsernameAndPassword(const std::string& json, |
+ std::string* username, std::string* password) { |
+ scoped_ptr<Value> parsed_value(JSONReader::Read(json, false)); |
+ if (!parsed_value.get() || !parsed_value->IsType(Value::TYPE_DICTIONARY)) |
+ return false; |
+ |
+ DictionaryValue* result = static_cast<DictionaryValue*>(parsed_value.get()); |
+ if (!result->GetString(L"user", username) || |
+ !result->GetString(L"pass", password)) { |
+ return false; |
+ } |
+ return true; |
+} |
+ |
+void FlowHandler::HandleSubmitAuth(const Value* value) { |
+ std::string json(GetJsonResponse(value)); |
+ std::string username, password; |
+ if (json.empty()) |
+ return; |
+ |
+ if (!GetUsernameAndPassword(json, &username, &password)) { |
+ // The page sent us something that we didn't understand. |
+ // This probably indicates a programming error. |
+ NOTREACHED(); |
+ return; |
+ } |
+ |
+ if (flow_) |
+ flow_->OnUserSubmittedAuth(username, password); |
+} |
+ |
+void FlowHandler::HandleSubmitMergeAndSync(const Value* value) { |
+ if (flow_) |
+ flow_->OnUserAcceptedMergeAndSync(); |
+} |
+ |
+// Called by SyncSetupFlow::Advance. |
+void FlowHandler::ShowGaiaLogin(const DictionaryValue& args) { |
+ std::string json; |
+ JSONWriter::Write(&args, false, &json); |
+ std::wstring javascript = std::wstring(L"showGaiaLogin") + |
+ L"(" + UTF8ToWide(json) + L");"; |
+ ExecuteJavascriptInIFrame(kLoginIFrameXPath, javascript); |
+} |
+ |
+void FlowHandler::ShowGaiaSuccessAndClose() { |
+ ExecuteJavascriptInIFrame(kLoginIFrameXPath, L"showGaiaSuccessAndClose();"); |
+} |
+ |
+void FlowHandler::ShowGaiaSuccessAndSettingUp() { |
+ ExecuteJavascriptInIFrame(kLoginIFrameXPath, |
+ L"showGaiaSuccessAndSettingUp();"); |
+} |
+ |
+void FlowHandler::ShowMergeAndSync() { |
+ if (dom_ui_) // NULL during testing. |
+ dom_ui_->CallJavascriptFunction(L"showMergeAndSync"); |
+} |
+ |
+void FlowHandler::ShowMergeAndSyncDone() { |
+ ExecuteJavascriptInIFrame(kMergeIFrameXPath, L"showMergeAndSyncDone();"); |
+} |
+ |
+void FlowHandler::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); |
+ } |
+} |
+ |
+SyncSetupFlow::~SyncSetupFlow() { |
+ flow_handler_->set_flow(NULL); |
+} |
+ |
+void SyncSetupFlow::GetDialogSize(gfx::Size* size) const { |
+ size->set_width(kSyncDialogWidth); |
+ size->set_height(kSyncDialogHeight); |
+} |
+ |
+// A callback to notify the delegate that the dialog closed. |
+void SyncSetupFlow::OnDialogClosed(const std::string& json_retval) { |
+ DCHECK(json_retval.empty()); |
+ container_->set_flow(NULL); // Sever ties from the wizard. |
+ if (current_state_ == SyncSetupWizard::DONE) { |
+ PrefService* prefs = service_->profile()->GetPrefs(); |
+ prefs->SetBoolean(prefs::kSyncHasSetupCompleted, true); |
+ prefs->ScheduleSavePersistentPrefs(); |
+ } |
+ service_->OnUserCancelledDialog(); |
+ delete this; |
+} |
+ |
+// static |
+void SyncSetupFlow::GetArgsForGaiaLogin(const ProfileSyncService* service, |
+ DictionaryValue* args) { |
+ AuthErrorState error(service->GetAuthErrorState()); |
+ if (!service->last_attempted_user_email().empty()) { |
+ args->SetString(L"user", service->last_attempted_user_email()); |
+ args->SetInteger(L"error", error); |
+ } else { |
+ std::wstring user(UTF16ToWide(service->GetAuthenticatedUsername())); |
+ args->SetString(L"user", user); |
+ args->SetInteger(L"error", user.empty() ? 0 : error); |
+ } |
+} |
+ |
+void SyncSetupFlow::GetDOMMessageHandlers( |
+ std::vector<DOMMessageHandler*>* handlers) const { |
+ handlers->push_back(flow_handler_); |
+} |
+ |
+bool SyncSetupFlow::ShouldAdvance(SyncSetupWizard::State state) { |
+ switch (state) { |
+ case SyncSetupWizard::GAIA_LOGIN: |
+ return current_state_ == SyncSetupWizard::GAIA_LOGIN; |
+ case SyncSetupWizard::GAIA_SUCCESS: |
+ return current_state_ == SyncSetupWizard::GAIA_LOGIN; |
+ case SyncSetupWizard::MERGE_AND_SYNC: |
+ return current_state_ == SyncSetupWizard::GAIA_SUCCESS; |
+ case SyncSetupWizard::DONE: |
+ return current_state_ == SyncSetupWizard::MERGE_AND_SYNC || |
+ current_state_ == SyncSetupWizard::GAIA_SUCCESS; |
+ default: |
+ NOTREACHED() << "Unhandled State: " << state; |
+ return false; |
+ } |
+} |
+ |
+void SyncSetupFlow::Advance(SyncSetupWizard::State advance_state) { |
+ if (!ShouldAdvance(advance_state)) |
+ return; |
+ switch (advance_state) { |
+ case SyncSetupWizard::GAIA_LOGIN: { |
+ DictionaryValue args; |
+ SyncSetupFlow::GetArgsForGaiaLogin(service_, &args); |
+ flow_handler_->ShowGaiaLogin(args); |
+ break; |
+ } |
+ case SyncSetupWizard::GAIA_SUCCESS: |
+ if (end_state_ == SyncSetupWizard::GAIA_SUCCESS) |
+ flow_handler_->ShowGaiaSuccessAndClose(); |
+ else |
+ flow_handler_->ShowGaiaSuccessAndSettingUp(); |
+ break; |
+ case SyncSetupWizard::MERGE_AND_SYNC: |
+ flow_handler_->ShowMergeAndSync(); |
+ break; |
+ case SyncSetupWizard::DONE: |
+ if (current_state_ == SyncSetupWizard::MERGE_AND_SYNC) |
+ flow_handler_->ShowMergeAndSyncDone(); |
+ else if (current_state_ == SyncSetupWizard::GAIA_SUCCESS) |
+ flow_handler_->ShowGaiaSuccessAndClose(); |
+ break; |
+ default: |
+ NOTREACHED() << "Invalid advance state: " << advance_state; |
+ } |
+ current_state_ = advance_state; |
+} |
+ |
+ |
+// static |
+SyncSetupFlow* SyncSetupFlow::Run(ProfileSyncService* service, |
+ SyncSetupFlowContainer* container, |
+ SyncSetupWizard::State start, |
+ SyncSetupWizard::State end) { |
+ DictionaryValue args; |
+ if (start == SyncSetupWizard::GAIA_LOGIN) |
+ SyncSetupFlow::GetArgsForGaiaLogin(service, &args); |
+ std::string json_args; |
+ JSONWriter::Write(&args, false, &json_args); |
+ |
+ Browser* b = BrowserList::GetLastActive(); |
+ if (!b) |
+ return NULL; |
+ |
+ FlowHandler* handler = new FlowHandler(); |
+ SyncSetupFlow* flow = new SyncSetupFlow(start, end, json_args, |
+ container, handler, service); |
+ handler->set_flow(flow); |
+ b->BrowserShowHtmlDialog(flow, NULL); |
+ return flow; |
+} |
+ |
+#endif // CHROME_PERSONALIZATION |
Property changes on: chrome\browser\views\sync\sync_setup_flow.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |