Home | History | Annotate | Download | only in ntp
      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 
     35 NewTabPageSyncHandler::NewTabPageSyncHandler() : sync_service_(NULL),
     36   waiting_for_initial_page_load_(true) {
     37 }
     38 
     39 NewTabPageSyncHandler::~NewTabPageSyncHandler() {
     40   if (sync_service_)
     41     sync_service_->RemoveObserver(this);
     42 }
     43 
     44 // static
     45 NewTabPageSyncHandler::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 
     60 void 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 
     79 void NewTabPageSyncHandler::HandleGetSyncMessage(const base::ListValue* args) {
     80   waiting_for_initial_page_load_ = false;
     81   BuildAndSendSyncStatus();
     82 }
     83 
     84 void NewTabPageSyncHandler::HideSyncStatusSection() {
     85   SendSyncMessageToPage(HIDE, std::string(), std::string());
     86 }
     87 
     88 void 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 
    126 void 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 
    149 void 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 
    156 void 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 
    163 void 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