172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/webui/new_tab_page_sync_handler.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <vector> 821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/callback.h" 103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_split.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/values.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/net/chrome_url_request_context.h" 1521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host.h" 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/cookie_monster.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/url_request/url_request_context.h" 2072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Default URL for the sync web interface. 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(idana): when we figure out how we are going to allow third parties to 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// plug in their own sync engine, we should allow this value to be 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// configurable. 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kSyncDefaultViewOnlineUrl[] = "http://docs.google.com"; 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(idana): the following code was originally copied from 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// toolbar_importer.h/cc and it needs to be moved to a common Google Accounts 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// utility. 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A simple pair of fields that identify a set of Google cookies, used to 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// filter from a larger set. 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct GoogleCookieFilter { 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The generalized, fully qualified URL of pages where 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // cookies with id |cookie_id| are obtained / accessed. 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* url; 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The id of the cookie this filter is selecting, 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // with name/value delimiter (i.e '='). 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* cookie_id; 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Filters to select Google GAIA cookies. 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const GoogleCookieFilter kGAIACookieFilters[] = { 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { "http://.google.com/", "SID=" }, // Gmail. 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add filters here for other interesting cookies that should result in 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // showing the promotions (e.g ASIDAS for dasher accounts). 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool IsGoogleGAIACookieInstalled() { 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < arraysize(kGAIACookieFilters); ++i) { 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Since we are running on the UI thread don't call GetURLRequestContext(). 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::CookieStore* store = 55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Profile::GetDefaultRequestContext()->DONTUSEME_GetCookieStore(); 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL url(kGAIACookieFilters[i].url); 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::CookieOptions options; 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options.set_include_httponly(); // The SID cookie might be httponly. 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string cookies = store->GetCookiesWithOptions(url, options); 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<std::string> cookie_list; 61731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick base::SplitString(cookies, ';', &cookie_list); 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (std::vector<std::string>::iterator current = cookie_list.begin(); 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch current != cookie_list.end(); 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++current) { 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t position = 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch current->find(kGAIACookieFilters[i].cookie_id); 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (0 == position) 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNewTabPageSyncHandler::NewTabPageSyncHandler() : sync_service_(NULL), 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch waiting_for_initial_page_load_(true) { 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNewTabPageSyncHandler::~NewTabPageSyncHandler() { 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (sync_service_) 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_service_->RemoveObserver(this); 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNewTabPageSyncHandler::MessageType 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewTabPageSyncHandler::FromSyncStatusMessageType( 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_ui_util::MessageType type) { 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (type) { 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case sync_ui_util::SYNC_ERROR: 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return SYNC_ERROR; 903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen case sync_ui_util::SYNC_PROMO: 913f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return SYNC_PROMO; 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case sync_ui_util::PRE_SYNCED: 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case sync_ui_util::SYNCED: 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return HIDE; 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenWebUIMessageHandler* NewTabPageSyncHandler::Attach(WebUI* web_ui) { 10072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen sync_service_ = web_ui->GetProfile()->GetProfileSyncService(); 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(sync_service_); // This shouldn't get called by an incognito NTP. 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!sync_service_->IsManaged()); // And neither if sync is managed. 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_service_->AddObserver(this); 10472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return WebUIMessageHandler::Attach(web_ui); 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NewTabPageSyncHandler::RegisterMessages() { 10872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen web_ui_->RegisterMessageCallback("GetSyncMessage", 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewCallback(this, &NewTabPageSyncHandler::HandleGetSyncMessage)); 11072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen web_ui_->RegisterMessageCallback("SyncLinkClicked", 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewCallback(this, &NewTabPageSyncHandler::HandleSyncLinkClicked)); 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid NewTabPageSyncHandler::HandleGetSyncMessage(const ListValue* args) { 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch waiting_for_initial_page_load_ = false; 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BuildAndSendSyncStatus(); 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NewTabPageSyncHandler::HideSyncStatusSection() { 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SendSyncMessageToPage(HIDE, std::string(), std::string()); 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NewTabPageSyncHandler::BuildAndSendSyncStatus() { 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!waiting_for_initial_page_load_); 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Hide the sync status section if sync is managed or disabled entirely. 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!sync_service_ || sync_service_->IsManaged()) { 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HideSyncStatusSection(); 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Don't show sync status if setup is not complete. 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!sync_service_->HasSyncSetupCompleted()) { 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Once sync has been enabled, the supported "sync statuses" for the NNTP 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // from the user's perspective are: 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // "Sync error", when we can't authenticate or establish a connection with 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the sync server (appropriate information appended to 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // message). 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch string16 status_msg; 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch string16 link_text; 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_ui_util::MessageType type = 14672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen sync_ui_util::GetStatusLabelsForNewTabPage(sync_service_, 14772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &status_msg, 14872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &link_text); 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SendSyncMessageToPage(FromSyncStatusMessageType(type), 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UTF16ToUTF8(status_msg), UTF16ToUTF8(link_text)); 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid NewTabPageSyncHandler::HandleSyncLinkClicked(const ListValue* args) { 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!waiting_for_initial_page_load_); 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(sync_service_); 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!sync_service_->IsSyncEnabled()) 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (sync_service_->HasSyncSetupCompleted()) { 15972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen sync_service_->ShowErrorUI(NULL); 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DictionaryValue value; 1613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick value.SetString("syncEnabledMessage", 1623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::GetStringFUTF16(IDS_SYNC_NTP_SYNCED_TO, 1633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick sync_service_->GetAuthenticatedUsername())); 164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen web_ui_->CallJavascriptFunction("syncAlreadyEnabled", value); 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // User clicked the 'Start now' link to begin syncing. 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ProfileSyncService::SyncEvent(ProfileSyncService::START_FROM_NTP); 1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick sync_service_->ShowLoginDialog(NULL); 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NewTabPageSyncHandler::OnStateChanged() { 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Don't do anything if the page has not yet loaded. 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (waiting_for_initial_page_load_) 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BuildAndSendSyncStatus(); 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NewTabPageSyncHandler::SendSyncMessageToPage( 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageType type, std::string msg, 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string linktext) { 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DictionaryValue value; 1833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string user; 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string title; 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string linkurl; 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // If there is nothing to show, we should hide the sync section altogether. 1883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (type == HIDE || (msg.empty() && linktext.empty())) { 1893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick value.SetBoolean("syncsectionisvisible", false); 1903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } else { 1913f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (type == SYNC_ERROR) 1923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen title = l10n_util::GetStringUTF8(IDS_SYNC_NTP_SYNC_SECTION_ERROR_TITLE); 1933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen else if (type == SYNC_PROMO) 1943f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen title = l10n_util::GetStringUTF8(IDS_SYNC_NTP_SYNC_SECTION_PROMO_TITLE); 1953f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen else 1963f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen NOTREACHED(); 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick value.SetBoolean("syncsectionisvisible", true); 1993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick value.SetString("msg", msg); 2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick value.SetString("title", title); 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (linktext.empty()) { 2023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick value.SetBoolean("linkisvisible", false); 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 2043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick value.SetBoolean("linkisvisible", true); 2053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick value.SetString("linktext", linktext); 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The only time we set the URL is when the user is synced and we need to 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // show a link to a web interface (e.g. http://docs.google.com). When we 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // set that URL, HandleSyncLinkClicked won't be called when the user 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // clicks on the link. 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (linkurl.empty()) { 2123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick value.SetBoolean("linkurlisset", false); 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 2143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick value.SetBoolean("linkurlisset", true); 2153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick value.SetString("linkurl", linkurl); 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen web_ui_->CallJavascriptFunction("syncMessageChanged", value); 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 221