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

Unified Diff: chrome/browser/geolocation/geolocation_permission_context_android.cc

Issue 2742373003: Limit the amount the Location Settings Dialog will be shown to users. (Closed)
Patch Set: Created 3 years, 9 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/geolocation/geolocation_permission_context_android.cc
diff --git a/chrome/browser/geolocation/geolocation_permission_context_android.cc b/chrome/browser/geolocation/geolocation_permission_context_android.cc
index 6630c11551b958b53999b8efdd988ee65775d884..f2d3d8869bc7d9e089e1d5d52c9470cb435bfde3 100644
--- a/chrome/browser/geolocation/geolocation_permission_context_android.cc
+++ b/chrome/browser/geolocation/geolocation_permission_context_android.cc
@@ -18,7 +18,10 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/common/chrome_features.h"
+#include "chrome/common/pref_names.h"
#include "components/infobars/core/infobar.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/pref_service.h"
#include "components/search_engines/template_url.h"
#include "components/search_engines/template_url_service.h"
#include "content/public/browser/browser_thread.h"
@@ -26,6 +29,28 @@
#include "content/public/browser/web_contents.h"
#include "url/gurl.h"
+namespace {
+
+int gDayOffsetForTesting = 0;
+
+bool gHasDSEOriginForTesting = false;
raymes 2017/03/15 04:28:25 Could you just use if (!gDSEOriginForTesting.empt
benwells 2017/03/15 23:10:48 Done.
+GURL gDSEOriginForTesting;
raymes 2017/03/15 04:28:25 I think we avoid non-POD globals because it leads
benwells 2017/03/15 23:10:48 Done.
+
+base::Time GetTimeNow() {
+ return base::Time::Now() + base::TimeDelta::FromDays(gDayOffsetForTesting);
raymes 2017/03/15 04:28:25 A more standard pattern is to store a base::Clock
benwells 2017/03/15 23:10:48 Yep, I know. I think I even added the clock to the
+}
+
+} // namespace
+
+// static
+void GeolocationPermissionContextAndroid::RegisterProfilePrefs(
+ PrefRegistrySimple* registry) {
+ registry->RegisterIntegerPref(prefs::kLocationSettingsBackoffLevelDSE, 0);
+ registry->RegisterIntegerPref(prefs::kLocationSettingsBackoffLevelDefault, 0);
+ registry->RegisterInt64Pref(prefs::kLocationSettingsNextShowDSE, 0);
+ registry->RegisterInt64Pref(prefs::kLocationSettingsNextShowDefault, 0);
+}
+
GeolocationPermissionContextAndroid::
GeolocationPermissionContextAndroid(Profile* profile)
: GeolocationPermissionContext(profile),
@@ -77,6 +102,18 @@ ContentSetting GeolocationPermissionContextAndroid::GetPermissionStatusInternal(
return value;
}
+// static
+void GeolocationPermissionContextAndroid::AddDayOffsetForTesting(int days) {
+ gDayOffsetForTesting += days;
+}
+
+// static
+void GeolocationPermissionContextAndroid::SetDSEOriginForTesting(
+ const GURL& dse_origin) {
+ gHasDSEOriginForTesting = true;
+ gDSEOriginForTesting = dse_origin;
+}
+
void GeolocationPermissionContextAndroid::RequestPermission(
content::WebContents* web_contents,
const PermissionRequestID& id,
@@ -129,6 +166,24 @@ void GeolocationPermissionContextAndroid::CancelPermissionRequest(
GeolocationPermissionContext::CancelPermissionRequest(web_contents, id);
}
+void GeolocationPermissionContextAndroid::PermissionDecided(
+ const PermissionRequestID& id,
+ const GURL& requesting_origin,
+ const GURL& embedding_origin,
+ bool user_gesture,
+ const BrowserPermissionCallback& callback,
+ bool persist,
+ ContentSetting content_setting) {
+ // If the user has accepted geolocation, reset the location settings dialog
+ // backoff.
+ if (content_setting == CONTENT_SETTING_ALLOW)
+ ResetLocationSettingsBackOff(requesting_origin);
+
+ GeolocationPermissionContext::PermissionDecided(
+ id, requesting_origin, embedding_origin, user_gesture, callback, persist,
+ content_setting);
+}
+
void GeolocationPermissionContextAndroid::NotifyPermissionSet(
const PermissionRequestID& id,
const GURL& requesting_origin,
@@ -139,7 +194,15 @@ void GeolocationPermissionContextAndroid::NotifyPermissionSet(
if (content_setting == CONTENT_SETTING_ALLOW &&
!location_settings_->IsSystemLocationSettingEnabled()) {
// There is no need to check CanShowLocationSettingsDialog here again, as it
- // must have been checked to get this far.
+ // must have been checked to get this far. But, the backoff will not have
+ // been checked, so check that.
raymes 2017/03/15 04:28:25 nit: maybe explain why the backoff hasn't been che
benwells 2017/03/15 23:10:48 Done.
+ if (IsInLocationSettingsBackOff(requesting_origin)) {
+ FinishNotifyPermissionSet(id, requesting_origin, embedding_origin,
+ callback, false /* persist */,
+ CONTENT_SETTING_BLOCK);
+ return;
+ }
+
content::WebContents* web_contents =
content::WebContents::FromRenderFrameHost(
content::RenderFrameHost::FromID(id.render_process_id(),
@@ -170,8 +233,11 @@ GeolocationPermissionContextAndroid::UpdatePermissionStatusWithDeviceStatus(
// gesture here. If there is a possibility of PROMPT (i.e. if there is a
// user gesture attached to the later request) that should be returned,
// not BLOCK.
- if (CanShowLocationSettingsDialog(requesting_origin,
- true /* user_gesture */)) {
+ // If the permission is in the ASK state, backoff is ignored.
raymes 2017/03/15 04:28:25 nit: maybe explain why this is the case here? I th
benwells 2017/03/15 23:10:48 Done.
+ if (CanShowLocationSettingsDialog(
+ requesting_origin, true /* user_gesture */,
+ result.content_setting ==
+ CONTENT_SETTING_ASK /* ignore_backoff */)) {
result.content_setting = CONTENT_SETTING_ASK;
} else {
result.content_setting = CONTENT_SETTING_BLOCK;
@@ -191,6 +257,70 @@ GeolocationPermissionContextAndroid::UpdatePermissionStatusWithDeviceStatus(
return result;
}
+std::string
+GeolocationPermissionContextAndroid::LocationSettingsBackOffLevelPref(
+ const GURL& requesting_origin) const {
+ if (GetLocationSettingsDialogContext(requesting_origin) == SEARCH)
+ return prefs::kLocationSettingsBackoffLevelDSE;
+
+ return prefs::kLocationSettingsBackoffLevelDefault;
+}
+
+std::string GeolocationPermissionContextAndroid::LocationSettingsNextShowPref(
+ const GURL& requesting_origin) const {
+ if (GetLocationSettingsDialogContext(requesting_origin) == SEARCH)
+ return prefs::kLocationSettingsNextShowDSE;
+
+ return prefs::kLocationSettingsNextShowDefault;
+}
+
+bool GeolocationPermissionContextAndroid::IsInLocationSettingsBackOff(
+ const GURL& requesting_origin) const {
+ base::Time next_show =
+ base::Time::FromInternalValue(profile()->GetPrefs()->GetInt64(
+ LocationSettingsNextShowPref(requesting_origin)));
+
+ return GetTimeNow() < next_show;
+}
+
+void GeolocationPermissionContextAndroid::ResetLocationSettingsBackOff(
+ const GURL& requesting_origin) {
+ PrefService* prefs = profile()->GetPrefs();
+ prefs->ClearPref(LocationSettingsNextShowPref(requesting_origin));
+ prefs->ClearPref(LocationSettingsBackOffLevelPref(requesting_origin));
+}
+
+void GeolocationPermissionContextAndroid::SetLocationSettingsBackOff(
raymes 2017/03/15 04:28:25 nit: maybe this should be ApplyLocationSettingsBac
benwells 2017/03/15 23:10:49 Done.
+ const GURL& requesting_origin) {
+ // Backoff levels:
+ // 0: 1 week
+ // 1: 1 month
+ // 2: 3 months
+ PrefService* prefs = profile()->GetPrefs();
+ int backoff_level =
+ prefs->GetInteger(LocationSettingsBackOffLevelPref(requesting_origin));
+
+ base::Time next_show = GetTimeNow();
+ switch (backoff_level) {
+ case 0:
+ next_show += base::TimeDelta::FromDays(7);
+ break;
+ case 1:
+ next_show += base::TimeDelta::FromDays(30);
+ break;
+ default:
+ next_show += base::TimeDelta::FromDays(90);
+ }
+
+ if (backoff_level < 2)
+ backoff_level++;
+
+ prefs->SetInteger(LocationSettingsBackOffLevelPref(requesting_origin),
+ backoff_level);
+ prefs->SetInt64(LocationSettingsNextShowPref(requesting_origin),
+ next_show.ToInternalValue());
+}
+
bool GeolocationPermissionContextAndroid::IsLocationAccessPossible(
content::WebContents* web_contents,
const GURL& requesting_origin,
@@ -199,25 +329,32 @@ bool GeolocationPermissionContextAndroid::IsLocationAccessPossible(
location_settings_->CanPromptForAndroidLocationPermission(
web_contents)) &&
(location_settings_->IsSystemLocationSettingEnabled() ||
- CanShowLocationSettingsDialog(requesting_origin, user_gesture));
+ CanShowLocationSettingsDialog(requesting_origin, user_gesture,
+ true /* ignore_backoff */));
}
LocationSettingsDialogContext
GeolocationPermissionContextAndroid::GetLocationSettingsDialogContext(
raymes 2017/03/15 04:28:25 nit: I wonder if this is more clearly framed as I
benwells 2017/03/15 23:10:48 Done.
const GURL& requesting_origin) const {
bool is_dse_origin = false;
- TemplateURLService* template_url_service =
- TemplateURLServiceFactory::GetForProfile(profile());
- if (template_url_service) {
- const TemplateURL* template_url =
- template_url_service->GetDefaultSearchProvider();
- if (template_url) {
- GURL search_url = template_url->GenerateSearchURL(
- template_url_service->search_terms_data());
- is_dse_origin = url::IsSameOriginWith(requesting_origin, search_url);
+ GURL dse_url;
+
+ if (gHasDSEOriginForTesting) {
+ dse_url = gDSEOriginForTesting;
+ } else {
+ TemplateURLService* template_url_service =
+ TemplateURLServiceFactory::GetForProfile(profile());
+ if (template_url_service) {
+ const TemplateURL* template_url =
+ template_url_service->GetDefaultSearchProvider();
+ if (template_url) {
+ dse_url = template_url->GenerateSearchURL(
+ template_url_service->search_terms_data());
+ }
}
}
+ is_dse_origin = url::IsSameOriginWith(requesting_origin, dse_url);
return is_dse_origin ? SEARCH : DEFAULT;
}
@@ -239,7 +376,8 @@ void GeolocationPermissionContextAndroid::HandleUpdateAndroidPermissions(
bool GeolocationPermissionContextAndroid::CanShowLocationSettingsDialog(
const GURL& requesting_origin,
- bool user_gesture) const {
+ bool user_gesture,
+ bool ignore_backoff) const {
if (!base::FeatureList::IsEnabled(features::kLsdPermissionPrompt))
return false;
@@ -249,7 +387,9 @@ bool GeolocationPermissionContextAndroid::CanShowLocationSettingsDialog(
return false;
}
- // TODO(benwells): Also check backoff for |requesting_origin|.
+ if (!ignore_backoff && IsInLocationSettingsBackOff(requesting_origin))
+ return false;
+
return location_settings_->CanPromptToEnableSystemLocationSetting();
}
@@ -261,7 +401,10 @@ void GeolocationPermissionContextAndroid::OnLocationSettingsDialogShown(
bool persist,
ContentSetting content_setting,
LocationSettingsDialogOutcome prompt_outcome) {
- if (prompt_outcome != GRANTED) {
+ if (prompt_outcome == GRANTED) {
+ ResetLocationSettingsBackOff(requesting_origin);
+ } else {
+ SetLocationSettingsBackOff(requesting_origin);
content_setting = CONTENT_SETTING_BLOCK;
persist = false;
}

Powered by Google App Engine
This is Rietveld 408576698