summaryrefslogtreecommitdiffstats
path: root/chrome/browser/google/google_url_tracker.h
blob: 2f67820b6d87343300263d946bc32a69e753946b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_GOOGLE_GOOGLE_URL_TRACKER_H_
#define CHROME_BROWSER_GOOGLE_GOOGLE_URL_TRACKER_H_
#pragma once

#include <string>

#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/tab_contents/confirm_infobar_delegate.h"
#include "chrome/common/net/url_fetcher.h"
#include "content/common/notification_observer.h"
#include "content/common/notification_registrar.h"
#include "googleurl/src/gurl.h"
#include "net/base/network_change_notifier.h"

class NavigationController;
class PrefService;
class TabContents;
class TemplateURL;

// This object is responsible for checking the Google URL once per network
// change, and if necessary prompting the user to see if they want to change to
// using it.  The current and last prompted values are saved to prefs.
//
// Most consumers should only call GoogleURL(), which is guaranteed to
// synchronously return a value at all times (even during startup or in unittest
// mode).  Consumers who need to be notified when things change should listen to
// the notification service for NOTIFY_GOOGLE_URL_UPDATED, and call GoogleURL()
// again after receiving it, in order to get the updated value.
//
// To protect users' privacy and reduce server load, no updates will be
// performed (ever) unless at least one consumer registers interest by calling
// RequestServerCheck().
class GoogleURLTracker : public URLFetcher::Delegate,
                         public NotificationObserver,
                         public net::NetworkChangeNotifier::IPAddressObserver {
 public:
  // Only the main browser process loop should call this, when setting up
  // g_browser_process->google_url_tracker_.  No code other than the
  // GoogleURLTracker itself should actually use
  // g_browser_process->google_url_tracker() (which shouldn't be hard, since
  // there aren't useful public functions on this object for consumers to access
  // anyway).
  GoogleURLTracker();

  virtual ~GoogleURLTracker();

  // Returns the current Google URL.  This will return a valid URL even in
  // unittest mode.
  //
  // This is the only function most code should ever call.
  static GURL GoogleURL();

  // Requests that the tracker perform a server check to update the Google URL
  // as necessary.  This will happen at most once per network change, not
  // sooner than five seconds after startup (checks requested before that time
  // will occur then; checks requested afterwards will occur immediately, if
  // no other checks have been made during this run).
  //
  // In unittest mode, this function does nothing.
  static void RequestServerCheck();

  static void RegisterPrefs(PrefService* prefs);

  // Notifies the tracker that the user has started a Google search.
  // If prompting is necessary, we then listen for the subsequent
  // NAV_ENTRY_PENDING notification to get the appropriate NavigationController.
  // When the load commits, we'll show the infobar.
  static void GoogleURLSearchCommitted();

  static const char kDefaultGoogleHomepage[];
  static const char kSearchDomainCheckURL[];

  // Methods called from InfoBar delegate.
  void AcceptGoogleURL(const GURL& google_url);
  void CancelGoogleURL(const GURL& google_url);
  void InfoBarClosed();
  void RedoSearch();

 private:
  friend class GoogleURLTrackerTest;

  typedef InfoBarDelegate* (*InfobarCreator)(TabContents*,
                                             GoogleURLTracker*,
                                             const GURL&);

  // Registers consumer interest in getting an updated URL from the server.
  // It will be notified as NotificationType::GOOGLE_URL_UPDATED, so the
  // consumer should observe this notification before calling this.
  void SetNeedToFetch();

  // Begins the five-second startup sleep period, unless a test has cleared
  // |queue_wakeup_task_|.
  void QueueWakeupTask();

  // Called when the five second startup sleep has finished.  Runs any pending
  // fetch.
  void FinishSleep();

  // Starts the fetch of the up-to-date Google URL if we actually want to fetch
  // it and can currently do so.
  void StartFetchIfDesirable();

  // URLFetcher::Delegate
  virtual void OnURLFetchComplete(const URLFetcher *source,
                                  const GURL& url,
                                  const net::URLRequestStatus& status,
                                  int response_code,
                                  const ResponseCookies& cookies,
                                  const std::string& data);

  // NotificationObserver
  virtual void Observe(NotificationType type,
                       const NotificationSource& source,
                       const NotificationDetails& details);

  // NetworkChangeNotifier::IPAddressObserver
  virtual void OnIPAddressChanged();

  void SearchCommitted();
  void OnNavigationPending(const NotificationSource& source,
                           const GURL& pending_url);
  void OnNavigationCommittedOrTabClosed(TabContents* tab_contents,
                                        NotificationType::Type type);
  void ShowGoogleURLInfoBarIfNecessary(TabContents* tab_contents);

  NotificationRegistrar registrar_;
  InfobarCreator infobar_creator_;
  // TODO(ukai): GoogleURLTracker should track google domain (e.g. google.co.uk)
  // rather than URL (e.g. http://www.google.co.uk/), so that user could
  // configure to use https in search engine templates.
  GURL google_url_;
  GURL fetched_google_url_;
  ScopedRunnableMethodFactory<GoogleURLTracker> runnable_method_factory_;
  scoped_ptr<URLFetcher> fetcher_;
  int fetcher_id_;
  bool queue_wakeup_task_;
  bool in_startup_sleep_;  // True if we're in the five-second "no fetching"
                           // period that begins at browser start.
  bool already_fetched_;   // True if we've already fetched a URL once this run;
                           // we won't fetch again until after a restart.
  bool need_to_fetch_;     // True if a consumer actually wants us to fetch an
                           // updated URL.  If this is never set, we won't
                           // bother to fetch anything.
                           // Consumers should observe
                           // NotificationType::GOOGLE_URL_UPDATED.
  bool need_to_prompt_;    // True if the last fetched Google URL is not
                           // matched with current user's default Google URL
                           // nor the last prompted Google URL.
  NavigationController* controller_;
  InfoBarDelegate* infobar_;
  GURL search_url_;

  DISALLOW_COPY_AND_ASSIGN(GoogleURLTracker);
};


// This infobar delegate is declared here (rather than in the .cc file) so test
// code can subclass it.
class GoogleURLTrackerInfoBarDelegate : public ConfirmInfoBarDelegate {
 public:
  GoogleURLTrackerInfoBarDelegate(TabContents* tab_contents,
                                  GoogleURLTracker* google_url_tracker,
                                  const GURL& new_google_url);

  // ConfirmInfoBarDelegate:
  virtual bool Accept();
  virtual bool Cancel();
  virtual void InfoBarClosed();

 protected:
  virtual ~GoogleURLTrackerInfoBarDelegate();

  GoogleURLTracker* google_url_tracker_;
  const GURL new_google_url_;

 private:
  // ConfirmInfoBarDelegate:
  virtual string16 GetMessageText() const;
  virtual string16 GetButtonLabel(InfoBarButton button) const;

  DISALLOW_COPY_AND_ASSIGN(GoogleURLTrackerInfoBarDelegate);
};

#endif  // CHROME_BROWSER_GOOGLE_GOOGLE_URL_TRACKER_H_