1 // Copyright (c) 2011 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 #ifndef CHROME_BROWSER_GOOGLE_GOOGLE_URL_TRACKER_H_ 6 #define CHROME_BROWSER_GOOGLE_GOOGLE_URL_TRACKER_H_ 7 #pragma once 8 9 #include <string> 10 11 #include "base/gtest_prod_util.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "chrome/browser/tab_contents/confirm_infobar_delegate.h" 14 #include "chrome/common/net/url_fetcher.h" 15 #include "content/common/notification_observer.h" 16 #include "content/common/notification_registrar.h" 17 #include "googleurl/src/gurl.h" 18 #include "net/base/network_change_notifier.h" 19 20 class NavigationController; 21 class PrefService; 22 class TabContents; 23 class TemplateURL; 24 25 // This object is responsible for checking the Google URL once per network 26 // change, and if necessary prompting the user to see if they want to change to 27 // using it. The current and last prompted values are saved to prefs. 28 // 29 // Most consumers should only call GoogleURL(), which is guaranteed to 30 // synchronously return a value at all times (even during startup or in unittest 31 // mode). Consumers who need to be notified when things change should listen to 32 // the notification service for NOTIFY_GOOGLE_URL_UPDATED, and call GoogleURL() 33 // again after receiving it, in order to get the updated value. 34 // 35 // To protect users' privacy and reduce server load, no updates will be 36 // performed (ever) unless at least one consumer registers interest by calling 37 // RequestServerCheck(). 38 class GoogleURLTracker : public URLFetcher::Delegate, 39 public NotificationObserver, 40 public net::NetworkChangeNotifier::IPAddressObserver { 41 public: 42 // Only the main browser process loop should call this, when setting up 43 // g_browser_process->google_url_tracker_. No code other than the 44 // GoogleURLTracker itself should actually use 45 // g_browser_process->google_url_tracker() (which shouldn't be hard, since 46 // there aren't useful public functions on this object for consumers to access 47 // anyway). 48 GoogleURLTracker(); 49 50 virtual ~GoogleURLTracker(); 51 52 // Returns the current Google URL. This will return a valid URL even in 53 // unittest mode. 54 // 55 // This is the only function most code should ever call. 56 static GURL GoogleURL(); 57 58 // Requests that the tracker perform a server check to update the Google URL 59 // as necessary. This will happen at most once per network change, not 60 // sooner than five seconds after startup (checks requested before that time 61 // will occur then; checks requested afterwards will occur immediately, if 62 // no other checks have been made during this run). 63 // 64 // In unittest mode, this function does nothing. 65 static void RequestServerCheck(); 66 67 static void RegisterPrefs(PrefService* prefs); 68 69 // Notifies the tracker that the user has started a Google search. 70 // If prompting is necessary, we then listen for the subsequent 71 // NAV_ENTRY_PENDING notification to get the appropriate NavigationController. 72 // When the load commits, we'll show the infobar. 73 static void GoogleURLSearchCommitted(); 74 75 static const char kDefaultGoogleHomepage[]; 76 static const char kSearchDomainCheckURL[]; 77 78 // Methods called from InfoBar delegate. 79 void AcceptGoogleURL(const GURL& google_url); 80 void CancelGoogleURL(const GURL& google_url); 81 void InfoBarClosed(); 82 void RedoSearch(); 83 84 private: 85 friend class GoogleURLTrackerTest; 86 87 typedef InfoBarDelegate* (*InfobarCreator)(TabContents*, 88 GoogleURLTracker*, 89 const GURL&); 90 91 // Registers consumer interest in getting an updated URL from the server. 92 // It will be notified as NotificationType::GOOGLE_URL_UPDATED, so the 93 // consumer should observe this notification before calling this. 94 void SetNeedToFetch(); 95 96 // Begins the five-second startup sleep period, unless a test has cleared 97 // |queue_wakeup_task_|. 98 void QueueWakeupTask(); 99 100 // Called when the five second startup sleep has finished. Runs any pending 101 // fetch. 102 void FinishSleep(); 103 104 // Starts the fetch of the up-to-date Google URL if we actually want to fetch 105 // it and can currently do so. 106 void StartFetchIfDesirable(); 107 108 // URLFetcher::Delegate 109 virtual void OnURLFetchComplete(const URLFetcher *source, 110 const GURL& url, 111 const net::URLRequestStatus& status, 112 int response_code, 113 const ResponseCookies& cookies, 114 const std::string& data); 115 116 // NotificationObserver 117 virtual void Observe(NotificationType type, 118 const NotificationSource& source, 119 const NotificationDetails& details); 120 121 // NetworkChangeNotifier::IPAddressObserver 122 virtual void OnIPAddressChanged(); 123 124 void SearchCommitted(); 125 void OnNavigationPending(const NotificationSource& source, 126 const GURL& pending_url); 127 void OnNavigationCommittedOrTabClosed(TabContents* tab_contents, 128 NotificationType::Type type); 129 void ShowGoogleURLInfoBarIfNecessary(TabContents* tab_contents); 130 131 NotificationRegistrar registrar_; 132 InfobarCreator infobar_creator_; 133 // TODO(ukai): GoogleURLTracker should track google domain (e.g. google.co.uk) 134 // rather than URL (e.g. http://www.google.co.uk/), so that user could 135 // configure to use https in search engine templates. 136 GURL google_url_; 137 GURL fetched_google_url_; 138 ScopedRunnableMethodFactory<GoogleURLTracker> runnable_method_factory_; 139 scoped_ptr<URLFetcher> fetcher_; 140 int fetcher_id_; 141 bool queue_wakeup_task_; 142 bool in_startup_sleep_; // True if we're in the five-second "no fetching" 143 // period that begins at browser start. 144 bool already_fetched_; // True if we've already fetched a URL once this run; 145 // we won't fetch again until after a restart. 146 bool need_to_fetch_; // True if a consumer actually wants us to fetch an 147 // updated URL. If this is never set, we won't 148 // bother to fetch anything. 149 // Consumers should observe 150 // NotificationType::GOOGLE_URL_UPDATED. 151 bool need_to_prompt_; // True if the last fetched Google URL is not 152 // matched with current user's default Google URL 153 // nor the last prompted Google URL. 154 NavigationController* controller_; 155 InfoBarDelegate* infobar_; 156 GURL search_url_; 157 158 DISALLOW_COPY_AND_ASSIGN(GoogleURLTracker); 159 }; 160 161 162 // This infobar delegate is declared here (rather than in the .cc file) so test 163 // code can subclass it. 164 class GoogleURLTrackerInfoBarDelegate : public ConfirmInfoBarDelegate { 165 public: 166 GoogleURLTrackerInfoBarDelegate(TabContents* tab_contents, 167 GoogleURLTracker* google_url_tracker, 168 const GURL& new_google_url); 169 170 // ConfirmInfoBarDelegate: 171 virtual bool Accept(); 172 virtual bool Cancel(); 173 virtual void InfoBarClosed(); 174 175 protected: 176 virtual ~GoogleURLTrackerInfoBarDelegate(); 177 178 GoogleURLTracker* google_url_tracker_; 179 const GURL new_google_url_; 180 181 private: 182 // ConfirmInfoBarDelegate: 183 virtual string16 GetMessageText() const; 184 virtual string16 GetButtonLabel(InfoBarButton button) const; 185 186 DISALLOW_COPY_AND_ASSIGN(GoogleURLTrackerInfoBarDelegate); 187 }; 188 189 #endif // CHROME_BROWSER_GOOGLE_GOOGLE_URL_TRACKER_H_ 190