OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2006-2008 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 #ifdef CHROME_PERSONALIZATION |
| 6 |
| 7 #include "chrome/browser/dom_ui/new_tab_page_sync_handler.h" |
| 8 |
| 9 #include "base/json_writer.h" |
| 10 #include "base/string_util.h" |
| 11 #include "base/values.h" |
| 12 #include "chrome/browser/profile.h" |
| 13 #include "chrome/browser/renderer_host/render_view_host.h" |
| 14 #include "chrome/browser/sync/personalization.h" |
| 15 #include "chrome/browser/sync/personalization_strings.h" |
| 16 #include "chrome/browser/tab_contents/tab_contents.h" |
| 17 #include "chrome/common/pref_names.h" |
| 18 #include "chrome/common/pref_service.h" |
| 19 #include "grit/browser_resources.h" |
| 20 #include "net/base/cookie_monster.h" |
| 21 #include "net/url_request/url_request_context.h" |
| 22 |
| 23 // XPath expression for finding our p13n iframe. |
| 24 static const wchar_t* kP13nIframeXpath = L"//iframe[@id='p13n']"; |
| 25 |
| 26 namespace Personalization { |
| 27 |
| 28 // A simple pair of fields that identify a set of Google cookies, used to |
| 29 // filter from a larger set. |
| 30 struct GoogleCookieFilter { |
| 31 // The generalized, fully qualified URL of pages where |
| 32 // cookies with id |cookie_id| are obtained / accessed. |
| 33 const char* url; |
| 34 // The id of the cookie this filter is selecting, |
| 35 // with name/value delimiter (i.e '='). |
| 36 const char* cookie_id; |
| 37 }; |
| 38 |
| 39 // Filters to select Google GAIA cookies. |
| 40 static const GoogleCookieFilter kGAIACookieFilters[] = { |
| 41 { "http://.google.com/", "SID=" }, // Gmail. |
| 42 // Add filters here for other interesting cookies that should result in |
| 43 // showing the promotions (e.g ASIDAS for dasher accounts). |
| 44 }; |
| 45 |
| 46 bool IsGoogleGAIACookieInstalled() { |
| 47 for (size_t i = 0; i < arraysize(kGAIACookieFilters); ++i) { |
| 48 URLRequestContext* context = Profile::GetDefaultRequestContext(); |
| 49 net::CookieStore* store = context->cookie_store(); |
| 50 GURL url(kGAIACookieFilters[i].url); |
| 51 net::CookieOptions options; |
| 52 options.set_include_httponly(); // The SID cookie might be httponly. |
| 53 std::string cookies = store->GetCookiesWithOptions(url, options); |
| 54 std::vector<std::string> cookie_list; |
| 55 SplitString(cookies, ';', &cookie_list); |
| 56 for (std::vector<std::string>::iterator current = cookie_list.begin(); |
| 57 current != cookie_list.end(); |
| 58 ++current) { |
| 59 size_t position = |
| 60 current->find(kGAIACookieFilters[i].cookie_id); |
| 61 if (0 == position) |
| 62 return true; |
| 63 } |
| 64 } |
| 65 return false; |
| 66 } |
| 67 |
| 68 } // namespace Personalization |
| 69 |
| 70 NewTabPageSyncHandler::NewTabPageSyncHandler() : sync_service_(NULL), |
| 71 waiting_for_initial_page_load_(true) { |
| 72 } |
| 73 |
| 74 NewTabPageSyncHandler::~NewTabPageSyncHandler() { |
| 75 sync_service_->RemoveObserver(this); |
| 76 } |
| 77 |
| 78 DOMMessageHandler* NewTabPageSyncHandler::Attach(DOMUI* dom_ui) { |
| 79 Profile* p = dom_ui->GetProfile(); |
| 80 sync_service_ = p->GetProfilePersonalization()->sync_service(); |
| 81 DCHECK(sync_service_); |
| 82 sync_service_->AddObserver(this); |
| 83 return DOMMessageHandler::Attach(dom_ui); |
| 84 } |
| 85 |
| 86 void NewTabPageSyncHandler::RegisterMessages() { |
| 87 dom_ui_->RegisterMessageCallback("GetSyncMessage", |
| 88 NewCallback(this, &NewTabPageSyncHandler::HandleGetSyncMessage)); |
| 89 dom_ui_->RegisterMessageCallback("SyncLinkClicked", |
| 90 NewCallback(this, &NewTabPageSyncHandler::HandleSyncLinkClicked)); |
| 91 dom_ui_->RegisterMessageCallback("ResizeP13N", |
| 92 NewCallback(this, &NewTabPageSyncHandler::HandleResizeP13N)); |
| 93 } |
| 94 |
| 95 void NewTabPageSyncHandler::HandleResizeP13N(const Value* value) { |
| 96 // We just want to call back in to the new tab page on behalf of our |
| 97 // same-origin-policy crippled iframe, to tell it to resize the container. |
| 98 dom_ui_->CallJavascriptFunction(L"resizeP13N", *value); |
| 99 } |
| 100 |
| 101 void NewTabPageSyncHandler::BuildAndSendSyncStatus() { |
| 102 DCHECK(!waiting_for_initial_page_load_); |
| 103 |
| 104 if (!sync_service_->IsSyncEnabledByUser() && |
| 105 !sync_service_->SetupInProgress()) { |
| 106 // Clear the page status, without showing the promotion or sync ui. |
| 107 // TODO(timsteele): This is fine, but if the page is refreshed or another |
| 108 // NTP is opened, we could end up showing the promo again. Not sure this is |
| 109 // desired if the user already signed up once and disabled. |
| 110 FundamentalValue value(0); |
| 111 dom_ui_->CallJavascriptFunction(L"resizeP13N", value); |
| 112 return; |
| 113 } |
| 114 |
| 115 // There are currently three supported "sync statuses" for the NTP, from |
| 116 // the users perspective: |
| 117 // "Synced to foo@gmail.com", when we are successfully authenticated and |
| 118 // connected to a sync server. |
| 119 // "Sync error", when we can't authenticate or establish a connection with |
| 120 // the sync server (appropriate information appended to |
| 121 // message). |
| 122 // "Authenticating", when credentials are in flight. |
| 123 SyncStatusUIHelper::MessageType type(SyncStatusUIHelper::PRE_SYNCED); |
| 124 std::wstring status_msg; |
| 125 std::wstring link_text; |
| 126 type = SyncStatusUIHelper::GetLabels(sync_service_, &status_msg, &link_text); |
| 127 SendSyncMessageToPage(type, WideToUTF8(status_msg), WideToUTF8(link_text)); |
| 128 } |
| 129 |
| 130 void NewTabPageSyncHandler::HandleGetSyncMessage(const Value* value) { |
| 131 waiting_for_initial_page_load_ = false; |
| 132 |
| 133 if (!sync_service_->IsSyncEnabledByUser() && |
| 134 !sync_service_->SetupInProgress()) { |
| 135 if (Personalization::IsGoogleGAIACookieInstalled()) { |
| 136 // Sync has not been enabled, and the user has logged in to GAIA. |
| 137 SendSyncMessageToPage(SyncStatusUIHelper::PRE_SYNCED, kSyncPromotionMsg, |
| 138 kStartNowLinkText); |
| 139 } |
| 140 return; |
| 141 } |
| 142 |
| 143 BuildAndSendSyncStatus(); |
| 144 } |
| 145 |
| 146 void NewTabPageSyncHandler::HandleSyncLinkClicked(const Value* value) { |
| 147 DCHECK(!waiting_for_initial_page_load_); |
| 148 if (sync_service_->IsSyncEnabledByUser()) { |
| 149 // User clicked 'Login again' link to re-authenticate. |
| 150 sync_service_->ShowLoginDialog(); |
| 151 } else { |
| 152 // User clicked "Start now" link to begin syncing. |
| 153 sync_service_->EnableForUser(); |
| 154 } |
| 155 } |
| 156 |
| 157 void NewTabPageSyncHandler::OnStateChanged() { |
| 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 SyncStatusUIHelper::MessageType type, std::string msg, |
| 166 const std::string& linktext) { |
| 167 DictionaryValue value; |
| 168 std::string title, msgtype; |
| 169 switch (type) { |
| 170 case SyncStatusUIHelper::PRE_SYNCED: |
| 171 title = kSyncSectionTitle; |
| 172 msgtype = "presynced"; |
| 173 break; |
| 174 case SyncStatusUIHelper::SYNCED: |
| 175 msgtype = "synced"; |
| 176 msg = msg.substr(0, msg.find(WideToUTF8(kLastSyncedLabel))); |
| 177 break; |
| 178 case SyncStatusUIHelper::SYNC_ERROR: |
| 179 title = kSyncErrorSectionTitle; |
| 180 msgtype = "error"; |
| 181 break; |
| 182 } |
| 183 |
| 184 value.SetString(L"title", title); |
| 185 value.SetString(L"msg", msg); |
| 186 value.SetString(L"msgtype", msgtype); |
| 187 if (!linktext.empty()) |
| 188 value.SetString(L"linktext", linktext); |
| 189 else |
| 190 value.SetBoolean(L"linktext", false); |
| 191 |
| 192 std::string json; |
| 193 JSONWriter::Write(&value, false, &json); |
| 194 std::wstring javascript = std::wstring(L"renderSyncMessage") + |
| 195 L"(" + UTF8ToWide(json) + L");"; |
| 196 RenderViewHost* rvh = dom_ui_->tab_contents()->render_view_host(); |
| 197 rvh->ExecuteJavascriptInWebFrame(kP13nIframeXpath, javascript); |
| 198 } |
| 199 |
| 200 #endif // CHROME_PERSONALIZATION |
OLD | NEW |