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