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

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

Issue 2612993002: Make geolocation API and X-Geo header access consistent (Closed)
Patch Set: Fix test / merge error 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/android/search_geolocation/search_geolocation_service.h "
6
7 #include "base/feature_list.h"
8 #include "base/values.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"
11 #include "chrome/browser/profiles/profile.h"
12 #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/common/chrome_features.h"
15 #include "chrome/common/pref_names.h"
16 #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/common/content_settings_types.h"
19 #include "components/keyed_service/content/browser_context_dependency_manager.h"
20 #include "components/pref_registry/pref_registry_syncable.h"
21 #include "components/prefs/pref_service.h"
22 #include "components/search_engines/template_url.h"
23 #include "components/search_engines/template_url_service.h"
24 #include "url/gurl.h"
25 #include "url/url_constants.h"
26
27 namespace {
28
29 const char kIsGoogleSearchEngineKey[] = "is_google_search_engine";
30 const char kCCTLDKey[] = "cctld";
31 const char kDSESettingKey[] = "dse_setting";
32
33 } // namespace
34
35 struct SearchGeolocationService::PrefValue {
36 bool is_google_search_engine = false;
37 url::Origin cctld;
38 bool setting = false;
39 };
40
41 // static
42 SearchGeolocationService*
43 SearchGeolocationService::Factory::GetForBrowserContext(
44 content::BrowserContext* context) {
45 return static_cast<SearchGeolocationService*>(GetInstance()
46 ->GetServiceForBrowserContext(context, true));
47 }
48
49 // static
50 SearchGeolocationService::Factory*
51 SearchGeolocationService::Factory::GetInstance() {
52 return base::Singleton<SearchGeolocationService::Factory>::get();
53 }
54
55 SearchGeolocationService::Factory::Factory()
56 : BrowserContextKeyedServiceFactory(
57 "SearchGeolocationService",
58 BrowserContextDependencyManager::GetInstance()) {
59 DependsOn(HostContentSettingsMapFactory::GetInstance());
60 DependsOn(TemplateURLServiceFactory::GetInstance());
61 }
62
63 SearchGeolocationService::Factory::~Factory() {}
64
65 bool SearchGeolocationService::Factory::ServiceIsCreatedWithBrowserContext()
66 const {
67 return true;
68 }
69
70 KeyedService* SearchGeolocationService::Factory::BuildServiceInstanceFor(
71 content::BrowserContext* context) const {
72 return new SearchGeolocationService(Profile::FromBrowserContext(context));
73 }
74
75 // static
76 void SearchGeolocationService::RegisterProfilePrefs(
77 user_prefs::PrefRegistrySyncable* registry) {
78 registry->RegisterDictionaryPref(prefs::kGoogleDSEGeolocationSetting);
79 }
80
81 SearchGeolocationService::SearchGeolocationService(Profile* profile)
82 : profile_(profile),
83 pref_service_(profile_->GetPrefs()),
84 host_content_settings_map_(
85 HostContentSettingsMapFactory::GetForProfile(profile_)),
86 template_url_service_(
87 TemplateURLServiceFactory::GetForProfile(profile_)) {
88 if (!UseConsistentSearchGeolocation())
89 return;
90
91 template_url_service_->AddObserver(this);
92
93 InitializeDSEGeolocationSettingIfNeeded();
94
95 // 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
97 // the flag to enable consistent search geolocation was off.
98 EnsureDSEGeolocationSettingIsValid();
99 }
100
101 bool SearchGeolocationService::UseDSEGeolocationSetting(
102 const url::Origin& requesting_origin) {
103 if (!UseConsistentSearchGeolocation())
104 return false;
105
106 if (profile_->IsOffTheRecord())
107 return false;
108
109 if (requesting_origin.scheme() != url::kHttpsScheme)
110 return false;
111
112 if (!requesting_origin.IsSameOriginWith(GetDSECCTLD()))
113 return false;
114
115 // 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.
117 if (!IsContentSettingUserSettable() &&
118 GetCurrentContentSetting() == CONTENT_SETTING_ASK) {
119 return false;
120 }
121
122 return true;
123 }
124
125 bool SearchGeolocationService::GetDSEGeolocationSetting() {
126 // Make sure the setting is valid, in case enterprise policy has changed.
127 // TODO(benwells): Check if enterprise policy can change while Chrome is
128 // running. If it can't this call is probably not needed.
129 EnsureDSEGeolocationSettingIsValid();
130
131 return GetDSEGeolocationPref().setting;
132 }
133
134 void SearchGeolocationService::SetDSEGeolocationSetting(bool setting) {
135 PrefValue pref = GetDSEGeolocationPref();
136 if (setting == pref.setting)
137 return;
138
139 // 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
141 // out.
142 if (!IsContentSettingUserSettable())
143 return;
144
145 pref.setting = setting;
146 SetDSEGeolocationPref(pref);
147
148 ResetContentSetting();
149 }
150
151 void SearchGeolocationService::Shutdown() {
152 if (UseConsistentSearchGeolocation())
153 template_url_service_->RemoveObserver(this);
154 }
155
156 SearchGeolocationService::~SearchGeolocationService() {}
157
158 void SearchGeolocationService::OnTemplateURLServiceChanged() {
159 bool is_now_google_search_engine = IsGoogleSearchEngine();
160 PrefValue pref = GetDSEGeolocationPref();
161 ContentSetting content_setting = GetCurrentContentSetting();
162
163 if (is_now_google_search_engine) {
164 if (content_setting == CONTENT_SETTING_BLOCK && pref.setting) {
165 pref.setting = false;
166 } else if (content_setting == CONTENT_SETTING_ALLOW && !pref.setting) {
167 ResetContentSetting();
168 }
169 }
170
171 if (is_now_google_search_engine && !pref.is_google_search_engine &&
172 pref.setting) {
173 SearchGeolocationDisclosureTabHelper::ResetDisclosure(profile_);
174 }
175
176 pref.is_google_search_engine = is_now_google_search_engine;
177 pref.cctld = GetDSECCTLD();
178 SetDSEGeolocationPref(pref);
179 }
180
181 void SearchGeolocationService::InitializeDSEGeolocationSettingIfNeeded() {
182 // Initialize the pref if it hasn't been initialized yet.
183 if (!pref_service_->HasPrefPath(prefs::kGoogleDSEGeolocationSetting)) {
184 ContentSetting content_setting = GetCurrentContentSetting();
185
186 PrefValue pref;
187 pref.is_google_search_engine = IsGoogleSearchEngine();
188 pref.cctld = GetDSECCTLD();
189 pref.setting = content_setting != CONTENT_SETTING_BLOCK;
190 SetDSEGeolocationPref(pref);
191
192 SearchGeolocationDisclosureTabHelper::ResetDisclosure(profile_);
193 }
194 }
195
196 void SearchGeolocationService::EnsureDSEGeolocationSettingIsValid() {
197 PrefValue pref = GetDSEGeolocationPref();
198 ContentSetting content_setting = GetCurrentContentSetting();
199 bool new_setting = pref.setting;
200
201 if (pref.setting && content_setting == CONTENT_SETTING_BLOCK) {
202 new_setting = false;
203 } else if (!pref.setting && content_setting == CONTENT_SETTING_ALLOW) {
204 new_setting = true;
205 }
206
207 if (pref.setting != new_setting) {
208 pref.setting = new_setting;
209 SetDSEGeolocationPref(pref);
210 }
211 }
212
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
229 SearchGeolocationService::GetDSEGeolocationPref() {
230 const base::DictionaryValue* dict =
231 pref_service_->GetDictionary(prefs::kGoogleDSEGeolocationSetting);
232
233 PrefValue pref;
234 bool is_google_search_engine;
235 std::string cctld_string;
236 bool setting;
237 if (dict->GetBoolean(kIsGoogleSearchEngineKey, &is_google_search_engine) &&
238 dict->GetString(kCCTLDKey, &cctld_string) &&
239 dict->GetBoolean(kDSESettingKey, &setting)) {
240 pref.is_google_search_engine = is_google_search_engine;
241 pref.cctld = url::Origin(GURL(cctld_string));
242 pref.setting = setting;
243 }
244
245 return pref;
246 }
247
248 void SearchGeolocationService::SetDSEGeolocationPref(
249 const SearchGeolocationService::PrefValue& pref) {
250 base::DictionaryValue dict;
251 dict.SetBoolean(kIsGoogleSearchEngineKey, pref.is_google_search_engine);
252 dict.SetString(kCCTLDKey, pref.cctld.Serialize());
253 dict.SetBoolean(kDSESettingKey, pref.setting);
254 pref_service_->Set(prefs::kGoogleDSEGeolocationSetting, dict);
255 }
256
257 ContentSetting SearchGeolocationService::GetCurrentContentSetting() {
258 url::Origin origin = GetDSECCTLD();
259 return host_content_settings_map_->GetContentSetting(
260 origin.GetURL(), origin.GetURL(), CONTENT_SETTINGS_TYPE_GEOLOCATION,
261 std::string());
262 }
263
264 void SearchGeolocationService::ResetContentSetting() {
265 url::Origin origin = GetDSECCTLD();
266 host_content_settings_map_->SetContentSettingDefaultScope(
267 origin.GetURL(), origin.GetURL(), CONTENT_SETTINGS_TYPE_GEOLOCATION,
268 std::string(), CONTENT_SETTING_DEFAULT);
269 }
270
271 bool SearchGeolocationService::IsContentSettingUserSettable() {
272 content_settings::SettingInfo info;
273 url::Origin origin = GetDSECCTLD();
274 std::unique_ptr<base::Value> value =
275 host_content_settings_map_->GetWebsiteSetting(
276 origin.GetURL(), origin.GetURL(), CONTENT_SETTINGS_TYPE_GEOLOCATION,
277 std::string(), &info);
278 return info.source == content_settings::SETTING_SOURCE_USER;
279 }
280
281 bool SearchGeolocationService::UseConsistentSearchGeolocation() {
282 return base::FeatureList::IsEnabled(features::kConsistentOmniboxGeolocation);
283 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698