Chromium Code Reviews| 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 |