Index: chrome/browser/rlz/rlz.cc |
diff --git a/components/rlz/rlz_tracker.cc b/chrome/browser/rlz/rlz.cc |
similarity index 64% |
rename from components/rlz/rlz_tracker.cc |
rename to chrome/browser/rlz/rlz.cc |
index baa166a9b04fb4db8a3b756bdad310be5221890e..94064d272b29948f07f942d9b30d69d1ec13103b 100644 |
--- a/components/rlz/rlz_tracker.cc |
+++ b/chrome/browser/rlz/rlz.cc |
@@ -6,19 +6,61 @@ |
// with or without the DLL being present. If the DLL is not present the |
// functions do nothing and just return false. |
-#include "components/rlz/rlz_tracker.h" |
+#include "chrome/browser/rlz/rlz.h" |
#include <algorithm> |
#include "base/bind.h" |
+#include "base/command_line.h" |
#include "base/message_loop/message_loop.h" |
+#include "base/prefs/pref_service.h" |
#include "base/strings/string_util.h" |
#include "base/strings/utf_string_conversions.h" |
#include "base/trace_event/trace_event.h" |
-#include "components/rlz/rlz_tracker_delegate.h" |
+#include "chrome/browser/browser_process.h" |
+#include "chrome/browser/chrome_notification_types.h" |
+#include "chrome/browser/google/google_brand.h" |
+#include "chrome/browser/prefs/session_startup_pref.h" |
+#include "chrome/browser/search_engines/template_url_service_factory.h" |
+#include "chrome/browser/ui/startup/startup_browser_creator.h" |
+#include "chrome/common/chrome_switches.h" |
+#include "chrome/common/pref_names.h" |
+#include "components/google/core/browser/google_util.h" |
+#include "components/omnibox/browser/omnibox_log.h" |
+#include "components/search_engines/template_url.h" |
+#include "components/search_engines/template_url_service.h" |
+#include "content/public/browser/browser_thread.h" |
+#include "content/public/browser/navigation_controller.h" |
+#include "content/public/browser/navigation_details.h" |
+#include "content/public/browser/navigation_entry.h" |
+#include "content/public/browser/notification_service.h" |
#include "net/http/http_util.h" |
-namespace rlz { |
+#if defined(OS_WIN) |
+#include "chrome/installer/util/google_update_settings.h" |
+#else |
+namespace GoogleUpdateSettings { |
+static bool GetLanguage(base::string16* language) { |
+ // TODO(thakis): Implement. |
+ NOTIMPLEMENTED(); |
+ return false; |
+} |
+ |
+// The referral program is defunct and not used. No need to implement these |
+// functions on non-Win platforms. |
+static bool GetReferral(base::string16* referral) { |
+ return true; |
+} |
+static bool ClearReferral() { |
+ return true; |
+} |
+} // namespace GoogleUpdateSettings |
+#endif |
+ |
+using content::BrowserThread; |
+using content::NavigationEntry; |
+using content::NavigationController; |
+ |
namespace { |
// Maximum and minimum delay for financial ping we would allow to be set through |
@@ -26,6 +68,10 @@ namespace { |
const base::TimeDelta kMaxInitDelay = base::TimeDelta::FromSeconds(200); |
const base::TimeDelta kMinInitDelay = base::TimeDelta::FromSeconds(20); |
+bool IsBrandOrganic(const std::string& brand) { |
+ return brand.empty() || google_brand::IsOrganic(brand); |
+} |
+ |
void RecordProductEvents(bool first_run, |
bool is_google_default_search, |
bool is_google_homepage, |
@@ -146,7 +192,7 @@ bool SendFinancialPing(const std::string& brand, |
} // namespace |
-RLZTracker* RLZTracker::tracker_ = nullptr; |
+RLZTracker* RLZTracker::tracker_ = NULL; |
// static |
RLZTracker* RLZTracker::GetInstance() { |
@@ -159,6 +205,7 @@ RLZTracker::RLZTracker() |
is_google_default_search_(false), |
is_google_homepage_(false), |
is_google_in_startpages_(false), |
+ worker_pool_token_(BrowserThread::GetBlockingPool()->GetSequenceToken()), |
already_ran_(false), |
omnibox_used_(false), |
homepage_used_(false), |
@@ -170,19 +217,6 @@ RLZTracker::~RLZTracker() { |
} |
// static |
-void RLZTracker::SetRlzDelegate(scoped_ptr<RLZTrackerDelegate> delegate) { |
- GetInstance()->SetDelegate(delegate.Pass()); |
-} |
- |
-void RLZTracker::SetDelegate(scoped_ptr<RLZTrackerDelegate> delegate) { |
- DCHECK(delegate); |
- if (!delegate_) { |
- delegate_ = delegate.Pass(); |
- worker_pool_token_ = delegate_->GetBlockingPool()->GetSequenceToken(); |
- } |
-} |
- |
-// static |
bool RLZTracker::InitRlzDelayed(bool first_run, |
bool send_ping_immediately, |
base::TimeDelta delay, |
@@ -194,6 +228,56 @@ bool RLZTracker::InitRlzDelayed(bool first_run, |
is_google_in_startpages); |
} |
+// static |
+bool RLZTracker::InitRlzFromProfileDelayed(Profile* profile, |
+ bool first_run, |
+ bool send_ping_immediately, |
+ base::TimeDelta delay) { |
+ bool is_google_default_search = false; |
+ TemplateURLService* template_url_service = |
+ TemplateURLServiceFactory::GetForProfile(profile); |
+ if (template_url_service) { |
+ const TemplateURL* url_template = |
+ template_url_service->GetDefaultSearchProvider(); |
+ is_google_default_search = |
+ url_template && url_template->url_ref().HasGoogleBaseURLs( |
+ template_url_service->search_terms_data()); |
+ } |
+ |
+ PrefService* pref_service = profile->GetPrefs(); |
+ bool is_google_homepage = google_util::IsGoogleHomePageUrl( |
+ GURL(pref_service->GetString(prefs::kHomePage))); |
+ |
+ bool is_google_in_startpages = false; |
+#if !defined(OS_IOS) |
+ // iOS does not have a notion of startpages. |
+ SessionStartupPref session_startup_prefs = |
+ StartupBrowserCreator::GetSessionStartupPref( |
+ *base::CommandLine::ForCurrentProcess(), profile); |
+ if (session_startup_prefs.type == SessionStartupPref::URLS) { |
+ is_google_in_startpages = |
+ std::count_if(session_startup_prefs.urls.begin(), |
+ session_startup_prefs.urls.end(), |
+ google_util::IsGoogleHomePageUrl) > 0; |
+ } |
+#endif |
+ |
+ if (!InitRlzDelayed(first_run, send_ping_immediately, delay, |
+ is_google_default_search, is_google_homepage, |
+ is_google_in_startpages)) { |
+ return false; |
+ } |
+ |
+#if !defined(OS_IOS) |
+ // Prime the RLZ cache for the home page access point so that its avaiable |
+ // for the startup page if needed (i.e., when the startup page is set to |
+ // the home page). |
+ GetAccessPointRlz(ChromeHomePage(), NULL); |
+#endif // !defined(OS_IOS) |
+ |
+ return true; |
+} |
+ |
bool RLZTracker::Init(bool first_run, |
bool send_ping_immediately, |
base::TimeDelta delay, |
@@ -207,57 +291,46 @@ bool RLZTracker::Init(bool first_run, |
send_ping_immediately_ = send_ping_immediately; |
// Enable zero delays for testing. |
- if (delegate_->ShouldEnableZeroDelayForTesting()) |
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestType)) |
EnableZeroDelayForTesting(); |
delay = std::min(kMaxInitDelay, std::max(min_init_delay_, delay)); |
- if (delegate_->GetBrand(&brand_) && !delegate_->IsBrandOrganic(brand_)) { |
+ if (google_brand::GetBrand(&brand_) && !IsBrandOrganic(brand_)) { |
// Register for notifications from the omnibox so that we can record when |
// the user performs a first search. |
- delegate_->SetOmniboxSearchCallback( |
- base::Bind(&RLZTracker::RecordFirstSearch, base::Unretained(this), |
- ChromeOmnibox())); |
+ registrar_.Add(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL, |
+ content::NotificationService::AllSources()); |
#if !defined(OS_IOS) |
// Register for notifications from navigations, to see if the user has used |
// the home page. |
- delegate_->SetHomepageSearchCallback( |
- base::Bind(&RLZTracker::RecordFirstSearch, base::Unretained(this), |
- ChromeHomePage())); |
-#endif |
+ registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
+ content::NotificationService::AllSources()); |
+#endif // !defined(OS_IOS) |
} |
- delegate_->GetReactivationBrand(&reactivation_brand_); |
+ google_brand::GetReactivationBrand(&reactivation_brand_); |
+ |
+ net::URLRequestContextGetter* context_getter = |
+ g_browser_process->system_request_context(); |
- // Could be null; don't run if so. RLZ will try again next restart. |
- net::URLRequestContextGetter* context_getter = delegate_->GetRequestContext(); |
+ // Could be NULL; don't run if so. RLZ will try again next restart. |
if (context_getter) { |
rlz_lib::SetURLRequestContext(context_getter); |
ScheduleDelayedInit(delay); |
} |
-#if !defined(OS_IOS) |
- // Prime the RLZ cache for the home page access point so that its avaiable |
- // for the startup page if needed (i.e., when the startup page is set to |
- // the home page). |
- GetAccessPointRlz(ChromeHomePage(), nullptr); |
-#endif // !defined(OS_IOS) |
- |
return true; |
} |
-void RLZTracker::Cleanup() { |
- rlz_cache_.clear(); |
- if (delegate_) |
- delegate_->Cleanup(); |
-} |
- |
void RLZTracker::ScheduleDelayedInit(base::TimeDelta delay) { |
// The RLZTracker is a singleton object that outlives any runnable tasks |
// that will be queued up. |
- delegate_->GetBlockingPool()->PostDelayedSequencedWorkerTask( |
- worker_pool_token_, FROM_HERE, |
- base::Bind(&RLZTracker::DelayedInit, base::Unretained(this)), delay); |
+ BrowserThread::GetBlockingPool()->PostDelayedSequencedWorkerTask( |
+ worker_pool_token_, |
+ FROM_HERE, |
+ base::Bind(&RLZTracker::DelayedInit, base::Unretained(this)), |
+ delay); |
} |
void RLZTracker::DelayedInit() { |
@@ -265,7 +338,7 @@ void RLZTracker::DelayedInit() { |
// For organic brandcodes do not use rlz at all. Empty brandcode usually |
// means a chromium install. This is ok. |
- if (!delegate_->IsBrandOrganic(brand_)) { |
+ if (!IsBrandOrganic(brand_)) { |
RecordProductEvents(first_run_, is_google_default_search_, |
is_google_homepage_, is_google_in_startpages_, |
already_ran_, omnibox_used_, homepage_used_, |
@@ -275,7 +348,7 @@ void RLZTracker::DelayedInit() { |
// If chrome has been reactivated, record the events for this brand |
// as well. |
- if (!delegate_->IsBrandOrganic(reactivation_brand_)) { |
+ if (!IsBrandOrganic(reactivation_brand_)) { |
rlz_lib::SupplementaryBranding branding(reactivation_brand_.c_str()); |
RecordProductEvents(first_run_, is_google_default_search_, |
is_google_homepage_, is_google_in_startpages_, |
@@ -291,8 +364,9 @@ void RLZTracker::DelayedInit() { |
} |
void RLZTracker::ScheduleFinancialPing() { |
- delegate_->GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior( |
- worker_pool_token_, FROM_HERE, |
+ BrowserThread::GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior( |
+ worker_pool_token_, |
+ FROM_HERE, |
base::Bind(&RLZTracker::PingNowImpl, base::Unretained(this)), |
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); |
} |
@@ -300,15 +374,14 @@ void RLZTracker::ScheduleFinancialPing() { |
void RLZTracker::PingNowImpl() { |
TRACE_EVENT0("RLZ", "RLZTracker::PingNowImpl"); |
base::string16 lang; |
- delegate_->GetLanguage(&lang); |
+ GoogleUpdateSettings::GetLanguage(&lang); |
if (lang.empty()) |
lang = base::ASCIIToUTF16("en"); |
base::string16 referral; |
- delegate_->GetReferral(&referral); |
+ GoogleUpdateSettings::GetReferral(&referral); |
- if (!delegate_->IsBrandOrganic(brand_) && |
- SendFinancialPing(brand_, lang, referral)) { |
- delegate_->ClearReferral(); |
+ if (!IsBrandOrganic(brand_) && SendFinancialPing(brand_, lang, referral)) { |
+ GoogleUpdateSettings::ClearReferral(); |
{ |
base::AutoLock lock(cache_lock_); |
@@ -316,14 +389,14 @@ void RLZTracker::PingNowImpl() { |
} |
// Prime the RLZ cache for the access points we are interested in. |
- GetAccessPointRlz(RLZTracker::ChromeOmnibox(), nullptr); |
+ GetAccessPointRlz(RLZTracker::ChromeOmnibox(), NULL); |
#if !defined(OS_IOS) |
- GetAccessPointRlz(RLZTracker::ChromeHomePage(), nullptr); |
- GetAccessPointRlz(RLZTracker::ChromeAppList(), nullptr); |
+ GetAccessPointRlz(RLZTracker::ChromeHomePage(), NULL); |
+ GetAccessPointRlz(RLZTracker::ChromeAppList(), NULL); |
#endif // !defined(OS_IOS) |
} |
- if (!delegate_->IsBrandOrganic(reactivation_brand_)) { |
+ if (!IsBrandOrganic(reactivation_brand_)) { |
rlz_lib::SupplementaryBranding branding(reactivation_brand_.c_str()); |
SendFinancialPing(reactivation_brand_, lang, referral); |
} |
@@ -332,7 +405,70 @@ void RLZTracker::PingNowImpl() { |
bool RLZTracker::SendFinancialPing(const std::string& brand, |
const base::string16& lang, |
const base::string16& referral) { |
- return ::rlz::SendFinancialPing(brand, lang, referral); |
+ return ::SendFinancialPing(brand, lang, referral); |
+} |
+ |
+void RLZTracker::Observe(int type, |
+ const content::NotificationSource& source, |
+ const content::NotificationDetails& details) { |
+ switch (type) { |
+ case chrome::NOTIFICATION_OMNIBOX_OPENED_URL: |
+ // In M-36, we made NOTIFICATION_OMNIBOX_OPENED_URL fire more often than |
+ // it did previously. The RLZ folks want RLZ's "first search" detection |
+ // to remain as unaffected as possible by this change. This test is |
+ // there to keep the old behavior. |
+ if (!content::Details<OmniboxLog>(details).ptr()->is_popup_open) |
+ break; |
+ RecordFirstSearch(ChromeOmnibox()); |
+ registrar_.Remove(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL, |
+ content::NotificationService::AllSources()); |
+ break; |
+#if !defined(OS_IOS) |
+ case content::NOTIFICATION_NAV_ENTRY_COMMITTED: { |
+ // Firstly check if it is a Google search. |
+ content::LoadCommittedDetails* load_details = |
+ content::Details<content::LoadCommittedDetails>(details).ptr(); |
+ if (load_details == NULL) |
+ break; |
+ |
+ NavigationEntry* entry = load_details->entry; |
+ if (entry == NULL) |
+ break; |
+ |
+ if (google_util::IsGoogleSearchUrl(entry->GetURL())) { |
+ // If it is a Google search, check if it originates from HOMEPAGE by |
+ // getting the previous NavigationEntry. |
+ NavigationController* controller = |
+ content::Source<NavigationController>(source).ptr(); |
+ if (controller == NULL) |
+ break; |
+ |
+ int entry_index = controller->GetLastCommittedEntryIndex(); |
+ if (entry_index < 1) |
+ break; |
+ |
+ const NavigationEntry* previous_entry = controller->GetEntryAtIndex( |
+ entry_index - 1); |
+ |
+ if (previous_entry == NULL) |
+ break; |
+ |
+ // Make sure it is a Google web page originated from HOMEPAGE. |
+ if (google_util::IsGoogleHomePageUrl(previous_entry->GetURL()) && |
+ ((previous_entry->GetTransitionType() & |
+ ui::PAGE_TRANSITION_HOME_PAGE) != 0)) { |
+ RecordFirstSearch(ChromeHomePage()); |
+ registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
+ content::NotificationService::AllSources()); |
+ } |
+ } |
+ break; |
+ } |
+#endif // !defined(OS_IOS) |
+ default: |
+ NOTREACHED(); |
+ break; |
+ } |
} |
// static |
@@ -364,13 +500,14 @@ bool RLZTracker::RecordProductEventImpl(rlz_lib::Product product, |
bool RLZTracker::ScheduleRecordProductEvent(rlz_lib::Product product, |
rlz_lib::AccessPoint point, |
rlz_lib::Event event_id) { |
- if (!delegate_->IsOnUIThread()) |
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) |
return false; |
- delegate_->GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior( |
- worker_pool_token_, FROM_HERE, |
- base::Bind(base::IgnoreResult(&RLZTracker::RecordProductEvent), product, |
- point, event_id), |
+ BrowserThread::GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior( |
+ worker_pool_token_, |
+ FROM_HERE, |
+ base::Bind(base::IgnoreResult(&RLZTracker::RecordProductEvent), |
+ product, point, event_id), |
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); |
return true; |
@@ -393,11 +530,13 @@ void RLZTracker::RecordFirstSearch(rlz_lib::AccessPoint point) { |
} |
bool RLZTracker::ScheduleRecordFirstSearch(rlz_lib::AccessPoint point) { |
- if (!delegate_->IsOnUIThread()) |
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) |
return false; |
- delegate_->GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior( |
- worker_pool_token_, FROM_HERE, |
- base::Bind(&RLZTracker::RecordFirstSearch, base::Unretained(this), point), |
+ BrowserThread::GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior( |
+ worker_pool_token_, |
+ FROM_HERE, |
+ base::Bind(&RLZTracker::RecordFirstSearch, |
+ base::Unretained(this), point), |
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); |
return true; |
} |
@@ -412,7 +551,7 @@ bool* RLZTracker::GetAccessPointRecord(rlz_lib::AccessPoint point) { |
return &app_list_used_; |
#endif // !defined(OS_IOS) |
NOTREACHED(); |
- return nullptr; |
+ return NULL; |
} |
// static |
@@ -472,12 +611,13 @@ bool RLZTracker::GetAccessPointRlzImpl(rlz_lib::AccessPoint point, |
} |
bool RLZTracker::ScheduleGetAccessPointRlz(rlz_lib::AccessPoint point) { |
- if (!delegate_->IsOnUIThread()) |
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) |
return false; |
- base::string16* not_used = nullptr; |
- delegate_->GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior( |
- worker_pool_token_, FROM_HERE, |
+ base::string16* not_used = NULL; |
+ BrowserThread::GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior( |
+ worker_pool_token_, |
+ FROM_HERE, |
base::Bind(base::IgnoreResult(&RLZTracker::GetAccessPointRlz), point, |
not_used), |
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); |
@@ -497,12 +637,14 @@ void RLZTracker::ClearRlzStateImpl() { |
} |
bool RLZTracker::ScheduleClearRlzState() { |
- if (!delegate_->IsOnUIThread()) |
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) |
return false; |
- delegate_->GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior( |
- worker_pool_token_, FROM_HERE, |
- base::Bind(&RLZTracker::ClearRlzStateImpl, base::Unretained(this)), |
+ BrowserThread::GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior( |
+ worker_pool_token_, |
+ FROM_HERE, |
+ base::Bind(&RLZTracker::ClearRlzStateImpl, |
+ base::Unretained(this)), |
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); |
return true; |
} |
@@ -510,8 +652,9 @@ bool RLZTracker::ScheduleClearRlzState() { |
// static |
void RLZTracker::CleanupRlz() { |
- GetInstance()->Cleanup(); |
- rlz_lib::SetURLRequestContext(nullptr); |
+ GetInstance()->rlz_cache_.clear(); |
+ GetInstance()->registrar_.RemoveAll(); |
+ rlz_lib::SetURLRequestContext(NULL); |
} |
// static |
@@ -525,5 +668,3 @@ void RLZTracker::RecordAppListSearch() { |
GetInstance()->RecordFirstSearch(RLZTracker::ChromeAppList()); |
} |
#endif |
- |
-} // namespace rlz |