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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/android/search_geolocation/search_geolocation_service.cc
diff --git a/chrome/browser/android/search_geolocation/search_geolocation_service.cc b/chrome/browser/android/search_geolocation/search_geolocation_service.cc
new file mode 100644
index 0000000000000000000000000000000000000000..628d616a0776173b8e27ad68f8588457b1332bef
--- /dev/null
+++ b/chrome/browser/android/search_geolocation/search_geolocation_service.cc
@@ -0,0 +1,253 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/android/search_geolocation/search_geolocation_service.h"
+
+#include "base/feature_list.h"
+#include "base/values.h"
+#include "chrome/browser/android/search_geolocation/search_geolocation_disclosure_tab_helper.h"
+#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/search_engines/template_url_service_factory.h"
+#include "chrome/browser/search_engines/ui_thread_search_terms_data.h"
+#include "chrome/common/chrome_features.h"
+#include "chrome/common/pref_names.h"
+#include "components/content_settings/core/browser/content_settings_utils.h"
+#include "components/content_settings/core/browser/host_content_settings_map.h"
+#include "components/content_settings/core/common/content_settings_types.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "components/pref_registry/pref_registry_syncable.h"
+#include "components/prefs/pref_service.h"
+#include "components/search_engines/template_url.h"
+#include "components/search_engines/template_url_service.h"
+#include "url/url_constants.h"
+
+namespace {
+
+const char kIsGoogleSearchEngineKey[] = "is_google_search_engine";
+const char kCCTLDKey[] = "cctld";
+const char kDSESettingKey[] = "dse_setting";
+
+} // namespace
+
+struct SearchGeolocationService::PrefValue {
+ bool is_google_search_engine;
+ url::Origin cctld;
+ bool setting;
+};
+
+// static
+void SearchGeolocationService::RegisterProfilePrefs(
+ user_prefs::PrefRegistrySyncable* registry) {
+ registry->RegisterDictionaryPref(prefs::kGoogleDSEGeolocationSetting);
+}
+
+SearchGeolocationService::SearchGeolocationService(Profile* profile)
+ : profile_(profile),
+ pref_service_(profile_->GetPrefs()),
+ host_content_settings_map_(
+ HostContentSettingsMapFactory::GetForProfile(profile_)),
+ template_url_service_(
+ TemplateURLServiceFactory::GetForProfile(profile_)) {
+ if (!UseConsistentSearchGeolocation())
+ return;
+
+ template_url_service_->AddObserver(this);
+
+ InitializeDSEGeolocationSettingIfNeeded();
+ 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.
+}
+
+bool SearchGeolocationService::UseDSEGeolocationSetting(
+ const url::Origin& requesting_origin) {
+ if (profile_->IsOffTheRecord())
+ return false;
+
+ if (!UseConsistentSearchGeolocation())
+ 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.
+
+ if (requesting_origin.scheme() != url::kHttpsScheme)
+ return false;
+
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 !
+ return requesting_origin.IsSameOriginWith(GetDSECCTLD());
+}
+
+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
+ return GetDSEGeolocationPref().setting;
+}
+
+void SearchGeolocationService::SetDSEGeolocationSetting(bool setting) {
+ PrefValue pref = GetDSEGeolocationPref();
+ if (setting == pref.setting)
+ return;
+
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.
+ pref.setting = setting;
+ SetDSEGeolocationPref(pref);
+
+ ResetContentSetting();
+
+ // The UI layer currently (January 2017) has no knowledge of enterprise
+ // policy, and allows users to edit settings in this state. If the user does
+ // this they may change their DSE geolocation setting when they shouldn't be
+ // able to, so we make sure the state is valid now.
+ EnsureDSEGeolocationSettingIsValid();
+}
+
+void SearchGeolocationService::Shutdown() {
+ if (UseConsistentSearchGeolocation())
+ template_url_service_->RemoveObserver(this);
+}
+
+// static
+SearchGeolocationService*
+SearchGeolocationService::Factory::GetForBrowserContext(
+ content::BrowserContext* context) {
+ return static_cast<SearchGeolocationService*>(GetInstance()
+ ->GetServiceForBrowserContext(context, true));
+}
+
+// static
+SearchGeolocationService::Factory*
+SearchGeolocationService::Factory::GetInstance() {
+ return base::Singleton<SearchGeolocationService::Factory>::get();
+}
+
+SearchGeolocationService::Factory::Factory()
+ : BrowserContextKeyedServiceFactory(
+ "SearchGeolocationService",
+ BrowserContextDependencyManager::GetInstance()) {}
+
+SearchGeolocationService::Factory::~Factory() {}
+
+bool SearchGeolocationService::Factory::ServiceIsCreatedWithBrowserContext()
+ const {
+ return true;
+}
+
+KeyedService* SearchGeolocationService::Factory::BuildServiceInstanceFor(
+ content::BrowserContext* context) const {
+ return new SearchGeolocationService(Profile::FromBrowserContext(context));
+}
+
+SearchGeolocationService::~SearchGeolocationService() {}
+
+void SearchGeolocationService::OnTemplateURLServiceChanged() {
+ bool is_now_google_search_engine = IsGoogleSearchEngine();
+ PrefValue pref = GetDSEGeolocationPref();
+ ContentSetting content_setting = GetCurrentContentSetting();
+
+ if (is_now_google_search_engine) {
+ if (content_setting == CONTENT_SETTING_BLOCK && pref.setting) {
+ pref.setting = false;
+ } else if (content_setting == CONTENT_SETTING_ALLOW && !pref.setting) {
+ ResetContentSetting();
+ }
+ }
+
+ if (is_now_google_search_engine && !pref.is_google_search_engine &&
+ pref.setting) {
+ SearchGeolocationDisclosureTabHelper::ResetDisclosure(profile_);
+ }
+
+ pref.is_google_search_engine = is_now_google_search_engine;
+ pref.cctld = GetDSECCTLD();
+ SetDSEGeolocationPref(pref);
+}
+
+void SearchGeolocationService::InitializeDSEGeolocationSettingIfNeeded() {
+ // 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.
+ if (!pref_service_->HasPrefPath(prefs::kGoogleDSEGeolocationSetting)) {
+ ContentSetting content_setting = GetCurrentContentSetting();
+
+ PrefValue pref;
+ pref.is_google_search_engine = IsGoogleSearchEngine();
+ pref.cctld = GetDSECCTLD();
+ pref.setting = content_setting != CONTENT_SETTING_BLOCK;
+ SetDSEGeolocationPref(pref);
+
+ SearchGeolocationDisclosureTabHelper::ResetDisclosure(profile_);
+ }
+}
+
+void SearchGeolocationService::EnsureDSEGeolocationSettingIsValid() {
+ PrefValue pref = GetDSEGeolocationPref();
+ ContentSetting content_setting = GetCurrentContentSetting();
+ bool new_setting = pref.setting;
+
+ if (pref.setting && content_setting == CONTENT_SETTING_BLOCK) {
+ new_setting = false;
+ } else if (!pref.setting && content_setting == CONTENT_SETTING_ALLOW) {
+ new_setting = true;
+ }
+
+ if (pref.setting != new_setting) {
+ pref.setting = new_setting;
+ SetDSEGeolocationPref(pref);
+ }
+}
+
+bool SearchGeolocationService::IsGoogleSearchEngine() {
+ const TemplateURL* template_url =
+ template_url_service_->GetDefaultSearchProvider();
+ return template_url &&
+ template_url->HasGoogleBaseURLs(UIThreadSearchTermsData(profile_));
+}
+
+url::Origin SearchGeolocationService::GetDSECCTLD() {
+ if (!IsGoogleSearchEngine())
+ return url::Origin();
+
+ GURL origin_url(UIThreadSearchTermsData(profile_).GoogleBaseURLValue());
+ return url::Origin(origin_url);
+}
+
+SearchGeolocationService::PrefValue
+SearchGeolocationService::GetDSEGeolocationPref() {
+ const base::DictionaryValue* dict =
+ pref_service_->GetDictionary(prefs::kGoogleDSEGeolocationSetting);
+
+ PrefValue pref;
+ bool is_google_search_engine;
+ std::string cctld_string;
+ bool setting;
+ if (dict->GetBoolean(kIsGoogleSearchEngineKey, &is_google_search_engine) &&
+ dict->GetString(kCCTLDKey, &cctld_string) &&
+ dict->GetBoolean(kDSESettingKey, &setting)) {
+ pref.is_google_search_engine = is_google_search_engine;
+ pref.cctld = url::Origin(GURL(cctld_string));
+ pref.setting = setting;
+ }
+
+ 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).
+}
+
+void SearchGeolocationService::SetDSEGeolocationPref(
+ const SearchGeolocationService::PrefValue& pref) {
+ base::DictionaryValue dict;
+ dict.SetBoolean(kIsGoogleSearchEngineKey, pref.is_google_search_engine);
+ dict.SetString(kCCTLDKey, pref.cctld.Serialize());
+ dict.SetBoolean(kDSESettingKey, pref.setting);
+ pref_service_->Set(prefs::kGoogleDSEGeolocationSetting, dict);
+}
+
+ContentSetting SearchGeolocationService::GetCurrentContentSetting() {
+ content_settings::SettingInfo info;
+ url::Origin origin = GetDSECCTLD();
+ std::unique_ptr<base::Value> value =
+ 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.
+ origin.GetURL(), origin.GetURL(), CONTENT_SETTINGS_TYPE_GEOLOCATION,
+ std::string(), &info);
+ return content_settings::ValueToContentSetting(value.get());
+}
+
+void SearchGeolocationService::ResetContentSetting() {
+ url::Origin origin = GetDSECCTLD();
+ host_content_settings_map_->SetContentSettingDefaultScope(
+ origin.GetURL(), origin.GetURL(), CONTENT_SETTINGS_TYPE_GEOLOCATION,
+ std::string(), CONTENT_SETTING_DEFAULT);
+}
+
+bool SearchGeolocationService::UseConsistentSearchGeolocation() {
+ return base::FeatureList::IsEnabled(features::kConsistentOmniboxGeolocation);
+}

Powered by Google App Engine
This is Rietveld 408576698