blob: 4eb38c55a74a2c4cf27503219f7c1e4302c6d32a [file] [log] [blame]
sdefresned967d552015-07-16 08:34:351// Copyright 2015 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/rlz/chrome_rlz_tracker_delegate.h"
6
Sebastien Marchandf1349f52019-01-25 03:16:417#include "base/bind.h"
Hans Wennborg1790e6b2020-04-24 19:10:338#include "base/check.h"
sdefresned967d552015-07-16 08:34:359#include "base/command_line.h"
Hans Wennborg1790e6b2020-04-24 19:10:3310#include "base/notreached.h"
avib896c712015-12-26 02:10:4311#include "build/build_config.h"
sdefresned967d552015-07-16 08:34:3512#include "chrome/browser/browser_process.h"
13#include "chrome/browser/chrome_notification_types.h"
14#include "chrome/browser/google/google_brand.h"
sdefresnebd4c75c2015-07-22 09:06:1815#include "chrome/browser/prefs/session_startup_pref.h"
sdefresned967d552015-07-16 08:34:3516#include "chrome/browser/profiles/profile.h"
17#include "chrome/browser/search_engines/template_url_service_factory.h"
sdefresnebd4c75c2015-07-22 09:06:1818#include "chrome/browser/ui/startup/startup_browser_creator.h"
sdefresned967d552015-07-16 08:34:3519#include "chrome/common/chrome_switches.h"
20#include "chrome/common/pref_names.h"
John Abd-El-Malek9cf3d7f02018-07-27 02:40:3921#include "components/google/core/common/google_util.h"
sdefresned967d552015-07-16 08:34:3522#include "components/omnibox/browser/omnibox_log.h"
gab3ca4a492017-03-02 00:19:4123#include "components/pref_registry/pref_registry_syncable.h"
brettwb1fc1b82016-02-02 00:19:0824#include "components/prefs/pref_service.h"
sdefresned967d552015-07-16 08:34:3525#include "components/search_engines/template_url.h"
26#include "components/search_engines/template_url_service.h"
27#include "content/public/browser/browser_thread.h"
28#include "content/public/browser/navigation_controller.h"
29#include "content/public/browser/navigation_details.h"
30#include "content/public/browser/navigation_entry.h"
31#include "content/public/browser/notification_details.h"
32#include "content/public/browser/notification_service.h"
33#include "content/public/browser/notification_source.h"
brettw90e92602015-10-10 00:12:4034#include "content/public/common/content_switches.h"
Scott Violeta5f7ba12018-04-02 22:03:4035#include "rlz/buildflags/buildflags.h"
Antonio Gomesa739bf462018-08-13 20:50:3036#include "services/network/public/cpp/shared_url_loader_factory.h"
sdefresned967d552015-07-16 08:34:3537
38#if defined(OS_WIN)
39#include "chrome/installer/util/google_update_settings.h"
40#endif
41
Wenzhao Zang8825a772018-04-04 01:56:2242#if defined(OS_CHROMEOS)
43#include "base/command_line.h"
Steven Bennetts38e9bde22019-01-03 17:31:1044#include "chromeos/constants/chromeos_switches.h"
Wenzhao Zang8825a772018-04-04 01:56:2245#endif
46
rogertac4a9c772017-08-01 16:40:3047ChromeRLZTrackerDelegate::ChromeRLZTrackerDelegate() {}
sdefresned967d552015-07-16 08:34:3548
rogertac4a9c772017-08-01 16:40:3049ChromeRLZTrackerDelegate::~ChromeRLZTrackerDelegate() {}
sdefresned967d552015-07-16 08:34:3550
51// static
gab3ca4a492017-03-02 00:19:4152void ChromeRLZTrackerDelegate::RegisterProfilePrefs(
53 user_prefs::PrefRegistrySyncable* registry) {
54#if BUILDFLAG(ENABLE_RLZ)
Wenzhao Zang8825a772018-04-04 01:56:2255 int rlz_ping_delay_seconds = 90;
Roger Tawac5d56c3c2018-03-15 14:21:2356#if defined(OS_CHROMEOS)
Wenzhao Zang8825a772018-04-04 01:56:2257 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
58 chromeos::switches::kRlzPingDelay)) {
59 // Use a switch for overwriting the default delay because it doesn't seem
60 // possible to manually override the Preferences file on Chrome OS: the file
61 // is already loaded into memory by the time you modify it and any changes
62 // made get overwritten by Chrome.
63 rlz_ping_delay_seconds =
64 std::stoi(base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
65 chromeos::switches::kRlzPingDelay));
66 } else {
67 rlz_ping_delay_seconds = 24 * 3600;
68 }
gab3ca4a492017-03-02 00:19:4169#endif
Wenzhao Zang8825a772018-04-04 01:56:2270 registry->RegisterIntegerPref(prefs::kRlzPingDelaySeconds,
71 rlz_ping_delay_seconds);
Roger Tawac5d56c3c2018-03-15 14:21:2372#endif
gab3ca4a492017-03-02 00:19:4173}
74
75// static
sdefresned967d552015-07-16 08:34:3576bool ChromeRLZTrackerDelegate::IsGoogleDefaultSearch(Profile* profile) {
77 bool is_google_default_search = false;
78 TemplateURLService* template_url_service =
79 TemplateURLServiceFactory::GetForProfile(profile);
80 if (template_url_service) {
81 const TemplateURL* url_template =
82 template_url_service->GetDefaultSearchProvider();
83 is_google_default_search = url_template &&
84 url_template->url_ref().HasGoogleBaseURLs(
85 template_url_service->search_terms_data());
86 }
87 return is_google_default_search;
88}
89
90// static
91bool ChromeRLZTrackerDelegate::IsGoogleHomepage(Profile* profile) {
92 return google_util::IsGoogleHomePageUrl(
93 GURL(profile->GetPrefs()->GetString(prefs::kHomePage)));
94}
95
96// static
97bool ChromeRLZTrackerDelegate::IsGoogleInStartpages(Profile* profile) {
sdefresned967d552015-07-16 08:34:3598 bool is_google_in_startpages = false;
99 SessionStartupPref session_startup_prefs =
100 StartupBrowserCreator::GetSessionStartupPref(
101 *base::CommandLine::ForCurrentProcess(), profile);
102 if (session_startup_prefs.type == SessionStartupPref::URLS) {
103 is_google_in_startpages =
104 std::count_if(session_startup_prefs.urls.begin(),
105 session_startup_prefs.urls.end(),
106 google_util::IsGoogleHomePageUrl) > 0;
107 }
108 return is_google_in_startpages;
sdefresned967d552015-07-16 08:34:35109}
110
111void ChromeRLZTrackerDelegate::Cleanup() {
112 registrar_.RemoveAll();
113 on_omnibox_search_callback_.Reset();
114 on_homepage_search_callback_.Reset();
115}
116
117bool ChromeRLZTrackerDelegate::IsOnUIThread() {
118 return content::BrowserThread::CurrentlyOn(content::BrowserThread::UI);
119}
120
Antonio Gomesa739bf462018-08-13 20:50:30121scoped_refptr<network::SharedURLLoaderFactory>
122ChromeRLZTrackerDelegate::GetURLLoaderFactory() {
123 return g_browser_process->shared_url_loader_factory();
sdefresned967d552015-07-16 08:34:35124}
125
126bool ChromeRLZTrackerDelegate::GetBrand(std::string* brand) {
Wenzhao Zang20153792018-09-29 00:37:10127 return google_brand::GetRlzBrand(brand);
sdefresned967d552015-07-16 08:34:35128}
129
130bool ChromeRLZTrackerDelegate::IsBrandOrganic(const std::string& brand) {
Joshua Pawlickibc5533ae2019-03-25 16:32:43131 return google_brand::IsOrganic(brand);
sdefresned967d552015-07-16 08:34:35132}
133
134bool ChromeRLZTrackerDelegate::GetReactivationBrand(std::string* brand) {
135 return google_brand::GetReactivationBrand(brand);
136}
137
138bool ChromeRLZTrackerDelegate::ShouldEnableZeroDelayForTesting() {
139 return base::CommandLine::ForCurrentProcess()->HasSwitch(
140 ::switches::kTestType);
141}
142
143bool ChromeRLZTrackerDelegate::GetLanguage(base::string16* language) {
144#if defined(OS_WIN)
145 return GoogleUpdateSettings::GetLanguage(language);
146#else
xdaiae4bf62a2016-04-06 18:15:59147 // On other systems, we don't know the install language of promotions. That's
148 // OK, for now all promotions on non-Windows systems will be reported as "en".
149 // If non-Windows promotions end up requiring language code reporting, that
150 // code will need to go here.
sdefresned967d552015-07-16 08:34:35151 return false;
152#endif
153}
154
155bool ChromeRLZTrackerDelegate::GetReferral(base::string16* referral) {
156#if defined(OS_WIN)
157 return GoogleUpdateSettings::GetReferral(referral);
158#else
159 // The referral program is defunct and not used. No need to implement this
160 // function on non-Win platforms.
161 return true;
162#endif
163}
164
165bool ChromeRLZTrackerDelegate::ClearReferral() {
166#if defined(OS_WIN)
167 return GoogleUpdateSettings::ClearReferral();
168#else
169 // The referral program is defunct and not used. No need to implement this
170 // function on non-Win platforms.
171 return true;
172#endif
173}
174
175void ChromeRLZTrackerDelegate::SetOmniboxSearchCallback(
Ayu Ishiiebdc85f2020-02-07 17:50:43176 base::OnceClosure callback) {
sdefresned967d552015-07-16 08:34:35177 DCHECK(!callback.is_null());
blundell81308002015-08-18 15:06:09178 omnibox_url_opened_subscription_ =
179 OmniboxEventGlobalTracker::GetInstance()->RegisterCallback(
180 base::Bind(&ChromeRLZTrackerDelegate::OnURLOpenedFromOmnibox,
181 base::Unretained(this)));
Ayu Ishiiebdc85f2020-02-07 17:50:43182 on_omnibox_search_callback_ = std::move(callback);
sdefresned967d552015-07-16 08:34:35183}
184
185void ChromeRLZTrackerDelegate::SetHomepageSearchCallback(
Ayu Ishiiebdc85f2020-02-07 17:50:43186 base::OnceClosure callback) {
sdefresned967d552015-07-16 08:34:35187 DCHECK(!callback.is_null());
188 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
189 content::NotificationService::AllSources());
Ayu Ishiiebdc85f2020-02-07 17:50:43190 on_homepage_search_callback_ = std::move(callback);
sdefresned967d552015-07-16 08:34:35191}
192
Jérôme Lebel0d2a5a82018-12-06 10:13:37193bool ChromeRLZTrackerDelegate::ShouldUpdateExistingAccessPointRlz() {
194 return true;
195}
196
sdefresned967d552015-07-16 08:34:35197void ChromeRLZTrackerDelegate::Observe(
198 int type,
199 const content::NotificationSource& source,
200 const content::NotificationDetails& details) {
Ayu Ishiiebdc85f2020-02-07 17:50:43201 base::OnceClosure callback_to_run;
sdefresned967d552015-07-16 08:34:35202 switch (type) {
sdefresned967d552015-07-16 08:34:35203 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: {
204 // Firstly check if it is a Google search.
205 content::LoadCommittedDetails* load_details =
206 content::Details<content::LoadCommittedDetails>(details).ptr();
207 if (load_details == nullptr)
208 break;
209
210 content::NavigationEntry* entry = load_details->entry;
211 if (entry == nullptr)
212 break;
213
214 if (google_util::IsGoogleSearchUrl(entry->GetURL())) {
215 // If it is a Google search, check if it originates from HOMEPAGE by
216 // getting the previous NavigationEntry.
217 content::NavigationController* controller =
218 content::Source<content::NavigationController>(source).ptr();
219 if (controller == nullptr)
220 break;
221
222 int entry_index = controller->GetLastCommittedEntryIndex();
223 if (entry_index < 1)
224 break;
225
Lucas Furukawa Gadani5553a152019-01-08 18:55:57226 content::NavigationEntry* previous_entry =
sdefresned967d552015-07-16 08:34:35227 controller->GetEntryAtIndex(entry_index - 1);
228
229 if (previous_entry == nullptr)
230 break;
231
232 // Make sure it is a Google web page originated from HOMEPAGE.
233 if (google_util::IsGoogleHomePageUrl(previous_entry->GetURL()) &&
234 ((previous_entry->GetTransitionType() &
235 ui::PAGE_TRANSITION_HOME_PAGE) != 0)) {
236 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
237 content::NotificationService::AllSources());
Ayu Ishiiebdc85f2020-02-07 17:50:43238 callback_to_run = std::move(on_homepage_search_callback_);
sdefresned967d552015-07-16 08:34:35239 }
240 }
241 break;
242 }
sdefresned967d552015-07-16 08:34:35243
244 default:
245 NOTREACHED();
246 break;
247 }
248
249 if (!callback_to_run.is_null())
Ayu Ishiiebdc85f2020-02-07 17:50:43250 std::move(callback_to_run).Run();
sdefresned967d552015-07-16 08:34:35251}
blundell81308002015-08-18 15:06:09252
253void ChromeRLZTrackerDelegate::OnURLOpenedFromOmnibox(OmniboxLog* log) {
blundell81308002015-08-18 15:06:09254
255 // In M-36, we made NOTIFICATION_OMNIBOX_OPENED_URL fire more often than
256 // it did previously. The RLZ folks want RLZ's "first search" detection
257 // to remain as unaffected as possible by this change. This test is
258 // there to keep the old behavior.
259 if (!log->is_popup_open)
260 return;
261
Peter Kasting7ba9440c2020-11-22 01:49:02262 omnibox_url_opened_subscription_ = {};
Ayu Ishiiebdc85f2020-02-07 17:50:43263 std::move(on_omnibox_search_callback_).Run();
blundell81308002015-08-18 15:06:09264}