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

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

Powered by Google App Engine
This is Rietveld 408576698