OLD | NEW |
---|---|
(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 } | |
OLD | NEW |