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