1// Copyright (c) 2012 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#include "chrome/browser/ui/webui/ntp/new_tab_page_sync_handler.h" 6 7#include <vector> 8 9#include "base/bind.h" 10#include "base/bind_helpers.h" 11#include "base/prefs/pref_service.h" 12#include "base/strings/string_split.h" 13#include "base/strings/string_util.h" 14#include "base/strings/utf_string_conversions.h" 15#include "base/values.h" 16#include "chrome/browser/profiles/profile.h" 17#include "chrome/browser/signin/signin_manager_factory.h" 18#include "chrome/browser/signin/signin_promo.h" 19#include "chrome/browser/sync/profile_sync_service.h" 20#include "chrome/browser/sync/profile_sync_service_factory.h" 21#include "chrome/browser/ui/browser.h" 22#include "chrome/browser/ui/browser_finder.h" 23#include "chrome/browser/ui/chrome_pages.h" 24#include "chrome/browser/ui/webui/signin/login_ui_service.h" 25#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" 26#include "chrome/common/pref_names.h" 27#include "chrome/grit/generated_resources.h" 28#include "components/signin/core/browser/signin_manager.h" 29#include "content/public/browser/render_view_host.h" 30#include "content/public/browser/web_ui.h" 31#include "net/cookies/cookie_monster.h" 32#include "net/url_request/url_request_context.h" 33#include "ui/base/l10n/l10n_util.h" 34 35NewTabPageSyncHandler::NewTabPageSyncHandler() : sync_service_(NULL), 36 waiting_for_initial_page_load_(true) { 37} 38 39NewTabPageSyncHandler::~NewTabPageSyncHandler() { 40 if (sync_service_) 41 sync_service_->RemoveObserver(this); 42} 43 44// static 45NewTabPageSyncHandler::MessageType 46 NewTabPageSyncHandler::FromSyncStatusMessageType( 47 sync_ui_util::MessageType type) { 48 switch (type) { 49 case sync_ui_util::SYNC_ERROR: 50 return SYNC_ERROR; 51 case sync_ui_util::SYNC_PROMO: 52 return SYNC_PROMO; 53 case sync_ui_util::PRE_SYNCED: 54 case sync_ui_util::SYNCED: 55 default: 56 return HIDE; 57 } 58} 59 60void NewTabPageSyncHandler::RegisterMessages() { 61 sync_service_ = ProfileSyncServiceFactory::GetInstance()->GetForProfile( 62 Profile::FromWebUI(web_ui())); 63 if (sync_service_) 64 sync_service_->AddObserver(this); 65 profile_pref_registrar_.Init(Profile::FromWebUI(web_ui())->GetPrefs()); 66 profile_pref_registrar_.Add( 67 prefs::kSigninAllowed, 68 base::Bind(&NewTabPageSyncHandler::OnSigninAllowedPrefChange, 69 base::Unretained(this))); 70 71 web_ui()->RegisterMessageCallback("GetSyncMessage", 72 base::Bind(&NewTabPageSyncHandler::HandleGetSyncMessage, 73 base::Unretained(this))); 74 web_ui()->RegisterMessageCallback("SyncLinkClicked", 75 base::Bind(&NewTabPageSyncHandler::HandleSyncLinkClicked, 76 base::Unretained(this))); 77} 78 79void NewTabPageSyncHandler::HandleGetSyncMessage(const base::ListValue* args) { 80 waiting_for_initial_page_load_ = false; 81 BuildAndSendSyncStatus(); 82} 83 84void NewTabPageSyncHandler::HideSyncStatusSection() { 85 SendSyncMessageToPage(HIDE, std::string(), std::string()); 86} 87 88void NewTabPageSyncHandler::BuildAndSendSyncStatus() { 89 DCHECK(!waiting_for_initial_page_load_); 90 SigninManagerBase* signin = SigninManagerFactory::GetForProfile( 91 Profile::FromWebUI(web_ui())); 92 93 // Hide the sync status section if sync is managed or disabled entirely. 94 if (!sync_service_ || 95 sync_service_->IsManaged() || 96 !signin || 97 !signin->IsSigninAllowed()) { 98 HideSyncStatusSection(); 99 return; 100 } 101 102 // Don't show sync status if setup is not complete. 103 if (!sync_service_->HasSyncSetupCompleted()) { 104 return; 105 } 106 107 // Once sync has been enabled, the supported "sync statuses" for the NNTP 108 // from the user's perspective are: 109 // 110 // "Sync error", when we can't authenticate or establish a connection with 111 // the sync server (appropriate information appended to 112 // message). 113 base::string16 status_msg; 114 base::string16 link_text; 115 116 sync_ui_util::MessageType type = 117 sync_ui_util::GetStatusLabelsForNewTabPage(sync_service_, 118 *signin, 119 &status_msg, 120 &link_text); 121 SendSyncMessageToPage(FromSyncStatusMessageType(type), 122 base::UTF16ToUTF8(status_msg), 123 base::UTF16ToUTF8(link_text)); 124} 125 126void NewTabPageSyncHandler::HandleSyncLinkClicked(const base::ListValue* args) { 127 DCHECK(!waiting_for_initial_page_load_); 128 if (!sync_service_ || !sync_service_->IsSyncEnabled()) 129 return; 130 Browser* browser = 131 chrome::FindBrowserWithWebContents(web_ui()->GetWebContents()); 132 if (!browser || browser->IsAttemptingToCloseBrowser()) 133 return; 134 chrome::ShowBrowserSignin(browser, signin::SOURCE_NTP_LINK); 135 136 if (sync_service_->HasSyncSetupCompleted()) { 137 base::string16 user = base::UTF8ToUTF16(SigninManagerFactory::GetForProfile( 138 Profile::FromWebUI(web_ui()))->GetAuthenticatedUsername()); 139 base::DictionaryValue value; 140 value.SetString("syncEnabledMessage", 141 l10n_util::GetStringFUTF16(IDS_SYNC_NTP_SYNCED_TO, 142 user)); 143 web_ui()->CallJavascriptFunction("ntp.syncAlreadyEnabled", value); 144 } else { 145 ProfileSyncService::SyncEvent(ProfileSyncService::START_FROM_NTP); 146 } 147} 148 149void NewTabPageSyncHandler::OnStateChanged() { 150 // Don't do anything if the page has not yet loaded. 151 if (waiting_for_initial_page_load_) 152 return; 153 BuildAndSendSyncStatus(); 154} 155 156void NewTabPageSyncHandler::OnSigninAllowedPrefChange() { 157 // Don't do anything if the page has not yet loaded. 158 if (waiting_for_initial_page_load_) 159 return; 160 BuildAndSendSyncStatus(); 161} 162 163void NewTabPageSyncHandler::SendSyncMessageToPage( 164 MessageType type, std::string msg, 165 std::string linktext) { 166 base::DictionaryValue value; 167 std::string user; 168 std::string title; 169 std::string linkurl; 170 171 // If there is nothing to show, we should hide the sync section altogether. 172 if (type == HIDE || (msg.empty() && linktext.empty())) { 173 value.SetBoolean("syncsectionisvisible", false); 174 } else { 175 if (type == SYNC_ERROR) 176 title = l10n_util::GetStringUTF8(IDS_SYNC_NTP_SYNC_SECTION_ERROR_TITLE); 177 else if (type == SYNC_PROMO) 178 title = l10n_util::GetStringUTF8(IDS_SYNC_NTP_SYNC_SECTION_PROMO_TITLE); 179 else 180 NOTREACHED(); 181 182 value.SetBoolean("syncsectionisvisible", true); 183 value.SetString("msg", msg); 184 value.SetString("title", title); 185 if (linktext.empty()) { 186 value.SetBoolean("linkisvisible", false); 187 } else { 188 value.SetBoolean("linkisvisible", true); 189 value.SetString("linktext", linktext); 190 191 // The only time we set the URL is when the user is synced and we need to 192 // show a link to a web interface (e.g. http://docs.google.com). When we 193 // set that URL, HandleSyncLinkClicked won't be called when the user 194 // clicks on the link. 195 if (linkurl.empty()) { 196 value.SetBoolean("linkurlisset", false); 197 } else { 198 value.SetBoolean("linkurlisset", true); 199 value.SetString("linkurl", linkurl); 200 } 201 } 202 } 203 web_ui()->CallJavascriptFunction("ntp.syncMessageChanged", value); 204} 205