OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 // | 4 // |
5 // This code glues the RLZ library DLL with Chrome. It allows Chrome to work | 5 // This code glues the RLZ library DLL with Chrome. It allows Chrome to work |
6 // with or without the DLL being present. If the DLL is not present the | 6 // with or without the DLL being present. If the DLL is not present the |
7 // functions do nothing and just return false. | 7 // functions do nothing and just return false. |
8 | 8 |
9 #include "chrome/browser/rlz/rlz.h" | 9 #include "chrome/browser/rlz/rlz.h" |
10 | 10 |
11 #include <process.h> | 11 #include <process.h> |
12 #include <windows.h> | 12 #include <windows.h> |
13 | 13 |
14 #include <algorithm> | 14 #include <algorithm> |
15 | 15 |
16 #include "base/file_path.h" | 16 #include "base/file_path.h" |
17 #include "base/message_loop.h" | 17 #include "base/message_loop.h" |
18 #include "base/path_service.h" | 18 #include "base/path_service.h" |
19 #include "base/string_util.h" | 19 #include "base/string_util.h" |
20 #include "base/synchronization/lock.h" | 20 #include "base/synchronization/lock.h" |
21 #include "base/task.h" | 21 #include "base/task.h" |
22 #include "base/threading/thread.h" | 22 #include "base/threading/thread.h" |
23 #include "base/threading/thread_restrictions.h" | 23 #include "base/threading/thread_restrictions.h" |
24 #include "base/utf_string_conversions.h" | 24 #include "base/utf_string_conversions.h" |
25 #include "chrome/browser/browser_process.h" | 25 #include "chrome/browser/browser_process.h" |
26 #include "chrome/browser/profiles/profile.h" | |
27 #include "chrome/browser/profiles/profile_manager.h" | |
28 #include "chrome/browser/search_engines/template_url.h" | 26 #include "chrome/browser/search_engines/template_url.h" |
29 #include "chrome/browser/search_engines/template_url_service.h" | 27 #include "chrome/browser/search_engines/template_url_service.h" |
30 #include "chrome/browser/search_engines/template_url_service_factory.h" | 28 #include "chrome/browser/search_engines/template_url_service_factory.h" |
31 #include "chrome/common/chrome_paths.h" | 29 #include "chrome/common/chrome_paths.h" |
32 #include "chrome/common/env_vars.h" | 30 #include "chrome/common/env_vars.h" |
33 #include "chrome/installer/util/google_update_settings.h" | 31 #include "chrome/installer/util/google_update_settings.h" |
34 #include "content/browser/browser_thread.h" | 32 #include "content/browser/browser_thread.h" |
35 #include "content/common/notification_registrar.h" | 33 #include "content/common/notification_registrar.h" |
36 #include "content/common/notification_service.h" | 34 #include "content/common/notification_service.h" |
37 | 35 |
(...skipping 23 matching lines...) Expand all Loading... |
61 | 59 |
62 return rlz_lib::SendFinancialPing(rlz_lib::CHROME, points, "chrome", | 60 return rlz_lib::SendFinancialPing(rlz_lib::CHROME, points, "chrome", |
63 brand_ascii.c_str(), referral_ascii.c_str(), | 61 brand_ascii.c_str(), referral_ascii.c_str(), |
64 lang_ascii.c_str(), exclude_id, NULL, true); | 62 lang_ascii.c_str(), exclude_id, NULL, true); |
65 } | 63 } |
66 | 64 |
67 // This class leverages the AutocompleteEditModel notification to know when | 65 // This class leverages the AutocompleteEditModel notification to know when |
68 // the user first interacted with the omnibox and set a global accordingly. | 66 // the user first interacted with the omnibox and set a global accordingly. |
69 class OmniBoxUsageObserver : public NotificationObserver { | 67 class OmniBoxUsageObserver : public NotificationObserver { |
70 public: | 68 public: |
71 OmniBoxUsageObserver(bool first_run, bool send_ping_immediately) | 69 OmniBoxUsageObserver(bool first_run, bool send_ping_immediately, |
| 70 bool google_default_search) |
72 : first_run_(first_run), | 71 : first_run_(first_run), |
73 send_ping_immediately_(send_ping_immediately) { | 72 send_ping_immediately_(send_ping_immediately), |
| 73 google_default_search_(google_default_search) { |
74 registrar_.Add(this, NotificationType::OMNIBOX_OPENED_URL, | 74 registrar_.Add(this, NotificationType::OMNIBOX_OPENED_URL, |
75 NotificationService::AllSources()); | 75 NotificationService::AllSources()); |
76 // If instant is enabled we'll start searching as soon as the user starts | 76 // If instant is enabled we'll start searching as soon as the user starts |
77 // typing in the omnibox (which triggers INSTANT_CONTROLLER_UPDATED). | 77 // typing in the omnibox (which triggers INSTANT_CONTROLLER_UPDATED). |
78 registrar_.Add(this, NotificationType::INSTANT_CONTROLLER_UPDATED, | 78 registrar_.Add(this, NotificationType::INSTANT_CONTROLLER_UPDATED, |
79 NotificationService::AllSources()); | 79 NotificationService::AllSources()); |
80 omnibox_used_ = false; | 80 omnibox_used_ = false; |
81 DCHECK(!instance_); | 81 DCHECK(!instance_); |
82 instance_ = this; | 82 instance_ = this; |
83 } | 83 } |
(...skipping 21 matching lines...) Expand all Loading... |
105 | 105 |
106 // There should only be one instance created at a time, and instance_ points | 106 // There should only be one instance created at a time, and instance_ points |
107 // to that instance. | 107 // to that instance. |
108 // NOTE: this is only non-null for the amount of time it is needed. Once the | 108 // NOTE: this is only non-null for the amount of time it is needed. Once the |
109 // instance_ is no longer needed (or Chrome is exiting), this is null. | 109 // instance_ is no longer needed (or Chrome is exiting), this is null. |
110 static OmniBoxUsageObserver* instance_; | 110 static OmniBoxUsageObserver* instance_; |
111 | 111 |
112 NotificationRegistrar registrar_; | 112 NotificationRegistrar registrar_; |
113 bool first_run_; | 113 bool first_run_; |
114 bool send_ping_immediately_; | 114 bool send_ping_immediately_; |
| 115 bool google_default_search_; |
115 }; | 116 }; |
116 | 117 |
117 bool OmniBoxUsageObserver::omnibox_used_ = false; | 118 bool OmniBoxUsageObserver::omnibox_used_ = false; |
118 OmniBoxUsageObserver* OmniBoxUsageObserver::instance_ = NULL; | 119 OmniBoxUsageObserver* OmniBoxUsageObserver::instance_ = NULL; |
119 | 120 |
120 // This task is run in the file thread, so to not block it for a long time | 121 // This task is run in the file thread, so to not block it for a long time |
121 // we use a throwaway thread to do the blocking url request. | 122 // we use a throwaway thread to do the blocking url request. |
122 class DailyPingTask : public Task { | 123 class DailyPingTask : public Task { |
123 public: | 124 public: |
124 virtual ~DailyPingTask() { | 125 virtual ~DailyPingTask() { |
(...skipping 28 matching lines...) Expand all Loading... |
153 // Organic brands all start with GG, such as GGCM. | 154 // Organic brands all start with GG, such as GGCM. |
154 static bool is_organic(const std::wstring& brand) { | 155 static bool is_organic(const std::wstring& brand) { |
155 return (brand.size() < 2) ? false : (brand.substr(0, 2) == L"GG"); | 156 return (brand.size() < 2) ? false : (brand.substr(0, 2) == L"GG"); |
156 } | 157 } |
157 }; | 158 }; |
158 | 159 |
159 // Performs late RLZ initialization and RLZ event recording for chrome. | 160 // Performs late RLZ initialization and RLZ event recording for chrome. |
160 // This task needs to run on the UI thread. | 161 // This task needs to run on the UI thread. |
161 class DelayedInitTask : public Task { | 162 class DelayedInitTask : public Task { |
162 public: | 163 public: |
163 explicit DelayedInitTask(bool first_run) | 164 explicit DelayedInitTask(bool first_run, bool google_default_search) |
164 : first_run_(first_run) { | 165 : first_run_(first_run), |
| 166 google_default_search_(google_default_search) { |
165 } | 167 } |
166 virtual ~DelayedInitTask() { | 168 virtual ~DelayedInitTask() { |
167 } | 169 } |
168 virtual void Run() { | 170 virtual void Run() { |
169 // For non-interactive tests we don't do the rest of the initialization | 171 // For non-interactive tests we don't do the rest of the initialization |
170 // because sometimes the very act of loading the dll causes QEMU to crash. | 172 // because sometimes the very act of loading the dll causes QEMU to crash. |
171 if (::GetEnvironmentVariableW(ASCIIToWide(env_vars::kHeadless).c_str(), | 173 if (::GetEnvironmentVariableW(ASCIIToWide(env_vars::kHeadless).c_str(), |
172 NULL, 0)) { | 174 NULL, 0)) { |
173 return; | 175 return; |
174 } | 176 } |
(...skipping 13 matching lines...) Expand all Loading... |
188 already_ran_ = true; | 190 already_ran_ = true; |
189 | 191 |
190 // Record the installation of chrome. | 192 // Record the installation of chrome. |
191 RLZTracker::RecordProductEvent(rlz_lib::CHROME, | 193 RLZTracker::RecordProductEvent(rlz_lib::CHROME, |
192 rlz_lib::CHROME_OMNIBOX, | 194 rlz_lib::CHROME_OMNIBOX, |
193 rlz_lib::INSTALL); | 195 rlz_lib::INSTALL); |
194 RLZTracker::RecordProductEvent(rlz_lib::CHROME, | 196 RLZTracker::RecordProductEvent(rlz_lib::CHROME, |
195 rlz_lib::CHROME_HOME_PAGE, | 197 rlz_lib::CHROME_HOME_PAGE, |
196 rlz_lib::INSTALL); | 198 rlz_lib::INSTALL); |
197 // Record if google is the initial search provider. | 199 // Record if google is the initial search provider. |
198 if (IsGoogleDefaultSearch()) { | 200 if (google_default_search_) { |
199 RLZTracker::RecordProductEvent(rlz_lib::CHROME, | 201 RLZTracker::RecordProductEvent(rlz_lib::CHROME, |
200 rlz_lib::CHROME_OMNIBOX, | 202 rlz_lib::CHROME_OMNIBOX, |
201 rlz_lib::SET_TO_GOOGLE); | 203 rlz_lib::SET_TO_GOOGLE); |
202 } | 204 } |
203 } | 205 } |
204 // Record first user interaction with the omnibox. We call this all the | 206 // Record first user interaction with the omnibox. We call this all the |
205 // time but the rlz lib should ingore all but the first one. | 207 // time but the rlz lib should ingore all but the first one. |
206 if (OmniBoxUsageObserver::used()) { | 208 if (OmniBoxUsageObserver::used()) { |
207 RLZTracker::RecordProductEvent(rlz_lib::CHROME, | 209 RLZTracker::RecordProductEvent(rlz_lib::CHROME, |
208 rlz_lib::CHROME_OMNIBOX, | 210 rlz_lib::CHROME_OMNIBOX, |
209 rlz_lib::FIRST_SEARCH); | 211 rlz_lib::FIRST_SEARCH); |
210 } | 212 } |
211 // Schedule the daily RLZ ping. | 213 // Schedule the daily RLZ ping. |
212 MessageLoop::current()->PostTask(FROM_HERE, new DailyPingTask()); | 214 MessageLoop::current()->PostTask(FROM_HERE, new DailyPingTask()); |
213 } | 215 } |
214 | 216 |
215 private: | 217 private: |
216 bool IsGoogleDefaultSearch() { | |
217 if (!g_browser_process) | |
218 return false; | |
219 FilePath user_data_dir; | |
220 if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) | |
221 return false; | |
222 ProfileManager* profile_manager = g_browser_process->profile_manager(); | |
223 Profile* profile = profile_manager->GetDefaultProfile(user_data_dir); | |
224 if (!profile) | |
225 return false; | |
226 const TemplateURL* url_template = TemplateURLServiceFactory::GetForProfile( | |
227 profile)->GetDefaultSearchProvider(); | |
228 if (!url_template) | |
229 return false; | |
230 const TemplateURLRef* urlref = url_template->url(); | |
231 if (!urlref) | |
232 return false; | |
233 return urlref->HasGoogleBaseURLs(); | |
234 } | |
235 | |
236 // Flag that remembers if the delayed task already ran or not. This is | 218 // Flag that remembers if the delayed task already ran or not. This is |
237 // needed only in the first_run case, since we don't want to record the | 219 // needed only in the first_run case, since we don't want to record the |
238 // set-to-google event more than once. We need to worry about this event | 220 // set-to-google event more than once. We need to worry about this event |
239 // (and not the others) because it is not a stateful RLZ event. | 221 // (and not the others) because it is not a stateful RLZ event. |
240 static bool already_ran_; | 222 static bool already_ran_; |
241 | 223 |
242 bool first_run_; | 224 bool first_run_; |
243 DISALLOW_IMPLICIT_CONSTRUCTORS(DelayedInitTask); | 225 |
| 226 // True if Google is the default search engine for the first profile starting |
| 227 // in a browser during first run. |
| 228 bool google_default_search_; |
| 229 |
244 }; | 230 }; |
245 | 231 |
246 bool DelayedInitTask::already_ran_ = false; | 232 bool DelayedInitTask::already_ran_ = false; |
247 | 233 |
248 void OmniBoxUsageObserver::Observe(NotificationType type, | 234 void OmniBoxUsageObserver::Observe(NotificationType type, |
249 const NotificationSource& source, | 235 const NotificationSource& source, |
250 const NotificationDetails& details) { | 236 const NotificationDetails& details) { |
251 // Needs to be evaluated. See http://crbug.com/62328. | 237 // Needs to be evaluated. See http://crbug.com/62328. |
252 base::ThreadRestrictions::ScopedAllowIO allow_io; | 238 base::ThreadRestrictions::ScopedAllowIO allow_io; |
253 | 239 |
254 // Try to record event now, else set the flag to try later when we | 240 // Try to record event now, else set the flag to try later when we |
255 // attempt the ping. | 241 // attempt the ping. |
256 if (!RLZTracker::RecordProductEvent(rlz_lib::CHROME, | 242 if (!RLZTracker::RecordProductEvent(rlz_lib::CHROME, |
257 rlz_lib::CHROME_OMNIBOX, | 243 rlz_lib::CHROME_OMNIBOX, |
258 rlz_lib::FIRST_SEARCH)) | 244 rlz_lib::FIRST_SEARCH)) |
259 omnibox_used_ = true; | 245 omnibox_used_ = true; |
260 else if (send_ping_immediately_) { | 246 else if (send_ping_immediately_) { |
261 BrowserThread::PostTask( | 247 BrowserThread::PostTask( |
262 BrowserThread::FILE, FROM_HERE, new DelayedInitTask(first_run_)); | 248 BrowserThread::FILE, FROM_HERE, new DelayedInitTask(first_run_, |
| 249 google_default_search_)); |
263 } | 250 } |
264 | 251 |
265 delete this; | 252 delete this; |
266 } | 253 } |
267 | 254 |
268 } // namespace | 255 } // namespace |
269 | 256 |
270 bool RLZTracker::InitRlzDelayed(bool first_run, int delay) { | 257 bool RLZTracker::InitRlzDelayed(bool first_run, int delay, |
| 258 bool google_default_search) { |
271 // A negative delay means that a financial ping should be sent immediately | 259 // A negative delay means that a financial ping should be sent immediately |
272 // after a first search is recorded, without waiting for the next restart | 260 // after a first search is recorded, without waiting for the next restart |
273 // of chrome. However, we only want this behaviour on first run. | 261 // of chrome. However, we only want this behaviour on first run. |
274 bool send_ping_immediately = false; | 262 bool send_ping_immediately = false; |
275 if (delay < 0) { | 263 if (delay < 0) { |
276 send_ping_immediately = true; | 264 send_ping_immediately = true; |
277 delay = -delay; | 265 delay = -delay; |
278 } | 266 } |
279 | 267 |
280 // Maximum and minimum delay we would allow to be set through master | 268 // Maximum and minimum delay we would allow to be set through master |
281 // preferences. Somewhat arbitrary, may need to be adjusted in future. | 269 // preferences. Somewhat arbitrary, may need to be adjusted in future. |
282 const int kMaxDelay = 200 * 1000; | 270 const int kMaxDelay = 200 * 1000; |
283 const int kMinDelay = 20 * 1000; | 271 const int kMinDelay = 20 * 1000; |
284 | 272 |
285 delay *= 1000; | 273 delay *= 1000; |
286 delay = (delay < kMinDelay) ? kMinDelay : delay; | 274 delay = (delay < kMinDelay) ? kMinDelay : delay; |
287 delay = (delay > kMaxDelay) ? kMaxDelay : delay; | 275 delay = (delay > kMaxDelay) ? kMaxDelay : delay; |
288 | 276 |
289 if (!OmniBoxUsageObserver::used()) | 277 if (!OmniBoxUsageObserver::used()) |
290 new OmniBoxUsageObserver(first_run, send_ping_immediately); | 278 new OmniBoxUsageObserver(first_run, send_ping_immediately, |
| 279 google_default_search); |
291 | 280 |
292 // Schedule the delayed init items. | 281 // Schedule the delayed init items. |
293 BrowserThread::PostDelayedTask( | 282 BrowserThread::PostDelayedTask( |
294 BrowserThread::FILE, FROM_HERE, new DelayedInitTask(first_run), delay); | 283 BrowserThread::FILE, |
| 284 FROM_HERE, |
| 285 new DelayedInitTask(first_run, google_default_search), |
| 286 delay); |
295 return true; | 287 return true; |
296 } | 288 } |
297 | 289 |
298 bool RLZTracker::RecordProductEvent(rlz_lib::Product product, | 290 bool RLZTracker::RecordProductEvent(rlz_lib::Product product, |
299 rlz_lib::AccessPoint point, | 291 rlz_lib::AccessPoint point, |
300 rlz_lib::Event event_id) { | 292 rlz_lib::Event event_id) { |
301 return rlz_lib::RecordProductEvent(product, point, event_id); | 293 return rlz_lib::RecordProductEvent(product, point, event_id); |
302 } | 294 } |
303 | 295 |
304 bool RLZTracker::ClearAllProductEvents(rlz_lib::Product product) { | 296 bool RLZTracker::ClearAllProductEvents(rlz_lib::Product product) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 cached_ommibox_rlz.assign(*rlz); | 339 cached_ommibox_rlz.assign(*rlz); |
348 access_values_state = ACCESS_VALUES_FRESH; | 340 access_values_state = ACCESS_VALUES_FRESH; |
349 } | 341 } |
350 return true; | 342 return true; |
351 } | 343 } |
352 | 344 |
353 // static | 345 // static |
354 void RLZTracker::CleanupRlz() { | 346 void RLZTracker::CleanupRlz() { |
355 OmniBoxUsageObserver::DeleteInstance(); | 347 OmniBoxUsageObserver::DeleteInstance(); |
356 } | 348 } |
OLD | NEW |