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

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 some things; rebase 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/url_constants.h"
25
26 namespace {
27
28 const char kIsGoogleSearchEngineKey[] = "is_google_search_engine";
29 const char kCCTLDKey[] = "cctld";
30 const char kDSESettingKey[] = "dse_setting";
31
32 } // namespace
33
34 struct SearchGeolocationService::PrefValue {
35 bool is_google_search_engine;
36 url::Origin cctld;
37 bool setting;
38 };
39
40 // static
41 void SearchGeolocationService::RegisterProfilePrefs(
42 user_prefs::PrefRegistrySyncable* registry) {
43 registry->RegisterDictionaryPref(prefs::kGoogleDSEGeolocationSetting);
44 }
45
46 SearchGeolocationService::SearchGeolocationService(Profile* profile)
47 : profile_(profile),
48 pref_service_(profile_->GetPrefs()),
49 host_content_settings_map_(
50 HostContentSettingsMapFactory::GetForProfile(profile_)),
51 template_url_service_(
52 TemplateURLServiceFactory::GetForProfile(profile_)) {
53 if (!UseConsistentSearchGeolocation())
54 return;
55
56 template_url_service_->AddObserver(this);
57
58 InitializeDSEGeolocationSettingIfNeeded();
59 EnsureDSEGeolocationSettingIsValid();
raymes 2017/01/09 05:47:26 It might be worth adding a comment about why this
benwells 2017/01/09 21:02:22 Done.
60 }
61
62 bool SearchGeolocationService::UseDSEGeolocationSetting(
63 const url::Origin& requesting_origin) {
64 if (profile_->IsOffTheRecord())
65 return false;
66
67 if (!UseConsistentSearchGeolocation())
68 return false;
raymes 2017/01/09 05:47:26 nit: should this just be the first check?
benwells 2017/01/09 21:02:22 Done.
69
70 if (requesting_origin.scheme() != url::kHttpsScheme)
71 return false;
72
raymes 2017/01/09 05:47:26 I think we could just add an "IsUserSettable()" ch
benwells 2017/01/09 21:02:22 The enterprise policy could force geolocation on,
raymes 2017/01/10 03:19:32 Hmm, but wouldn't we fall back to using the enterp
benwells 2017/01/11 05:35:32 After our discussion offline, I've made it so if !
73 return requesting_origin.IsSameOriginWith(GetDSECCTLD());
74 }
75
76 bool SearchGeolocationService::GetDSEGeolocationSetting() {
raymes 2017/01/09 05:47:26 I vaguely remember talking about ensuring validity
benwells 2017/01/09 21:02:22 I'm not sure if it's needed or not. I've added in
77 return GetDSEGeolocationPref().setting;
78 }
79
80 void SearchGeolocationService::SetDSEGeolocationSetting(bool setting) {
81 PrefValue pref = GetDSEGeolocationPref();
82 if (setting == pref.setting)
83 return;
84
raymes 2017/01/09 05:47:26 As mentioned, I think I'd prefer having if (!IsUs
benwells 2017/01/09 21:02:22 Done.
85 pref.setting = setting;
86 SetDSEGeolocationPref(pref);
87
88 ResetContentSetting();
89
90 // The UI layer currently (January 2017) has no knowledge of enterprise
91 // policy, and allows users to edit settings in this state. If the user does
92 // this they may change their DSE geolocation setting when they shouldn't be
93 // able to, so we make sure the state is valid now.
94 EnsureDSEGeolocationSettingIsValid();
95 }
96
97 void SearchGeolocationService::Shutdown() {
98 if (UseConsistentSearchGeolocation())
99 template_url_service_->RemoveObserver(this);
100 }
101
102 // static
103 SearchGeolocationService*
104 SearchGeolocationService::Factory::GetForBrowserContext(
105 content::BrowserContext* context) {
106 return static_cast<SearchGeolocationService*>(GetInstance()
107 ->GetServiceForBrowserContext(context, true));
108 }
109
110 // static
111 SearchGeolocationService::Factory*
112 SearchGeolocationService::Factory::GetInstance() {
113 return base::Singleton<SearchGeolocationService::Factory>::get();
114 }
115
116 SearchGeolocationService::Factory::Factory()
117 : BrowserContextKeyedServiceFactory(
118 "SearchGeolocationService",
119 BrowserContextDependencyManager::GetInstance()) {}
120
121 SearchGeolocationService::Factory::~Factory() {}
122
123 bool SearchGeolocationService::Factory::ServiceIsCreatedWithBrowserContext()
124 const {
125 return true;
126 }
127
128 KeyedService* SearchGeolocationService::Factory::BuildServiceInstanceFor(
129 content::BrowserContext* context) const {
130 return new SearchGeolocationService(Profile::FromBrowserContext(context));
131 }
132
133 SearchGeolocationService::~SearchGeolocationService() {}
134
135 void SearchGeolocationService::OnTemplateURLServiceChanged() {
136 bool is_now_google_search_engine = IsGoogleSearchEngine();
137 PrefValue pref = GetDSEGeolocationPref();
138 ContentSetting content_setting = GetCurrentContentSetting();
139
140 if (is_now_google_search_engine) {
141 if (content_setting == CONTENT_SETTING_BLOCK && pref.setting) {
142 pref.setting = false;
143 } else if (content_setting == CONTENT_SETTING_ALLOW && !pref.setting) {
144 ResetContentSetting();
145 }
146 }
147
148 if (is_now_google_search_engine && !pref.is_google_search_engine &&
149 pref.setting) {
150 SearchGeolocationDisclosureTabHelper::ResetDisclosure(profile_);
151 }
152
153 pref.is_google_search_engine = is_now_google_search_engine;
154 pref.cctld = GetDSECCTLD();
155 SetDSEGeolocationPref(pref);
156 }
157
158 void SearchGeolocationService::InitializeDSEGeolocationSettingIfNeeded() {
159 // Initialize the pref if it hasn't been initialize yet.
raymes 2017/01/09 05:47:26 nit: initialized
benwells 2017/01/09 21:02:22 Done.
160 if (!pref_service_->HasPrefPath(prefs::kGoogleDSEGeolocationSetting)) {
161 ContentSetting content_setting = GetCurrentContentSetting();
162
163 PrefValue pref;
164 pref.is_google_search_engine = IsGoogleSearchEngine();
165 pref.cctld = GetDSECCTLD();
166 pref.setting = content_setting != CONTENT_SETTING_BLOCK;
167 SetDSEGeolocationPref(pref);
168
169 SearchGeolocationDisclosureTabHelper::ResetDisclosure(profile_);
170 }
171 }
172
173 void SearchGeolocationService::EnsureDSEGeolocationSettingIsValid() {
174 PrefValue pref = GetDSEGeolocationPref();
175 ContentSetting content_setting = GetCurrentContentSetting();
176 bool new_setting = pref.setting;
177
178 if (pref.setting && content_setting == CONTENT_SETTING_BLOCK) {
179 new_setting = false;
180 } else if (!pref.setting && content_setting == CONTENT_SETTING_ALLOW) {
181 new_setting = true;
182 }
183
184 if (pref.setting != new_setting) {
185 pref.setting = new_setting;
186 SetDSEGeolocationPref(pref);
187 }
188 }
189
190 bool SearchGeolocationService::IsGoogleSearchEngine() {
191 const TemplateURL* template_url =
192 template_url_service_->GetDefaultSearchProvider();
193 return template_url &&
194 template_url->HasGoogleBaseURLs(UIThreadSearchTermsData(profile_));
195 }
196
197 url::Origin SearchGeolocationService::GetDSECCTLD() {
198 if (!IsGoogleSearchEngine())
199 return url::Origin();
200
201 GURL origin_url(UIThreadSearchTermsData(profile_).GoogleBaseURLValue());
202 return url::Origin(origin_url);
203 }
204
205 SearchGeolocationService::PrefValue
206 SearchGeolocationService::GetDSEGeolocationPref() {
207 const base::DictionaryValue* dict =
208 pref_service_->GetDictionary(prefs::kGoogleDSEGeolocationSetting);
209
210 PrefValue pref;
211 bool is_google_search_engine;
212 std::string cctld_string;
213 bool setting;
214 if (dict->GetBoolean(kIsGoogleSearchEngineKey, &is_google_search_engine) &&
215 dict->GetString(kCCTLDKey, &cctld_string) &&
216 dict->GetBoolean(kDSESettingKey, &setting)) {
217 pref.is_google_search_engine = is_google_search_engine;
218 pref.cctld = url::Origin(GURL(cctld_string));
219 pref.setting = setting;
220 }
221
222 return pref;
raymes 2017/01/09 05:47:26 I think the struct will be uninitialized? We could
benwells 2017/01/09 21:02:22 Done (via default values).
223 }
224
225 void SearchGeolocationService::SetDSEGeolocationPref(
226 const SearchGeolocationService::PrefValue& pref) {
227 base::DictionaryValue dict;
228 dict.SetBoolean(kIsGoogleSearchEngineKey, pref.is_google_search_engine);
229 dict.SetString(kCCTLDKey, pref.cctld.Serialize());
230 dict.SetBoolean(kDSESettingKey, pref.setting);
231 pref_service_->Set(prefs::kGoogleDSEGeolocationSetting, dict);
232 }
233
234 ContentSetting SearchGeolocationService::GetCurrentContentSetting() {
235 content_settings::SettingInfo info;
236 url::Origin origin = GetDSECCTLD();
237 std::unique_ptr<base::Value> value =
238 host_content_settings_map_->GetWebsiteSetting(
raymes 2017/01/09 05:47:26 Since you're not using "info" here, you can just c
benwells 2017/01/09 21:02:22 Done.
239 origin.GetURL(), origin.GetURL(), CONTENT_SETTINGS_TYPE_GEOLOCATION,
240 std::string(), &info);
241 return content_settings::ValueToContentSetting(value.get());
242 }
243
244 void SearchGeolocationService::ResetContentSetting() {
245 url::Origin origin = GetDSECCTLD();
246 host_content_settings_map_->SetContentSettingDefaultScope(
247 origin.GetURL(), origin.GetURL(), CONTENT_SETTINGS_TYPE_GEOLOCATION,
248 std::string(), CONTENT_SETTING_DEFAULT);
249 }
250
251 bool SearchGeolocationService::UseConsistentSearchGeolocation() {
252 return base::FeatureList::IsEnabled(features::kConsistentOmniboxGeolocation);
253 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698