Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: chrome/browser/android/search_geolocation/search_geolocation_service.cc

Issue 2637953003: Refactor SearchGeolocationService to make it testable (Closed)
Patch Set: Refactor for test Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/android/search_geolocation/search_geolocation_service.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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 #include "chrome/browser/android/search_geolocation/search_geolocation_service.h " 5 #include "chrome/browser/android/search_geolocation/search_geolocation_service.h "
6 6
7 #include "base/callback.h"
7 #include "base/feature_list.h" 8 #include "base/feature_list.h"
8 #include "base/values.h" 9 #include "base/values.h"
9 #include "chrome/browser/android/search_geolocation/search_geolocation_disclosur e_tab_helper.h" 10 #include "chrome/browser/android/search_geolocation/search_geolocation_disclosur e_tab_helper.h"
10 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" 11 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
11 #include "chrome/browser/profiles/profile.h" 12 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/search_engines/template_url_service_factory.h" 13 #include "chrome/browser/search_engines/template_url_service_factory.h"
13 #include "chrome/browser/search_engines/ui_thread_search_terms_data.h" 14 #include "chrome/browser/search_engines/ui_thread_search_terms_data.h"
14 #include "chrome/common/chrome_features.h" 15 #include "chrome/common/chrome_features.h"
15 #include "chrome/common/pref_names.h" 16 #include "chrome/common/pref_names.h"
16 #include "components/content_settings/core/browser/content_settings_utils.h" 17 #include "components/content_settings/core/browser/content_settings_utils.h"
17 #include "components/content_settings/core/browser/host_content_settings_map.h" 18 #include "components/content_settings/core/browser/host_content_settings_map.h"
18 #include "components/content_settings/core/common/content_settings_types.h" 19 #include "components/content_settings/core/common/content_settings_types.h"
19 #include "components/keyed_service/content/browser_context_dependency_manager.h" 20 #include "components/keyed_service/content/browser_context_dependency_manager.h"
20 #include "components/pref_registry/pref_registry_syncable.h" 21 #include "components/pref_registry/pref_registry_syncable.h"
21 #include "components/prefs/pref_service.h" 22 #include "components/prefs/pref_service.h"
22 #include "components/search_engines/template_url.h" 23 #include "components/search_engines/template_url.h"
23 #include "components/search_engines/template_url_service.h" 24 #include "components/search_engines/template_url_service.h"
25 #include "components/search_engines/template_url_service_observer.h"
24 #include "url/gurl.h" 26 #include "url/gurl.h"
25 #include "url/url_constants.h" 27 #include "url/url_constants.h"
26 28
27 namespace { 29 namespace {
28 30
29 const char kIsGoogleSearchEngineKey[] = "is_google_search_engine"; 31 const char kIsGoogleSearchEngineKey[] = "is_google_search_engine";
30 const char kCCTLDKey[] = "cctld";
31 const char kDSESettingKey[] = "dse_setting"; 32 const char kDSESettingKey[] = "dse_setting";
32 33
34 // Default implementation of SearchEngineDelegate that is used for production
35 // code.
36 class SearchEngineDelegateImpl
37 : public SearchGeolocationService::SearchEngineDelegate,
38 public TemplateURLServiceObserver {
39 public:
40 explicit SearchEngineDelegateImpl(Profile* profile)
41 : profile_(profile),
42 template_url_service_(
43 TemplateURLServiceFactory::GetForProfile(profile_)) {
44 if (template_url_service_)
45 template_url_service_->AddObserver(this);
46 }
47
48 ~SearchEngineDelegateImpl() override {
49 if (template_url_service_)
50 template_url_service_->RemoveObserver(this);
51 }
52
53 bool IsDSEGoogle() override {
54 if (!template_url_service_)
55 return false;
56
57 const TemplateURL* template_url =
58 template_url_service_->GetDefaultSearchProvider();
59 return template_url &&
60 template_url->HasGoogleBaseURLs(UIThreadSearchTermsData(profile_));
61 }
62
63 url::Origin GetGoogleDSECCTLD() override {
64 if (!IsDSEGoogle())
65 return url::Origin();
66
67 return url::Origin(
68 GURL(UIThreadSearchTermsData(profile_).GoogleBaseURLValue()));
69 }
70
71 void SetDSEChangedCallback(const base::Closure& callback) override {
72 dse_changed_callback_ = callback;
73 }
74
75 // TemplateURLServiceObserver
76 void OnTemplateURLServiceChanged() override { dse_changed_callback_.Run(); }
77
78 private:
79 Profile* profile_;
80
81 // Will be null in unittests.
82 TemplateURLService* template_url_service_;
83
84 base::Closure dse_changed_callback_;
85 };
86
33 } // namespace 87 } // namespace
34 88
35 struct SearchGeolocationService::PrefValue { 89 struct SearchGeolocationService::PrefValue {
36 bool is_google_search_engine = false; 90 bool is_google_search_engine = false;
37 url::Origin cctld;
38 bool setting = false; 91 bool setting = false;
39 }; 92 };
40 93
41 // static 94 // static
42 SearchGeolocationService* 95 SearchGeolocationService*
43 SearchGeolocationService::Factory::GetForBrowserContext( 96 SearchGeolocationService::Factory::GetForBrowserContext(
44 content::BrowserContext* context) { 97 content::BrowserContext* context) {
45 return static_cast<SearchGeolocationService*>(GetInstance() 98 return static_cast<SearchGeolocationService*>(GetInstance()
46 ->GetServiceForBrowserContext(context, true)); 99 ->GetServiceForBrowserContext(context, true));
47 } 100 }
(...skipping 27 matching lines...) Expand all
75 // static 128 // static
76 void SearchGeolocationService::RegisterProfilePrefs( 129 void SearchGeolocationService::RegisterProfilePrefs(
77 user_prefs::PrefRegistrySyncable* registry) { 130 user_prefs::PrefRegistrySyncable* registry) {
78 registry->RegisterDictionaryPref(prefs::kGoogleDSEGeolocationSetting); 131 registry->RegisterDictionaryPref(prefs::kGoogleDSEGeolocationSetting);
79 } 132 }
80 133
81 SearchGeolocationService::SearchGeolocationService(Profile* profile) 134 SearchGeolocationService::SearchGeolocationService(Profile* profile)
82 : profile_(profile), 135 : profile_(profile),
83 pref_service_(profile_->GetPrefs()), 136 pref_service_(profile_->GetPrefs()),
84 host_content_settings_map_( 137 host_content_settings_map_(
85 HostContentSettingsMapFactory::GetForProfile(profile_)), 138 HostContentSettingsMapFactory::GetForProfile(profile_)) {
86 template_url_service_( 139 // This class should never be constructed in incognito.
87 TemplateURLServiceFactory::GetForProfile(profile_)) { 140 DCHECK(!profile_->IsOffTheRecord());
141
88 if (!UseConsistentSearchGeolocation()) 142 if (!UseConsistentSearchGeolocation())
89 return; 143 return;
90 144
91 template_url_service_->AddObserver(this); 145 delegate_.reset(new SearchEngineDelegateImpl(profile_));
146 delegate_->SetDSEChangedCallback(base::Bind(
147 &SearchGeolocationService::OnDSEChanged, base::Unretained(this)));
92 148
93 InitializeDSEGeolocationSettingIfNeeded(); 149 InitializeDSEGeolocationSettingIfNeeded();
94 150
95 // Make sure the setting is valid now. It's possible that the setting has 151 // Make sure the setting is valid now. It's possible that the setting has
96 // become invalid either by changes being made to enterprise policy, or while 152 // become invalid either by changes being made to enterprise policy, or while
97 // the flag to enable consistent search geolocation was off. 153 // the flag to enable consistent search geolocation was off.
98 EnsureDSEGeolocationSettingIsValid(); 154 EnsureDSEGeolocationSettingIsValid();
99 } 155 }
100 156
101 bool SearchGeolocationService::UseDSEGeolocationSetting( 157 bool SearchGeolocationService::UseDSEGeolocationSetting(
102 const url::Origin& requesting_origin) { 158 const url::Origin& requesting_origin) {
103 if (!UseConsistentSearchGeolocation()) 159 if (!UseConsistentSearchGeolocation())
104 return false; 160 return false;
105 161
106 if (profile_->IsOffTheRecord())
107 return false;
108
109 if (requesting_origin.scheme() != url::kHttpsScheme) 162 if (requesting_origin.scheme() != url::kHttpsScheme)
110 return false; 163 return false;
111 164
112 if (!requesting_origin.IsSameOriginWith(GetDSECCTLD())) 165 if (!requesting_origin.IsSameOriginWith(delegate_->GetGoogleDSECCTLD()))
113 return false; 166 return false;
114 167
115 // If the content setting for the DSE CCTLD is controlled by policy, and is st 168 // If the content setting for the DSE CCTLD is controlled by policy, and is st
116 // to ASK, don't use the DSE geolocation setting. 169 // to ASK, don't use the DSE geolocation setting.
117 if (!IsContentSettingUserSettable() && 170 if (!IsContentSettingUserSettable() &&
118 GetCurrentContentSetting() == CONTENT_SETTING_ASK) { 171 GetCurrentContentSetting() == CONTENT_SETTING_ASK) {
119 return false; 172 return false;
120 } 173 }
121 174
122 return true; 175 return true;
123 } 176 }
124 177
125 bool SearchGeolocationService::GetDSEGeolocationSetting() { 178 bool SearchGeolocationService::GetDSEGeolocationSetting() {
126 // Make sure the setting is valid, in case enterprise policy has changed. 179 // Make sure the setting is valid, in case enterprise policy has changed.
127 // TODO(benwells): Check if enterprise policy can change while Chrome is 180 // TODO(benwells): Check if enterprise policy can change while Chrome is
128 // running. If it can't this call is probably not needed. 181 // running. If it can't this call is probably not needed.
129 EnsureDSEGeolocationSettingIsValid(); 182 EnsureDSEGeolocationSettingIsValid();
130 183
131 return GetDSEGeolocationPref().setting; 184 return GetDSEGeolocationPref().setting;
132 } 185 }
133 186
134 void SearchGeolocationService::SetDSEGeolocationSetting(bool setting) { 187 void SearchGeolocationService::SetDSEGeolocationSetting(bool setting) {
188 DCHECK(delegate_->IsDSEGoogle());
135 PrefValue pref = GetDSEGeolocationPref(); 189 PrefValue pref = GetDSEGeolocationPref();
136 if (setting == pref.setting) 190 if (setting == pref.setting)
137 return; 191 return;
138 192
139 // If the user cannot change their geolocation content setting (e.g. due to 193 // If the user cannot change their geolocation content setting (e.g. due to
140 // enterprise policy), they also can't change this preference so just bail 194 // enterprise policy), they also can't change this preference so just bail
141 // out. 195 // out.
142 if (!IsContentSettingUserSettable()) 196 if (!IsContentSettingUserSettable())
143 return; 197 return;
144 198
145 pref.setting = setting; 199 pref.setting = setting;
146 SetDSEGeolocationPref(pref); 200 SetDSEGeolocationPref(pref);
147 201
148 ResetContentSetting(); 202 ResetContentSetting();
149 } 203 }
150 204
151 void SearchGeolocationService::Shutdown() { 205 void SearchGeolocationService::Shutdown() {
152 if (UseConsistentSearchGeolocation()) 206 delegate_.reset();
153 template_url_service_->RemoveObserver(this);
154 } 207 }
155 208
156 SearchGeolocationService::~SearchGeolocationService() {} 209 SearchGeolocationService::~SearchGeolocationService() {}
157 210
158 void SearchGeolocationService::OnTemplateURLServiceChanged() { 211 void SearchGeolocationService::OnDSEChanged() {
159 bool is_now_google_search_engine = IsGoogleSearchEngine(); 212 bool is_now_google_search_engine = delegate_->IsDSEGoogle();
160 PrefValue pref = GetDSEGeolocationPref(); 213 PrefValue pref = GetDSEGeolocationPref();
161 ContentSetting content_setting = GetCurrentContentSetting(); 214 ContentSetting content_setting = GetCurrentContentSetting();
162 215
163 if (is_now_google_search_engine) { 216 if (is_now_google_search_engine) {
164 if (content_setting == CONTENT_SETTING_BLOCK && pref.setting) { 217 if (content_setting == CONTENT_SETTING_BLOCK && pref.setting) {
165 pref.setting = false; 218 pref.setting = false;
166 } else if (content_setting == CONTENT_SETTING_ALLOW && !pref.setting) { 219 } else if (content_setting == CONTENT_SETTING_ALLOW && !pref.setting) {
167 ResetContentSetting(); 220 ResetContentSetting();
168 } 221 }
169 } 222 }
170 223
171 if (is_now_google_search_engine && !pref.is_google_search_engine && 224 if (is_now_google_search_engine && !pref.is_google_search_engine &&
172 pref.setting) { 225 pref.setting) {
173 SearchGeolocationDisclosureTabHelper::ResetDisclosure(profile_); 226 SearchGeolocationDisclosureTabHelper::ResetDisclosure(profile_);
174 } 227 }
175 228
176 pref.is_google_search_engine = is_now_google_search_engine; 229 pref.is_google_search_engine = is_now_google_search_engine;
177 pref.cctld = GetDSECCTLD();
178 SetDSEGeolocationPref(pref); 230 SetDSEGeolocationPref(pref);
179 } 231 }
180 232
181 void SearchGeolocationService::InitializeDSEGeolocationSettingIfNeeded() { 233 void SearchGeolocationService::InitializeDSEGeolocationSettingIfNeeded() {
182 // Initialize the pref if it hasn't been initialized yet. 234 // Initialize the pref if it hasn't been initialized yet.
183 if (!pref_service_->HasPrefPath(prefs::kGoogleDSEGeolocationSetting)) { 235 if (!pref_service_->HasPrefPath(prefs::kGoogleDSEGeolocationSetting)) {
184 ContentSetting content_setting = GetCurrentContentSetting(); 236 ContentSetting content_setting = GetCurrentContentSetting();
185 237
186 PrefValue pref; 238 PrefValue pref;
187 pref.is_google_search_engine = IsGoogleSearchEngine(); 239 pref.is_google_search_engine = delegate_->IsDSEGoogle();
188 pref.cctld = GetDSECCTLD();
189 pref.setting = content_setting != CONTENT_SETTING_BLOCK; 240 pref.setting = content_setting != CONTENT_SETTING_BLOCK;
190 SetDSEGeolocationPref(pref); 241 SetDSEGeolocationPref(pref);
191 242
192 SearchGeolocationDisclosureTabHelper::ResetDisclosure(profile_); 243 SearchGeolocationDisclosureTabHelper::ResetDisclosure(profile_);
193 } 244 }
194 } 245 }
195 246
196 void SearchGeolocationService::EnsureDSEGeolocationSettingIsValid() { 247 void SearchGeolocationService::EnsureDSEGeolocationSettingIsValid() {
197 PrefValue pref = GetDSEGeolocationPref(); 248 PrefValue pref = GetDSEGeolocationPref();
198 ContentSetting content_setting = GetCurrentContentSetting(); 249 ContentSetting content_setting = GetCurrentContentSetting();
199 bool new_setting = pref.setting; 250 bool new_setting = pref.setting;
200 251
201 if (pref.setting && content_setting == CONTENT_SETTING_BLOCK) { 252 if (pref.setting && content_setting == CONTENT_SETTING_BLOCK) {
202 new_setting = false; 253 new_setting = false;
203 } else if (!pref.setting && content_setting == CONTENT_SETTING_ALLOW) { 254 } else if (!pref.setting && content_setting == CONTENT_SETTING_ALLOW) {
204 new_setting = true; 255 new_setting = true;
205 } 256 }
206 257
207 if (pref.setting != new_setting) { 258 if (pref.setting != new_setting) {
208 pref.setting = new_setting; 259 pref.setting = new_setting;
209 SetDSEGeolocationPref(pref); 260 SetDSEGeolocationPref(pref);
210 } 261 }
211 } 262 }
212 263
213 bool SearchGeolocationService::IsGoogleSearchEngine() {
214 const TemplateURL* template_url =
215 template_url_service_->GetDefaultSearchProvider();
216 return template_url &&
217 template_url->HasGoogleBaseURLs(UIThreadSearchTermsData(profile_));
218 }
219
220 url::Origin SearchGeolocationService::GetDSECCTLD() {
221 if (!IsGoogleSearchEngine())
222 return url::Origin();
223
224 GURL origin_url(UIThreadSearchTermsData(profile_).GoogleBaseURLValue());
225 return url::Origin(origin_url);
226 }
227
228 SearchGeolocationService::PrefValue 264 SearchGeolocationService::PrefValue
229 SearchGeolocationService::GetDSEGeolocationPref() { 265 SearchGeolocationService::GetDSEGeolocationPref() {
230 const base::DictionaryValue* dict = 266 const base::DictionaryValue* dict =
231 pref_service_->GetDictionary(prefs::kGoogleDSEGeolocationSetting); 267 pref_service_->GetDictionary(prefs::kGoogleDSEGeolocationSetting);
232 268
233 PrefValue pref; 269 PrefValue pref;
234 bool is_google_search_engine; 270 bool is_google_search_engine;
235 std::string cctld_string;
236 bool setting; 271 bool setting;
237 if (dict->GetBoolean(kIsGoogleSearchEngineKey, &is_google_search_engine) && 272 if (dict->GetBoolean(kIsGoogleSearchEngineKey, &is_google_search_engine) &&
238 dict->GetString(kCCTLDKey, &cctld_string) &&
239 dict->GetBoolean(kDSESettingKey, &setting)) { 273 dict->GetBoolean(kDSESettingKey, &setting)) {
240 pref.is_google_search_engine = is_google_search_engine; 274 pref.is_google_search_engine = is_google_search_engine;
241 pref.cctld = url::Origin(GURL(cctld_string));
242 pref.setting = setting; 275 pref.setting = setting;
243 } 276 }
244 277
245 return pref; 278 return pref;
246 } 279 }
247 280
248 void SearchGeolocationService::SetDSEGeolocationPref( 281 void SearchGeolocationService::SetDSEGeolocationPref(
249 const SearchGeolocationService::PrefValue& pref) { 282 const SearchGeolocationService::PrefValue& pref) {
250 base::DictionaryValue dict; 283 base::DictionaryValue dict;
251 dict.SetBoolean(kIsGoogleSearchEngineKey, pref.is_google_search_engine); 284 dict.SetBoolean(kIsGoogleSearchEngineKey, pref.is_google_search_engine);
252 dict.SetString(kCCTLDKey, pref.cctld.Serialize());
253 dict.SetBoolean(kDSESettingKey, pref.setting); 285 dict.SetBoolean(kDSESettingKey, pref.setting);
254 pref_service_->Set(prefs::kGoogleDSEGeolocationSetting, dict); 286 pref_service_->Set(prefs::kGoogleDSEGeolocationSetting, dict);
255 } 287 }
256 288
257 ContentSetting SearchGeolocationService::GetCurrentContentSetting() { 289 ContentSetting SearchGeolocationService::GetCurrentContentSetting() {
258 url::Origin origin = GetDSECCTLD(); 290 url::Origin origin = delegate_->GetGoogleDSECCTLD();
259 return host_content_settings_map_->GetContentSetting( 291 return host_content_settings_map_->GetContentSetting(
260 origin.GetURL(), origin.GetURL(), CONTENT_SETTINGS_TYPE_GEOLOCATION, 292 origin.GetURL(), origin.GetURL(), CONTENT_SETTINGS_TYPE_GEOLOCATION,
261 std::string()); 293 std::string());
262 } 294 }
263 295
264 void SearchGeolocationService::ResetContentSetting() { 296 void SearchGeolocationService::ResetContentSetting() {
265 url::Origin origin = GetDSECCTLD(); 297 url::Origin origin = delegate_->GetGoogleDSECCTLD();
266 host_content_settings_map_->SetContentSettingDefaultScope( 298 host_content_settings_map_->SetContentSettingDefaultScope(
267 origin.GetURL(), origin.GetURL(), CONTENT_SETTINGS_TYPE_GEOLOCATION, 299 origin.GetURL(), origin.GetURL(), CONTENT_SETTINGS_TYPE_GEOLOCATION,
268 std::string(), CONTENT_SETTING_DEFAULT); 300 std::string(), CONTENT_SETTING_DEFAULT);
269 } 301 }
270 302
271 bool SearchGeolocationService::IsContentSettingUserSettable() { 303 bool SearchGeolocationService::IsContentSettingUserSettable() {
272 content_settings::SettingInfo info; 304 content_settings::SettingInfo info;
273 url::Origin origin = GetDSECCTLD(); 305 url::Origin origin = delegate_->GetGoogleDSECCTLD();
274 std::unique_ptr<base::Value> value = 306 std::unique_ptr<base::Value> value =
275 host_content_settings_map_->GetWebsiteSetting( 307 host_content_settings_map_->GetWebsiteSetting(
276 origin.GetURL(), origin.GetURL(), CONTENT_SETTINGS_TYPE_GEOLOCATION, 308 origin.GetURL(), origin.GetURL(), CONTENT_SETTINGS_TYPE_GEOLOCATION,
277 std::string(), &info); 309 std::string(), &info);
278 return info.source == content_settings::SETTING_SOURCE_USER; 310 return info.source == content_settings::SETTING_SOURCE_USER;
279 } 311 }
280 312
281 bool SearchGeolocationService::UseConsistentSearchGeolocation() { 313 bool SearchGeolocationService::UseConsistentSearchGeolocation() {
282 return base::FeatureList::IsEnabled(features::kConsistentOmniboxGeolocation); 314 return base::FeatureList::IsEnabled(features::kConsistentOmniboxGeolocation);
283 } 315 }
316
317 void SearchGeolocationService::SetSearchEngineDelegateForTest(
318 std::unique_ptr<SearchEngineDelegate> delegate) {
319 delegate_ = std::move(delegate);
320 delegate_->SetDSEChangedCallback(base::Bind(
321 &SearchGeolocationService::OnDSEChanged, base::Unretained(this)));
322 }
OLDNEW
« no previous file with comments | « chrome/browser/android/search_geolocation/search_geolocation_service.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698