OLD | NEW |
---|---|
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/geolocation/geolocation_permission_context_android.h" | 5 #include "chrome/browser/geolocation/geolocation_permission_context_android.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/feature_list.h" | 11 #include "base/feature_list.h" |
12 #include "base/metrics/histogram_functions.h" | |
12 #include "chrome/browser/android/location_settings.h" | 13 #include "chrome/browser/android/location_settings.h" |
13 #include "chrome/browser/android/location_settings_impl.h" | 14 #include "chrome/browser/android/location_settings_impl.h" |
14 #include "chrome/browser/android/search_geolocation/search_geolocation_disclosur e_tab_helper.h" | 15 #include "chrome/browser/android/search_geolocation/search_geolocation_disclosur e_tab_helper.h" |
15 #include "chrome/browser/android/search_geolocation/search_geolocation_service.h " | 16 #include "chrome/browser/android/search_geolocation/search_geolocation_service.h " |
16 #include "chrome/browser/permissions/permission_request_id.h" | 17 #include "chrome/browser/permissions/permission_request_id.h" |
17 #include "chrome/browser/permissions/permission_update_infobar_delegate_android. h" | 18 #include "chrome/browser/permissions/permission_update_infobar_delegate_android. h" |
18 #include "chrome/browser/profiles/profile.h" | 19 #include "chrome/browser/profiles/profile.h" |
19 #include "chrome/browser/search_engines/template_url_service_factory.h" | 20 #include "chrome/browser/search_engines/template_url_service_factory.h" |
20 #include "chrome/common/chrome_features.h" | 21 #include "chrome/common/chrome_features.h" |
21 #include "chrome/common/pref_names.h" | 22 #include "chrome/common/pref_names.h" |
22 #include "components/infobars/core/infobar.h" | 23 #include "components/infobars/core/infobar.h" |
23 #include "components/prefs/pref_registry_simple.h" | 24 #include "components/prefs/pref_registry_simple.h" |
24 #include "components/prefs/pref_service.h" | 25 #include "components/prefs/pref_service.h" |
25 #include "components/search_engines/template_url.h" | 26 #include "components/search_engines/template_url.h" |
26 #include "components/search_engines/template_url_service.h" | 27 #include "components/search_engines/template_url_service.h" |
27 #include "content/public/browser/browser_thread.h" | 28 #include "content/public/browser/browser_thread.h" |
28 #include "content/public/browser/render_frame_host.h" | 29 #include "content/public/browser/render_frame_host.h" |
29 #include "content/public/browser/web_contents.h" | 30 #include "content/public/browser/web_contents.h" |
30 #include "url/gurl.h" | 31 #include "url/gurl.h" |
31 | 32 |
32 namespace { | 33 namespace { |
33 | 34 |
34 int g_day_offset_for_testing = 0; | 35 int g_day_offset_for_testing = 0; |
36 const char* g_dse_origin_for_testing = nullptr; | |
35 | 37 |
36 const char* g_dse_origin_for_testing = nullptr; | 38 const char kLocationSettingsShowMetricBase[] = |
39 "Geolocation.SettingsDialog.ShowEvent."; | |
40 const char kLocationSettingsSuppressMetricBase[] = | |
41 "Geolocation.SettingsDialog.SuppressEvent."; | |
42 const char kLocationSettingsAcceptMetricBase[] = | |
43 "Geolocation.SettingsDialog.AcceptEvent."; | |
44 const char kLocationSettingsDenyMetricBase[] = | |
45 "Geolocation.SettingsDialog.DenyEvent."; | |
46 | |
47 const char kLocationSettingsMetricDSESuffix[] = "DSE"; | |
48 const char kLocationSettingsMetricNonDSESuffix[] = "NonDSE"; | |
37 | 49 |
38 base::Time GetTimeNow() { | 50 base::Time GetTimeNow() { |
39 return base::Time::Now() + | 51 return base::Time::Now() + |
40 base::TimeDelta::FromDays(g_day_offset_for_testing); | 52 base::TimeDelta::FromDays(g_day_offset_for_testing); |
41 } | 53 } |
42 | 54 |
55 void LogLocationSettingsMetric( | |
56 const std::string& metric_base, | |
57 bool is_default_search, | |
58 GeolocationPermissionContextAndroid::LocationSettingsDialogBackOff | |
59 backoff) { | |
60 std::string metric_name = metric_base; | |
61 if (is_default_search) | |
62 metric_name.append(kLocationSettingsMetricDSESuffix); | |
63 else | |
64 metric_name.append(kLocationSettingsMetricNonDSESuffix); | |
65 | |
66 base::UmaHistogramEnumeration(metric_name, backoff, | |
67 GeolocationPermissionContextAndroid:: | |
68 LocationSettingsDialogBackOff::kCount); | |
69 } | |
70 | |
43 } // namespace | 71 } // namespace |
44 | 72 |
45 // static | 73 // static |
46 void GeolocationPermissionContextAndroid::RegisterProfilePrefs( | 74 void GeolocationPermissionContextAndroid::RegisterProfilePrefs( |
47 PrefRegistrySimple* registry) { | 75 PrefRegistrySimple* registry) { |
48 registry->RegisterIntegerPref(prefs::kLocationSettingsBackoffLevelDSE, 0); | 76 registry->RegisterIntegerPref(prefs::kLocationSettingsBackoffLevelDSE, 0); |
49 registry->RegisterIntegerPref(prefs::kLocationSettingsBackoffLevelDefault, 0); | 77 registry->RegisterIntegerPref(prefs::kLocationSettingsBackoffLevelDefault, 0); |
50 registry->RegisterInt64Pref(prefs::kLocationSettingsNextShowDSE, 0); | 78 registry->RegisterInt64Pref(prefs::kLocationSettingsNextShowDSE, 0); |
51 registry->RegisterInt64Pref(prefs::kLocationSettingsNextShowDefault, 0); | 79 registry->RegisterInt64Pref(prefs::kLocationSettingsNextShowDefault, 0); |
52 } | 80 } |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
166 } | 194 } |
167 | 195 |
168 void GeolocationPermissionContextAndroid::UserMadePermissionDecision( | 196 void GeolocationPermissionContextAndroid::UserMadePermissionDecision( |
169 const PermissionRequestID& id, | 197 const PermissionRequestID& id, |
170 const GURL& requesting_origin, | 198 const GURL& requesting_origin, |
171 const GURL& embedding_origin, | 199 const GURL& embedding_origin, |
172 ContentSetting content_setting) { | 200 ContentSetting content_setting) { |
173 // If the user has accepted geolocation, reset the location settings dialog | 201 // If the user has accepted geolocation, reset the location settings dialog |
174 // backoff. | 202 // backoff. |
175 if (content_setting == CONTENT_SETTING_ALLOW) | 203 if (content_setting == CONTENT_SETTING_ALLOW) |
176 ResetLocationSettingsBackOff(requesting_origin); | 204 ResetLocationSettingsBackOff(IsRequestingOriginDSE(requesting_origin)); |
177 } | 205 } |
178 | 206 |
179 void GeolocationPermissionContextAndroid::NotifyPermissionSet( | 207 void GeolocationPermissionContextAndroid::NotifyPermissionSet( |
180 const PermissionRequestID& id, | 208 const PermissionRequestID& id, |
181 const GURL& requesting_origin, | 209 const GURL& requesting_origin, |
182 const GURL& embedding_origin, | 210 const GURL& embedding_origin, |
183 const BrowserPermissionCallback& callback, | 211 const BrowserPermissionCallback& callback, |
184 bool persist, | 212 bool persist, |
185 ContentSetting content_setting) { | 213 ContentSetting content_setting) { |
214 bool is_default_search = IsRequestingOriginDSE(requesting_origin); | |
186 if (content_setting == CONTENT_SETTING_ALLOW && | 215 if (content_setting == CONTENT_SETTING_ALLOW && |
187 !location_settings_->IsSystemLocationSettingEnabled()) { | 216 !location_settings_->IsSystemLocationSettingEnabled()) { |
188 // There is no need to check CanShowLocationSettingsDialog here again, as it | 217 // There is no need to check CanShowLocationSettingsDialog here again, as it |
189 // must have been checked to get this far. But, the backoff will not have | 218 // must have been checked to get this far. But, the backoff will not have |
190 // been checked, so check that. Backoff isn't checked earlier because if the | 219 // been checked, so check that. Backoff isn't checked earlier because if the |
191 // content setting is ASK the backoff should be ignored. However if we get | 220 // content setting is ASK the backoff should be ignored. However if we get |
192 // here and the content setting was ASK, the user must have accepted which | 221 // here and the content setting was ASK, the user must have accepted which |
193 // would reset the backoff. | 222 // would reset the backoff. |
194 if (IsInLocationSettingsBackOff(requesting_origin)) { | 223 if (IsInLocationSettingsBackOff(is_default_search)) { |
195 FinishNotifyPermissionSet(id, requesting_origin, embedding_origin, | 224 FinishNotifyPermissionSet(id, requesting_origin, embedding_origin, |
196 callback, false /* persist */, | 225 callback, false /* persist */, |
197 CONTENT_SETTING_BLOCK); | 226 CONTENT_SETTING_BLOCK); |
227 LogLocationSettingsMetric( | |
228 kLocationSettingsSuppressMetricBase, is_default_search, | |
229 LocationSettingsBackOffLevel(is_default_search)); | |
198 return; | 230 return; |
199 } | 231 } |
200 | 232 |
233 LogLocationSettingsMetric(kLocationSettingsShowMetricBase, | |
234 is_default_search, | |
235 LocationSettingsBackOffLevel(is_default_search)); | |
201 content::WebContents* web_contents = | 236 content::WebContents* web_contents = |
202 content::WebContents::FromRenderFrameHost( | 237 content::WebContents::FromRenderFrameHost( |
203 content::RenderFrameHost::FromID(id.render_process_id(), | 238 content::RenderFrameHost::FromID(id.render_process_id(), |
204 id.render_frame_id())); | 239 id.render_frame_id())); |
205 location_settings_->PromptToEnableSystemLocationSetting( | 240 location_settings_->PromptToEnableSystemLocationSetting( |
206 IsRequestingOriginDSE(requesting_origin) ? SEARCH : DEFAULT, | 241 is_default_search ? SEARCH : DEFAULT, web_contents, |
207 web_contents, | |
208 base::BindOnce( | 242 base::BindOnce( |
209 &GeolocationPermissionContextAndroid::OnLocationSettingsDialogShown, | 243 &GeolocationPermissionContextAndroid::OnLocationSettingsDialogShown, |
210 weak_factory_.GetWeakPtr(), id, requesting_origin, embedding_origin, | 244 weak_factory_.GetWeakPtr(), id, requesting_origin, embedding_origin, |
211 callback, persist, content_setting)); | 245 callback, persist, content_setting)); |
212 return; | 246 return; |
213 } | 247 } |
214 | 248 |
215 FinishNotifyPermissionSet(id, requesting_origin, embedding_origin, callback, | 249 FinishNotifyPermissionSet(id, requesting_origin, embedding_origin, callback, |
216 persist, content_setting); | 250 persist, content_setting); |
217 } | 251 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
252 result.content_setting = CONTENT_SETTING_ASK; | 286 result.content_setting = CONTENT_SETTING_ASK; |
253 result.source = PermissionStatusSource::UNSPECIFIED; | 287 result.source = PermissionStatusSource::UNSPECIFIED; |
254 } | 288 } |
255 } | 289 } |
256 | 290 |
257 return result; | 291 return result; |
258 } | 292 } |
259 | 293 |
260 std::string | 294 std::string |
261 GeolocationPermissionContextAndroid::GetLocationSettingsBackOffLevelPref( | 295 GeolocationPermissionContextAndroid::GetLocationSettingsBackOffLevelPref( |
262 const GURL& requesting_origin) const { | 296 bool is_default_search) const { |
263 if (IsRequestingOriginDSE(requesting_origin)) | 297 return is_default_search ? prefs::kLocationSettingsBackoffLevelDSE |
264 return prefs::kLocationSettingsBackoffLevelDSE; | 298 : prefs::kLocationSettingsBackoffLevelDefault; |
265 | |
266 return prefs::kLocationSettingsBackoffLevelDefault; | |
267 } | 299 } |
268 | 300 |
269 std::string | 301 std::string |
270 GeolocationPermissionContextAndroid::GetLocationSettingsNextShowPref( | 302 GeolocationPermissionContextAndroid::GetLocationSettingsNextShowPref( |
271 const GURL& requesting_origin) const { | 303 bool is_default_search) const { |
272 if (IsRequestingOriginDSE(requesting_origin)) | 304 return is_default_search ? prefs::kLocationSettingsNextShowDSE |
273 return prefs::kLocationSettingsNextShowDSE; | 305 : prefs::kLocationSettingsNextShowDefault; |
274 | |
275 return prefs::kLocationSettingsNextShowDefault; | |
276 } | 306 } |
277 | 307 |
278 bool GeolocationPermissionContextAndroid::IsInLocationSettingsBackOff( | 308 bool GeolocationPermissionContextAndroid::IsInLocationSettingsBackOff( |
279 const GURL& requesting_origin) const { | 309 bool is_default_search) const { |
280 base::Time next_show = | 310 base::Time next_show = |
281 base::Time::FromInternalValue(profile()->GetPrefs()->GetInt64( | 311 base::Time::FromInternalValue(profile()->GetPrefs()->GetInt64( |
282 GetLocationSettingsNextShowPref(requesting_origin))); | 312 GetLocationSettingsNextShowPref(is_default_search))); |
283 | 313 |
284 return GetTimeNow() < next_show; | 314 return GetTimeNow() < next_show; |
285 } | 315 } |
286 | 316 |
287 void GeolocationPermissionContextAndroid::ResetLocationSettingsBackOff( | 317 void GeolocationPermissionContextAndroid::ResetLocationSettingsBackOff( |
288 const GURL& requesting_origin) { | 318 bool is_default_search) { |
289 PrefService* prefs = profile()->GetPrefs(); | 319 PrefService* prefs = profile()->GetPrefs(); |
290 prefs->ClearPref(GetLocationSettingsNextShowPref(requesting_origin)); | 320 prefs->ClearPref(GetLocationSettingsNextShowPref(is_default_search)); |
291 prefs->ClearPref(GetLocationSettingsBackOffLevelPref(requesting_origin)); | 321 prefs->ClearPref(GetLocationSettingsBackOffLevelPref(is_default_search)); |
292 } | 322 } |
293 | 323 |
294 void GeolocationPermissionContextAndroid::UpdateLocationSettingsBackOff( | 324 void GeolocationPermissionContextAndroid::UpdateLocationSettingsBackOff( |
295 const GURL& requesting_origin) { | 325 bool is_default_search) { |
296 // Backoff levels: | 326 LocationSettingsDialogBackOff backoff_level = |
297 // 0: 1 week | 327 LocationSettingsBackOffLevel(is_default_search); |
298 // 1: 1 month | |
299 // 2: 3 months | |
300 PrefService* prefs = profile()->GetPrefs(); | |
301 int backoff_level = | |
302 prefs->GetInteger(GetLocationSettingsBackOffLevelPref(requesting_origin)); | |
303 | 328 |
304 base::Time next_show = GetTimeNow(); | 329 base::Time next_show = GetTimeNow(); |
305 switch (backoff_level) { | 330 switch (backoff_level) { |
306 case 0: | 331 case LocationSettingsDialogBackOff::kNoBackOff: |
332 backoff_level = LocationSettingsDialogBackOff::kOneWeek; | |
307 next_show += base::TimeDelta::FromDays(7); | 333 next_show += base::TimeDelta::FromDays(7); |
308 break; | 334 break; |
309 case 1: | 335 case LocationSettingsDialogBackOff::kOneWeek: |
336 backoff_level = LocationSettingsDialogBackOff::kOneMonth; | |
310 next_show += base::TimeDelta::FromDays(30); | 337 next_show += base::TimeDelta::FromDays(30); |
311 break; | 338 break; |
339 case LocationSettingsDialogBackOff::kOneMonth: | |
340 backoff_level = LocationSettingsDialogBackOff::kThreeMonths; | |
341 // fall through | |
raymes
2017/04/04 22:35:36
nit: // Fall through.
I'd tend to write the longha
| |
342 case LocationSettingsDialogBackOff::kThreeMonths: | |
343 next_show += base::TimeDelta::FromDays(90); | |
344 break; | |
312 default: | 345 default: |
313 next_show += base::TimeDelta::FromDays(90); | 346 NOTREACHED(); |
314 } | 347 } |
315 | 348 |
316 if (backoff_level < 2) | 349 PrefService* prefs = profile()->GetPrefs(); |
317 backoff_level++; | 350 prefs->SetInteger(GetLocationSettingsBackOffLevelPref(is_default_search), |
351 static_cast<int>(backoff_level)); | |
352 prefs->SetInt64(GetLocationSettingsNextShowPref(is_default_search), | |
353 next_show.ToInternalValue()); | |
354 } | |
318 | 355 |
319 prefs->SetInteger(GetLocationSettingsBackOffLevelPref(requesting_origin), | 356 GeolocationPermissionContextAndroid::LocationSettingsDialogBackOff |
320 backoff_level); | 357 GeolocationPermissionContextAndroid::LocationSettingsBackOffLevel( |
321 prefs->SetInt64(GetLocationSettingsNextShowPref(requesting_origin), | 358 bool is_default_search) const { |
322 next_show.ToInternalValue()); | 359 PrefService* prefs = profile()->GetPrefs(); |
360 int int_backoff = | |
361 prefs->GetInteger(GetLocationSettingsBackOffLevelPref(is_default_search)); | |
362 return static_cast<LocationSettingsDialogBackOff>(int_backoff); | |
323 } | 363 } |
324 | 364 |
325 bool GeolocationPermissionContextAndroid::IsLocationAccessPossible( | 365 bool GeolocationPermissionContextAndroid::IsLocationAccessPossible( |
326 content::WebContents* web_contents, | 366 content::WebContents* web_contents, |
327 const GURL& requesting_origin, | 367 const GURL& requesting_origin, |
328 bool user_gesture) { | 368 bool user_gesture) { |
329 return (location_settings_->HasAndroidLocationPermission() || | 369 return (location_settings_->HasAndroidLocationPermission() || |
330 location_settings_->CanPromptForAndroidLocationPermission( | 370 location_settings_->CanPromptForAndroidLocationPermission( |
331 web_contents)) && | 371 web_contents)) && |
332 (location_settings_->IsSystemLocationSettingEnabled() || | 372 (location_settings_->IsSystemLocationSettingEnabled() || |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
372 false /* persist */, new_setting); | 412 false /* persist */, new_setting); |
373 } | 413 } |
374 | 414 |
375 bool GeolocationPermissionContextAndroid::CanShowLocationSettingsDialog( | 415 bool GeolocationPermissionContextAndroid::CanShowLocationSettingsDialog( |
376 const GURL& requesting_origin, | 416 const GURL& requesting_origin, |
377 bool user_gesture, | 417 bool user_gesture, |
378 bool ignore_backoff) const { | 418 bool ignore_backoff) const { |
379 if (!base::FeatureList::IsEnabled(features::kLsdPermissionPrompt)) | 419 if (!base::FeatureList::IsEnabled(features::kLsdPermissionPrompt)) |
380 return false; | 420 return false; |
381 | 421 |
422 bool is_default_search = IsRequestingOriginDSE(requesting_origin); | |
382 // If this isn't the default search engine, a gesture is needed. | 423 // If this isn't the default search engine, a gesture is needed. |
383 if (!IsRequestingOriginDSE(requesting_origin) && !user_gesture) { | 424 if (!is_default_search && !user_gesture) { |
384 return false; | 425 return false; |
385 } | 426 } |
386 | 427 |
387 if (!ignore_backoff && IsInLocationSettingsBackOff(requesting_origin)) | 428 if (!ignore_backoff && IsInLocationSettingsBackOff(is_default_search)) |
388 return false; | 429 return false; |
389 | 430 |
390 return location_settings_->CanPromptToEnableSystemLocationSetting(); | 431 return location_settings_->CanPromptToEnableSystemLocationSetting(); |
391 } | 432 } |
392 | 433 |
393 void GeolocationPermissionContextAndroid::OnLocationSettingsDialogShown( | 434 void GeolocationPermissionContextAndroid::OnLocationSettingsDialogShown( |
394 const PermissionRequestID& id, | 435 const PermissionRequestID& id, |
395 const GURL& requesting_origin, | 436 const GURL& requesting_origin, |
396 const GURL& embedding_origin, | 437 const GURL& embedding_origin, |
397 const BrowserPermissionCallback& callback, | 438 const BrowserPermissionCallback& callback, |
398 bool persist, | 439 bool persist, |
399 ContentSetting content_setting, | 440 ContentSetting content_setting, |
400 LocationSettingsDialogOutcome prompt_outcome) { | 441 LocationSettingsDialogOutcome prompt_outcome) { |
442 bool is_default_search = IsRequestingOriginDSE(requesting_origin); | |
401 if (prompt_outcome == GRANTED) { | 443 if (prompt_outcome == GRANTED) { |
402 ResetLocationSettingsBackOff(requesting_origin); | 444 LogLocationSettingsMetric(kLocationSettingsAcceptMetricBase, |
445 is_default_search, | |
446 LocationSettingsBackOffLevel(is_default_search)); | |
447 ResetLocationSettingsBackOff(is_default_search); | |
403 } else { | 448 } else { |
404 UpdateLocationSettingsBackOff(requesting_origin); | 449 LogLocationSettingsMetric(kLocationSettingsDenyMetricBase, |
450 is_default_search, | |
451 LocationSettingsBackOffLevel(is_default_search)); | |
452 UpdateLocationSettingsBackOff(is_default_search); | |
405 content_setting = CONTENT_SETTING_BLOCK; | 453 content_setting = CONTENT_SETTING_BLOCK; |
406 persist = false; | 454 persist = false; |
407 } | 455 } |
408 | 456 |
409 FinishNotifyPermissionSet(id, requesting_origin, embedding_origin, callback, | 457 FinishNotifyPermissionSet(id, requesting_origin, embedding_origin, callback, |
410 persist, content_setting); | 458 persist, content_setting); |
411 } | 459 } |
412 | 460 |
413 void GeolocationPermissionContextAndroid::FinishNotifyPermissionSet( | 461 void GeolocationPermissionContextAndroid::FinishNotifyPermissionSet( |
414 const PermissionRequestID& id, | 462 const PermissionRequestID& id, |
(...skipping 22 matching lines...) Expand all Loading... | |
437 // The tab helper can be null in tests. | 485 // The tab helper can be null in tests. |
438 if (disclosure_helper) | 486 if (disclosure_helper) |
439 disclosure_helper->MaybeShowDisclosure(requesting_origin); | 487 disclosure_helper->MaybeShowDisclosure(requesting_origin); |
440 } | 488 } |
441 } | 489 } |
442 | 490 |
443 void GeolocationPermissionContextAndroid::SetLocationSettingsForTesting( | 491 void GeolocationPermissionContextAndroid::SetLocationSettingsForTesting( |
444 std::unique_ptr<LocationSettings> settings) { | 492 std::unique_ptr<LocationSettings> settings) { |
445 location_settings_ = std::move(settings); | 493 location_settings_ = std::move(settings); |
446 } | 494 } |
OLD | NEW |