OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <algorithm> | 11 #include <algorithm> |
12 | 12 |
13 #include "base/bind.h" | 13 #include "base/bind.h" |
14 #include "base/command_line.h" | |
14 #include "base/debug/trace_event.h" | 15 #include "base/debug/trace_event.h" |
15 #include "base/message_loop.h" | 16 #include "base/message_loop.h" |
16 #include "base/string_util.h" | 17 #include "base/string_util.h" |
17 #include "base/utf_string_conversions.h" | 18 #include "base/utf_string_conversions.h" |
18 #include "chrome/browser/browser_process.h" | 19 #include "chrome/browser/browser_process.h" |
19 #include "chrome/browser/google/google_util.h" | 20 #include "chrome/browser/google/google_util.h" |
21 #include "chrome/browser/prefs/pref_service.h" | |
22 #include "chrome/browser/prefs/session_startup_pref.h" | |
20 #include "chrome/browser/search_engines/template_url.h" | 23 #include "chrome/browser/search_engines/template_url.h" |
21 #include "chrome/browser/search_engines/template_url_service.h" | 24 #include "chrome/browser/search_engines/template_url_service.h" |
22 #include "chrome/browser/search_engines/template_url_service_factory.h" | 25 #include "chrome/browser/search_engines/template_url_service_factory.h" |
26 #include "chrome/browser/ui/startup/startup_browser_creator.h" | |
23 #include "chrome/common/chrome_notification_types.h" | 27 #include "chrome/common/chrome_notification_types.h" |
28 #include "chrome/common/pref_names.h" | |
24 #include "content/public/browser/browser_thread.h" | 29 #include "content/public/browser/browser_thread.h" |
25 #include "content/public/browser/navigation_entry.h" | 30 #include "content/public/browser/navigation_entry.h" |
26 #include "content/public/browser/notification_service.h" | 31 #include "content/public/browser/notification_service.h" |
27 #include "net/http/http_util.h" | 32 #include "net/http/http_util.h" |
28 | 33 |
29 #if defined(OS_WIN) | 34 #if defined(OS_WIN) |
30 #include "chrome/installer/util/google_update_settings.h" | 35 #include "chrome/installer/util/google_update_settings.h" |
31 #else | 36 #else |
32 namespace GoogleUpdateSettings { | 37 namespace GoogleUpdateSettings { |
33 static bool GetLanguage(string16* language) { | 38 static bool GetLanguage(string16* language) { |
(...skipping 11 matching lines...) Expand all Loading... | |
45 return true; | 50 return true; |
46 } | 51 } |
47 } // namespace GoogleUpdateSettings | 52 } // namespace GoogleUpdateSettings |
48 #endif | 53 #endif |
49 | 54 |
50 using content::BrowserThread; | 55 using content::BrowserThread; |
51 using content::NavigationEntry; | 56 using content::NavigationEntry; |
52 | 57 |
53 namespace { | 58 namespace { |
54 | 59 |
60 bool IsGoogleUrl(const GURL& url) { | |
61 return google_util::IsGoogleHomePageUrl(url.possibly_invalid_spec()); | |
62 } | |
63 | |
55 bool IsBrandOrganic(const std::string& brand) { | 64 bool IsBrandOrganic(const std::string& brand) { |
56 return brand.empty() || google_util::IsOrganic(brand); | 65 return brand.empty() || google_util::IsOrganic(brand); |
57 } | 66 } |
58 | 67 |
59 void RecordProductEvents(bool first_run, | 68 void RecordProductEvents(bool first_run, |
60 bool is_google_default_search, | 69 bool is_google_default_search, |
61 bool is_google_homepage, | 70 bool is_google_homepage, |
62 bool is_google_in_startpages, | 71 bool is_google_in_startpages, |
63 bool already_ran, | 72 bool already_ran, |
64 bool omnibox_used, | 73 bool omnibox_used, |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
182 // static | 191 // static |
183 bool RLZTracker::InitRlzDelayed(bool first_run, | 192 bool RLZTracker::InitRlzDelayed(bool first_run, |
184 int delay, | 193 int delay, |
185 bool is_google_default_search, | 194 bool is_google_default_search, |
186 bool is_google_homepage, | 195 bool is_google_homepage, |
187 bool is_google_in_startpages) { | 196 bool is_google_in_startpages) { |
188 return GetInstance()->Init(first_run, delay, is_google_default_search, | 197 return GetInstance()->Init(first_run, delay, is_google_default_search, |
189 is_google_homepage, is_google_in_startpages); | 198 is_google_homepage, is_google_in_startpages); |
190 } | 199 } |
191 | 200 |
201 // static | |
202 bool RLZTracker::InitRlzFromProfileDelayed(Profile* profile, | |
203 bool first_run, | |
204 int delay) { | |
205 bool is_google_default_search = false; | |
206 TemplateURLService* template_url_service = | |
207 TemplateURLServiceFactory::GetForProfile(profile); | |
208 if (template_url_service) { | |
209 const TemplateURL* url_template = | |
210 template_url_service->GetDefaultSearchProvider(); | |
211 is_google_default_search = | |
212 url_template && url_template->url_ref().HasGoogleBaseURLs(); | |
213 } | |
214 | |
215 PrefService* pref_service = profile->GetPrefs(); | |
216 bool is_google_homepage = google_util::IsGoogleHomePageUrl( | |
217 pref_service->GetString(prefs::kHomePage)); | |
218 | |
219 bool is_google_in_startpages = false; | |
220 SessionStartupPref session_startup_prefs = | |
221 StartupBrowserCreator::GetSessionStartupPref( | |
222 *CommandLine::ForCurrentProcess(), profile); | |
223 if (session_startup_prefs.type == SessionStartupPref::URLS) { | |
224 is_google_in_startpages = std::count_if(session_startup_prefs.urls.begin(), | |
225 session_startup_prefs.urls.end(), | |
226 IsGoogleUrl) > 0; | |
227 } | |
228 | |
229 if (!InitRlzDelayed(first_run, delay, | |
230 is_google_default_search, is_google_homepage, | |
231 is_google_in_startpages)) { | |
232 return false; | |
233 } | |
234 | |
235 // Prime the RLZ cache for the home page access point so that its avaiable | |
236 // for the startup page if needed (i.e., when the startup page is set to | |
237 // the home page). | |
238 GetAccessPointRlz(CHROME_HOME_PAGE, NULL); | |
239 | |
240 return true; | |
241 } | |
Roger Tawa OOO till Jul 10th
2012/11/28 15:23:18
I think its great to pull this code into rlz.cc!
| |
242 | |
192 bool RLZTracker::Init(bool first_run, | 243 bool RLZTracker::Init(bool first_run, |
193 int delay, | 244 int delay, |
194 bool is_google_default_search, | 245 bool is_google_default_search, |
195 bool is_google_homepage, | 246 bool is_google_homepage, |
196 bool is_google_in_startpages) { | 247 bool is_google_in_startpages) { |
197 first_run_ = first_run; | 248 first_run_ = first_run; |
198 is_google_default_search_ = is_google_default_search; | 249 is_google_default_search_ = is_google_default_search; |
199 is_google_homepage_ = is_google_homepage; | 250 is_google_homepage_ = is_google_homepage; |
200 is_google_in_startpages_ = is_google_in_startpages; | 251 is_google_in_startpages_ = is_google_in_startpages; |
201 | 252 |
202 // A negative delay means that a financial ping should be sent immediately | 253 // A negative delay means that a financial ping should be sent immediately |
203 // after a first search is recorded, without waiting for the next restart | 254 // after a first search is recorded, without waiting for the next restart |
204 // of chrome. However, we only want this behaviour on first run. | 255 // of chrome. However, we only want this behaviour on first run. |
205 send_ping_immediately_ = false; | 256 send_ping_immediately_ = false; |
206 if (delay < 0) { | 257 if (delay < 0) { |
207 send_ping_immediately_ = true; | 258 send_ping_immediately_ = true; |
208 delay = -delay; | 259 delay = -delay; |
209 } | 260 } |
210 | 261 |
211 // Maximum and minimum delay we would allow to be set through master | 262 // Maximum and minimum delay we would allow to be set through master |
212 // preferences. Somewhat arbitrary, may need to be adjusted in future. | 263 // preferences. Somewhat arbitrary, may need to be adjusted in future. |
213 const int kMaxDelay = 200 * 1000; | 264 const int kMaxDelay = 200 * 1000; |
214 const int kMinDelay = 20 * 1000; | 265 const int kMinDelay = 20 * 1000; |
215 | 266 |
216 delay *= 1000; | 267 delay *= 1000; |
217 delay = (delay < kMinDelay) ? kMinDelay : delay; | 268 delay = (delay < kMinDelay) ? kMinDelay : delay; |
218 delay = (delay > kMaxDelay) ? kMaxDelay : delay; | 269 delay = (delay > kMaxDelay) ? kMaxDelay : delay; |
219 | 270 |
220 std::string brand; | 271 if (google_util::GetBrand(&brand_) && !IsBrandOrganic(brand_)) { |
221 if (google_util::GetBrand(&brand) && !IsBrandOrganic(brand)) { | |
222 // Register for notifications from the omnibox so that we can record when | 272 // Register for notifications from the omnibox so that we can record when |
223 // the user performs a first search. | 273 // the user performs a first search. |
224 registrar_.Add(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL, | 274 registrar_.Add(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL, |
225 content::NotificationService::AllSources()); | 275 content::NotificationService::AllSources()); |
226 // If instant is enabled we'll start searching as soon as the user starts | 276 // If instant is enabled we'll start searching as soon as the user starts |
227 // typing in the omnibox (which triggers INSTANT_CONTROLLER_UPDATED). | 277 // typing in the omnibox (which triggers INSTANT_CONTROLLER_UPDATED). |
228 registrar_.Add(this, chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED, | 278 registrar_.Add(this, chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED, |
229 content::NotificationService::AllSources()); | 279 content::NotificationService::AllSources()); |
230 | 280 |
231 // Register for notifications from navigations, to see if the user has used | 281 // Register for notifications from navigations, to see if the user has used |
232 // the home page. | 282 // the home page. |
233 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_PENDING, | 283 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_PENDING, |
234 content::NotificationService::AllSources()); | 284 content::NotificationService::AllSources()); |
235 } | 285 } |
286 google_util::GetReactivationBrand(&reactivation_brand_); | |
236 | 287 |
237 rlz_lib::SetURLRequestContext(g_browser_process->system_request_context()); | 288 rlz_lib::SetURLRequestContext(g_browser_process->system_request_context()); |
238 ScheduleDelayedInit(delay); | 289 ScheduleDelayedInit(delay); |
239 | 290 |
240 return true; | 291 return true; |
241 } | 292 } |
242 | 293 |
243 void RLZTracker::ScheduleDelayedInit(int delay) { | 294 void RLZTracker::ScheduleDelayedInit(int delay) { |
244 // The RLZTracker is a singleton object that outlives any runnable tasks | 295 // The RLZTracker is a singleton object that outlives any runnable tasks |
245 // that will be queued up. | 296 // that will be queued up. |
246 BrowserThread::GetBlockingPool()->PostDelayedTask( | 297 BrowserThread::GetBlockingPool()->PostDelayedTask( |
247 FROM_HERE, | 298 FROM_HERE, |
248 base::Bind(&RLZTracker::DelayedInit, base::Unretained(this)), | 299 base::Bind(&RLZTracker::DelayedInit, base::Unretained(this)), |
249 base::TimeDelta::FromMilliseconds(delay)); | 300 base::TimeDelta::FromMilliseconds(delay)); |
250 } | 301 } |
251 | 302 |
252 void RLZTracker::DelayedInit() { | 303 void RLZTracker::DelayedInit() { |
253 worker_pool_token_ = BrowserThread::GetBlockingPool()->GetSequenceToken(); | 304 worker_pool_token_ = BrowserThread::GetBlockingPool()->GetSequenceToken(); |
254 | 305 |
255 bool schedule_ping = false; | 306 bool schedule_ping = false; |
256 | 307 |
257 // For organic brandcodes do not use rlz at all. Empty brandcode usually | 308 // For organic brandcodes do not use rlz at all. Empty brandcode usually |
258 // means a chromium install. This is ok. | 309 // means a chromium install. This is ok. |
259 std::string brand; | 310 if (!IsBrandOrganic(brand_)) { |
260 if (google_util::GetBrand(&brand) && !IsBrandOrganic(brand)) { | |
261 RecordProductEvents(first_run_, is_google_default_search_, | 311 RecordProductEvents(first_run_, is_google_default_search_, |
262 is_google_homepage_, is_google_in_startpages_, | 312 is_google_homepage_, is_google_in_startpages_, |
263 already_ran_, omnibox_used_, homepage_used_); | 313 already_ran_, omnibox_used_, homepage_used_); |
264 schedule_ping = true; | 314 schedule_ping = true; |
265 } | 315 } |
266 | 316 |
267 // If chrome has been reactivated, record the events for this brand | 317 // If chrome has been reactivated, record the events for this brand |
268 // as well. | 318 // as well. |
269 std::string reactivation_brand; | 319 if (!IsBrandOrganic(reactivation_brand_)) { |
270 if (google_util::GetReactivationBrand(&reactivation_brand) && | 320 rlz_lib::SupplementaryBranding branding(reactivation_brand_.c_str()); |
271 !IsBrandOrganic(reactivation_brand)) { | |
272 rlz_lib::SupplementaryBranding branding(reactivation_brand.c_str()); | |
273 RecordProductEvents(first_run_, is_google_default_search_, | 321 RecordProductEvents(first_run_, is_google_default_search_, |
274 is_google_homepage_, is_google_in_startpages_, | 322 is_google_homepage_, is_google_in_startpages_, |
275 already_ran_, omnibox_used_, homepage_used_); | 323 already_ran_, omnibox_used_, homepage_used_); |
276 schedule_ping = true; | 324 schedule_ping = true; |
277 } | 325 } |
278 | 326 |
279 already_ran_ = true; | 327 already_ran_ = true; |
280 | 328 |
281 if (schedule_ping) | 329 if (schedule_ping) |
282 ScheduleFinancialPing(); | 330 ScheduleFinancialPing(); |
283 } | 331 } |
284 | 332 |
285 void RLZTracker::ScheduleFinancialPing() { | 333 void RLZTracker::ScheduleFinancialPing() { |
286 BrowserThread::GetBlockingPool()->PostSequencedWorkerTask( | 334 BrowserThread::GetBlockingPool()->PostSequencedWorkerTask( |
287 worker_pool_token_, | 335 worker_pool_token_, |
288 FROM_HERE, | 336 FROM_HERE, |
289 base::Bind(&RLZTracker::PingNowImpl, base::Unretained(this))); | 337 base::Bind(&RLZTracker::PingNowImpl, base::Unretained(this))); |
290 } | 338 } |
291 | 339 |
292 void RLZTracker::PingNowImpl() { | 340 void RLZTracker::PingNowImpl() { |
293 TRACE_EVENT0("RLZ", "RLZTracker::PingNowImpl"); | 341 TRACE_EVENT0("RLZ", "RLZTracker::PingNowImpl"); |
294 string16 lang; | 342 string16 lang; |
295 GoogleUpdateSettings::GetLanguage(&lang); | 343 GoogleUpdateSettings::GetLanguage(&lang); |
296 if (lang.empty()) | 344 if (lang.empty()) |
297 lang = ASCIIToUTF16("en"); | 345 lang = ASCIIToUTF16("en"); |
298 string16 referral; | 346 string16 referral; |
299 GoogleUpdateSettings::GetReferral(&referral); | 347 GoogleUpdateSettings::GetReferral(&referral); |
300 | 348 |
301 std::string brand; | 349 if (!IsBrandOrganic(brand_) && SendFinancialPing(brand_, lang, referral)) { |
302 if (google_util::GetBrand(&brand) && !IsBrandOrganic(brand) && | |
303 SendFinancialPing(brand, lang, referral)) { | |
304 GoogleUpdateSettings::ClearReferral(); | 350 GoogleUpdateSettings::ClearReferral(); |
305 | 351 |
306 { | 352 { |
307 base::AutoLock lock(cache_lock_); | 353 base::AutoLock lock(cache_lock_); |
308 rlz_cache_.clear(); | 354 rlz_cache_.clear(); |
309 } | 355 } |
310 | 356 |
311 // Prime the RLZ cache for the access points we are interested in. | 357 // Prime the RLZ cache for the access points we are interested in. |
312 GetAccessPointRlz(RLZTracker::CHROME_OMNIBOX, NULL); | 358 GetAccessPointRlz(RLZTracker::CHROME_OMNIBOX, NULL); |
313 GetAccessPointRlz(RLZTracker::CHROME_HOME_PAGE, NULL); | 359 GetAccessPointRlz(RLZTracker::CHROME_HOME_PAGE, NULL); |
314 } | 360 } |
315 | 361 |
316 std::string reactivation_brand; | 362 if (!IsBrandOrganic(reactivation_brand_)) { |
317 if (google_util::GetReactivationBrand(&reactivation_brand) && | 363 rlz_lib::SupplementaryBranding branding(reactivation_brand_.c_str()); |
318 !IsBrandOrganic(reactivation_brand)) { | 364 SendFinancialPing(reactivation_brand_, lang, referral); |
319 rlz_lib::SupplementaryBranding branding(reactivation_brand.c_str()); | |
320 SendFinancialPing(reactivation_brand, lang, referral); | |
321 } | 365 } |
322 } | 366 } |
323 | 367 |
324 bool RLZTracker::SendFinancialPing(const std::string& brand, | 368 bool RLZTracker::SendFinancialPing(const std::string& brand, |
325 const string16& lang, | 369 const string16& lang, |
326 const string16& referral) { | 370 const string16& referral) { |
327 return ::SendFinancialPing(brand, lang, referral); | 371 return ::SendFinancialPing(brand, lang, referral); |
328 } | 372 } |
329 | 373 |
330 void RLZTracker::Observe(int type, | 374 void RLZTracker::Observe(int type, |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
368 rlz_lib::AccessPoint point, | 412 rlz_lib::AccessPoint point, |
369 rlz_lib::Event event_id) { | 413 rlz_lib::Event event_id) { |
370 // Make sure we don't access disk outside of the I/O thread. | 414 // Make sure we don't access disk outside of the I/O thread. |
371 // In such case we repost the task on the right thread and return error. | 415 // In such case we repost the task on the right thread and return error. |
372 if (ScheduleRecordProductEvent(product, point, event_id)) | 416 if (ScheduleRecordProductEvent(product, point, event_id)) |
373 return true; | 417 return true; |
374 | 418 |
375 bool ret = rlz_lib::RecordProductEvent(product, point, event_id); | 419 bool ret = rlz_lib::RecordProductEvent(product, point, event_id); |
376 | 420 |
377 // If chrome has been reactivated, record the event for this brand as well. | 421 // If chrome has been reactivated, record the event for this brand as well. |
378 std::string reactivation_brand; | 422 if (!reactivation_brand_.empty()) { |
379 if (google_util::GetReactivationBrand(&reactivation_brand)) { | 423 rlz_lib::SupplementaryBranding branding(reactivation_brand_.c_str()); |
380 rlz_lib::SupplementaryBranding branding(reactivation_brand.c_str()); | |
381 ret &= rlz_lib::RecordProductEvent(product, point, event_id); | 424 ret &= rlz_lib::RecordProductEvent(product, point, event_id); |
382 } | 425 } |
383 | 426 |
384 return ret; | 427 return ret; |
385 } | 428 } |
386 | 429 |
387 bool RLZTracker::ScheduleRecordProductEvent(rlz_lib::Product product, | 430 bool RLZTracker::ScheduleRecordProductEvent(rlz_lib::Product product, |
388 rlz_lib::AccessPoint point, | 431 rlz_lib::AccessPoint point, |
389 rlz_lib::Event event_id) { | 432 rlz_lib::Event event_id) { |
390 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) | 433 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
498 base::Bind(base::IgnoreResult(&RLZTracker::GetAccessPointRlz), point, | 541 base::Bind(base::IgnoreResult(&RLZTracker::GetAccessPointRlz), point, |
499 not_used)); | 542 not_used)); |
500 return true; | 543 return true; |
501 } | 544 } |
502 | 545 |
503 // static | 546 // static |
504 void RLZTracker::CleanupRlz() { | 547 void RLZTracker::CleanupRlz() { |
505 GetInstance()->rlz_cache_.clear(); | 548 GetInstance()->rlz_cache_.clear(); |
506 GetInstance()->registrar_.RemoveAll(); | 549 GetInstance()->registrar_.RemoveAll(); |
507 } | 550 } |
OLD | NEW |