| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/permissions/permission_decision_auto_blocker.h" | 5 #include "chrome/browser/permissions/permission_decision_auto_blocker.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/feature_list.h" | 9 #include "base/feature_list.h" |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 // static | 161 // static |
| 162 const char PermissionDecisionAutoBlocker::kPermissionDismissalEmbargoKey[] = | 162 const char PermissionDecisionAutoBlocker::kPermissionDismissalEmbargoKey[] = |
| 163 "dismissal_embargo_days"; | 163 "dismissal_embargo_days"; |
| 164 | 164 |
| 165 // static | 165 // static |
| 166 PermissionDecisionAutoBlocker* PermissionDecisionAutoBlocker::GetForProfile( | 166 PermissionDecisionAutoBlocker* PermissionDecisionAutoBlocker::GetForProfile( |
| 167 Profile* profile) { | 167 Profile* profile) { |
| 168 return PermissionDecisionAutoBlocker::Factory::GetForProfile(profile); | 168 return PermissionDecisionAutoBlocker::Factory::GetForProfile(profile); |
| 169 } | 169 } |
| 170 | 170 |
| 171 PermissionDecisionAutoBlocker::PermissionDecisionAutoBlocker(Profile* profile) | |
| 172 : profile_(profile), | |
| 173 db_manager_(nullptr), | |
| 174 safe_browsing_timeout_(kCheckUrlTimeoutMs), | |
| 175 clock_(new base::DefaultClock()) { | |
| 176 safe_browsing::SafeBrowsingService* sb_service = | |
| 177 g_browser_process->safe_browsing_service(); | |
| 178 if (sb_service) | |
| 179 db_manager_ = sb_service->database_manager(); | |
| 180 } | |
| 181 | |
| 182 PermissionDecisionAutoBlocker::~PermissionDecisionAutoBlocker() {} | |
| 183 | |
| 184 void PermissionDecisionAutoBlocker::RemoveCountsByUrl( | |
| 185 base::Callback<bool(const GURL& url)> filter) { | |
| 186 HostContentSettingsMap* map = | |
| 187 HostContentSettingsMapFactory::GetForProfile(profile_); | |
| 188 | |
| 189 std::unique_ptr<ContentSettingsForOneType> settings( | |
| 190 new ContentSettingsForOneType); | |
| 191 map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA, | |
| 192 std::string(), settings.get()); | |
| 193 | |
| 194 for (const auto& site : *settings) { | |
| 195 GURL origin(site.primary_pattern.ToString()); | |
| 196 | |
| 197 if (origin.is_valid() && filter.Run(origin)) { | |
| 198 map->SetWebsiteSettingDefaultScope( | |
| 199 origin, GURL(), CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA, | |
| 200 std::string(), nullptr); | |
| 201 } | |
| 202 } | |
| 203 } | |
| 204 | |
| 205 int PermissionDecisionAutoBlocker::GetDismissCount( | |
| 206 const GURL& url, | |
| 207 ContentSettingsType permission) { | |
| 208 return GetActionCount(url, permission, kPromptDismissCountKey, profile_); | |
| 209 } | |
| 210 | |
| 211 int PermissionDecisionAutoBlocker::GetIgnoreCount( | |
| 212 const GURL& url, | |
| 213 ContentSettingsType permission) { | |
| 214 return GetActionCount(url, permission, kPromptIgnoreCountKey, profile_); | |
| 215 } | |
| 216 | |
| 217 bool PermissionDecisionAutoBlocker::RecordDismissAndEmbargo( | |
| 218 const GURL& url, | |
| 219 ContentSettingsType permission) { | |
| 220 int current_dismissal_count = RecordActionInWebsiteSettings( | |
| 221 url, permission, kPromptDismissCountKey, profile_); | |
| 222 | |
| 223 if (base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften) && | |
| 224 current_dismissal_count >= g_prompt_dismissals_before_block) { | |
| 225 PlaceUnderEmbargo(permission, url, kPermissionDismissalEmbargoKey); | |
| 226 return true; | |
| 227 } | |
| 228 return false; | |
| 229 } | |
| 230 | |
| 231 int PermissionDecisionAutoBlocker::RecordIgnore( | |
| 232 const GURL& url, | |
| 233 ContentSettingsType permission) { | |
| 234 return RecordActionInWebsiteSettings(url, permission, kPromptIgnoreCountKey, | |
| 235 profile_); | |
| 236 } | |
| 237 | |
| 238 // static | 171 // static |
| 239 void PermissionDecisionAutoBlocker::UpdateFromVariations() { | 172 void PermissionDecisionAutoBlocker::UpdateFromVariations() { |
| 240 int prompt_dismissals = -1; | 173 int prompt_dismissals = -1; |
| 241 int blacklist_embargo_days = -1; | 174 int blacklist_embargo_days = -1; |
| 242 int dismissal_embargo_days = -1; | 175 int dismissal_embargo_days = -1; |
| 243 std::string dismissals_value = variations::GetVariationParamValueByFeature( | 176 std::string dismissals_value = variations::GetVariationParamValueByFeature( |
| 244 features::kBlockPromptsIfDismissedOften, kPromptDismissCountKey); | 177 features::kBlockPromptsIfDismissedOften, kPromptDismissCountKey); |
| 245 std::string blacklist_embargo_value = | 178 std::string blacklist_embargo_value = |
| 246 variations::GetVariationParamValueByFeature( | 179 variations::GetVariationParamValueByFeature( |
| 247 features::kPermissionsBlacklist, kPermissionBlacklistEmbargoKey); | 180 features::kPermissionsBlacklist, kPermissionBlacklistEmbargoKey); |
| 248 std::string dismissal_embargo_value = | 181 std::string dismissal_embargo_value = |
| 249 variations::GetVariationParamValueByFeature( | 182 variations::GetVariationParamValueByFeature( |
| 250 features::kBlockPromptsIfDismissedOften, | 183 features::kBlockPromptsIfDismissedOften, |
| 251 kPermissionDismissalEmbargoKey); | 184 kPermissionDismissalEmbargoKey); |
| 252 // If converting the value fails, stick with the current value. | 185 // If converting the value fails, stick with the current value. |
| 253 if (base::StringToInt(dismissals_value, &prompt_dismissals) && | 186 if (base::StringToInt(dismissals_value, &prompt_dismissals) && |
| 254 prompt_dismissals > 0) { | 187 prompt_dismissals > 0) { |
| 255 g_prompt_dismissals_before_block = prompt_dismissals; | 188 g_prompt_dismissals_before_block = prompt_dismissals; |
| 256 } | 189 } |
| 257 if (base::StringToInt(blacklist_embargo_value, &blacklist_embargo_days) && | 190 if (base::StringToInt(blacklist_embargo_value, &blacklist_embargo_days) && |
| 258 blacklist_embargo_days > 0) { | 191 blacklist_embargo_days > 0) { |
| 259 g_blacklist_embargo_days = blacklist_embargo_days; | 192 g_blacklist_embargo_days = blacklist_embargo_days; |
| 260 } | 193 } |
| 261 if (base::StringToInt(dismissal_embargo_value, &dismissal_embargo_days) && | 194 if (base::StringToInt(dismissal_embargo_value, &dismissal_embargo_days) && |
| 262 dismissal_embargo_days > 0) { | 195 dismissal_embargo_days > 0) { |
| 263 g_dismissal_embargo_days = dismissal_embargo_days; | 196 g_dismissal_embargo_days = dismissal_embargo_days; |
| 264 } | 197 } |
| 265 } | 198 } |
| 266 | 199 |
| 267 void PermissionDecisionAutoBlocker::UpdateEmbargoedStatus( | 200 void PermissionDecisionAutoBlocker::CheckSafeBrowsingBlacklist( |
| 201 content::WebContents* web_contents, |
| 202 const GURL& request_origin, |
| 268 ContentSettingsType permission, | 203 ContentSettingsType permission, |
| 269 const GURL& request_origin, | |
| 270 content::WebContents* web_contents, | |
| 271 base::Callback<void(bool)> callback) { | 204 base::Callback<void(bool)> callback) { |
| 272 DCHECK_EQ(CONTENT_SETTING_ASK, | 205 DCHECK_EQ(CONTENT_SETTING_ASK, |
| 273 GetEmbargoResult(permission, request_origin).content_setting); | 206 GetEmbargoResult(request_origin, permission).content_setting); |
| 274 | 207 |
| 275 if (base::FeatureList::IsEnabled(features::kPermissionsBlacklist) && | 208 if (base::FeatureList::IsEnabled(features::kPermissionsBlacklist) && |
| 276 db_manager_) { | 209 db_manager_) { |
| 277 // The CheckSafeBrowsingResult callback won't be called if the profile is | 210 // The CheckSafeBrowsingResult callback won't be called if the profile is |
| 278 // destroyed before a result is received. In that case this object will have | 211 // destroyed before a result is received. In that case this object will have |
| 279 // been destroyed by that point. | 212 // been destroyed by that point. |
| 280 PermissionBlacklistClient::CheckSafeBrowsingBlacklist( | 213 PermissionBlacklistClient::CheckSafeBrowsingBlacklist( |
| 281 db_manager_, permission, request_origin, web_contents, | 214 web_contents, db_manager_, request_origin, permission, |
| 282 safe_browsing_timeout_, | 215 safe_browsing_timeout_, |
| 283 base::Bind(&PermissionDecisionAutoBlocker::CheckSafeBrowsingResult, | 216 base::Bind(&PermissionDecisionAutoBlocker::CheckSafeBrowsingResult, |
| 284 base::Unretained(this), permission, request_origin, | 217 base::Unretained(this), request_origin, permission, |
| 285 callback)); | 218 callback)); |
| 286 return; | 219 return; |
| 287 } | 220 } |
| 288 | 221 |
| 289 callback.Run(false /* permission blocked */); | 222 callback.Run(false /* permission blocked */); |
| 290 } | 223 } |
| 291 | 224 |
| 292 PermissionResult PermissionDecisionAutoBlocker::GetEmbargoResult( | 225 PermissionResult PermissionDecisionAutoBlocker::GetEmbargoResult( |
| 293 ContentSettingsType permission, | 226 const GURL& request_origin, |
| 294 const GURL& request_origin) { | 227 ContentSettingsType permission) { |
| 295 HostContentSettingsMap* map = | 228 HostContentSettingsMap* map = |
| 296 HostContentSettingsMapFactory::GetForProfile(profile_); | 229 HostContentSettingsMapFactory::GetForProfile(profile_); |
| 297 std::unique_ptr<base::DictionaryValue> dict = | 230 std::unique_ptr<base::DictionaryValue> dict = |
| 298 GetOriginDict(map, request_origin); | 231 GetOriginDict(map, request_origin); |
| 299 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( | 232 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( |
| 300 dict.get(), PermissionUtil::GetPermissionString(permission)); | 233 dict.get(), PermissionUtil::GetPermissionString(permission)); |
| 301 double embargo_date = -1; | 234 double embargo_date = -1; |
| 302 | 235 |
| 303 base::Time current_time = clock_->Now(); | 236 base::Time current_time = clock_->Now(); |
| 304 if (base::FeatureList::IsEnabled(features::kPermissionsBlacklist) && | 237 if (base::FeatureList::IsEnabled(features::kPermissionsBlacklist) && |
| (...skipping 15 matching lines...) Expand all Loading... |
| 320 base::TimeDelta::FromDays(g_dismissal_embargo_days)) { | 253 base::TimeDelta::FromDays(g_dismissal_embargo_days)) { |
| 321 return PermissionResult(CONTENT_SETTING_BLOCK, | 254 return PermissionResult(CONTENT_SETTING_BLOCK, |
| 322 PermissionStatusSource::MULTIPLE_DISMISSALS); | 255 PermissionStatusSource::MULTIPLE_DISMISSALS); |
| 323 } | 256 } |
| 324 } | 257 } |
| 325 | 258 |
| 326 return PermissionResult(CONTENT_SETTING_ASK, | 259 return PermissionResult(CONTENT_SETTING_ASK, |
| 327 PermissionStatusSource::UNSPECIFIED); | 260 PermissionStatusSource::UNSPECIFIED); |
| 328 } | 261 } |
| 329 | 262 |
| 263 int PermissionDecisionAutoBlocker::GetDismissCount( |
| 264 const GURL& url, |
| 265 ContentSettingsType permission) { |
| 266 return GetActionCount(url, permission, kPromptDismissCountKey, profile_); |
| 267 } |
| 268 |
| 269 int PermissionDecisionAutoBlocker::GetIgnoreCount( |
| 270 const GURL& url, |
| 271 ContentSettingsType permission) { |
| 272 return GetActionCount(url, permission, kPromptIgnoreCountKey, profile_); |
| 273 } |
| 274 |
| 275 bool PermissionDecisionAutoBlocker::RecordDismissAndEmbargo( |
| 276 const GURL& url, |
| 277 ContentSettingsType permission) { |
| 278 int current_dismissal_count = RecordActionInWebsiteSettings( |
| 279 url, permission, kPromptDismissCountKey, profile_); |
| 280 |
| 281 if (base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften) && |
| 282 current_dismissal_count >= g_prompt_dismissals_before_block) { |
| 283 PlaceUnderEmbargo(url, permission, kPermissionDismissalEmbargoKey); |
| 284 return true; |
| 285 } |
| 286 return false; |
| 287 } |
| 288 |
| 289 int PermissionDecisionAutoBlocker::RecordIgnore( |
| 290 const GURL& url, |
| 291 ContentSettingsType permission) { |
| 292 return RecordActionInWebsiteSettings(url, permission, kPromptIgnoreCountKey, |
| 293 profile_); |
| 294 } |
| 295 |
| 296 void PermissionDecisionAutoBlocker::RemoveCountsByUrl( |
| 297 base::Callback<bool(const GURL& url)> filter) { |
| 298 HostContentSettingsMap* map = |
| 299 HostContentSettingsMapFactory::GetForProfile(profile_); |
| 300 |
| 301 std::unique_ptr<ContentSettingsForOneType> settings( |
| 302 new ContentSettingsForOneType); |
| 303 map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA, |
| 304 std::string(), settings.get()); |
| 305 |
| 306 for (const auto& site : *settings) { |
| 307 GURL origin(site.primary_pattern.ToString()); |
| 308 |
| 309 if (origin.is_valid() && filter.Run(origin)) { |
| 310 map->SetWebsiteSettingDefaultScope( |
| 311 origin, GURL(), CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA, |
| 312 std::string(), nullptr); |
| 313 } |
| 314 } |
| 315 } |
| 316 |
| 317 PermissionDecisionAutoBlocker::PermissionDecisionAutoBlocker(Profile* profile) |
| 318 : profile_(profile), |
| 319 db_manager_(nullptr), |
| 320 safe_browsing_timeout_(kCheckUrlTimeoutMs), |
| 321 clock_(new base::DefaultClock()) { |
| 322 safe_browsing::SafeBrowsingService* sb_service = |
| 323 g_browser_process->safe_browsing_service(); |
| 324 if (sb_service) |
| 325 db_manager_ = sb_service->database_manager(); |
| 326 } |
| 327 |
| 328 PermissionDecisionAutoBlocker::~PermissionDecisionAutoBlocker() {} |
| 329 |
| 330 void PermissionDecisionAutoBlocker::CheckSafeBrowsingResult( | 330 void PermissionDecisionAutoBlocker::CheckSafeBrowsingResult( |
| 331 const GURL& request_origin, |
| 331 ContentSettingsType permission, | 332 ContentSettingsType permission, |
| 332 const GURL& request_origin, | |
| 333 base::Callback<void(bool)> callback, | 333 base::Callback<void(bool)> callback, |
| 334 bool should_be_embargoed) { | 334 bool should_be_embargoed) { |
| 335 if (should_be_embargoed) { | 335 if (should_be_embargoed) { |
| 336 // Requesting site is blacklisted for this permission, update the content | 336 // Requesting site is blacklisted for this permission, update the content |
| 337 // setting to place it under embargo. | 337 // setting to place it under embargo. |
| 338 PlaceUnderEmbargo(permission, request_origin, | 338 PlaceUnderEmbargo(request_origin, permission, |
| 339 kPermissionBlacklistEmbargoKey); | 339 kPermissionBlacklistEmbargoKey); |
| 340 } | 340 } |
| 341 callback.Run(should_be_embargoed /* permission blocked */); | 341 callback.Run(should_be_embargoed /* permission blocked */); |
| 342 } | 342 } |
| 343 | 343 |
| 344 void PermissionDecisionAutoBlocker::PlaceUnderEmbargo( | 344 void PermissionDecisionAutoBlocker::PlaceUnderEmbargo( |
| 345 const GURL& request_origin, |
| 345 ContentSettingsType permission, | 346 ContentSettingsType permission, |
| 346 const GURL& request_origin, | |
| 347 const char* key) { | 347 const char* key) { |
| 348 HostContentSettingsMap* map = | 348 HostContentSettingsMap* map = |
| 349 HostContentSettingsMapFactory::GetForProfile(profile_); | 349 HostContentSettingsMapFactory::GetForProfile(profile_); |
| 350 std::unique_ptr<base::DictionaryValue> dict = | 350 std::unique_ptr<base::DictionaryValue> dict = |
| 351 GetOriginDict(map, request_origin); | 351 GetOriginDict(map, request_origin); |
| 352 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( | 352 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( |
| 353 dict.get(), PermissionUtil::GetPermissionString(permission)); | 353 dict.get(), PermissionUtil::GetPermissionString(permission)); |
| 354 permission_dict->SetDouble(key, clock_->Now().ToInternalValue()); | 354 permission_dict->SetDouble(key, clock_->Now().ToInternalValue()); |
| 355 map->SetWebsiteSettingDefaultScope( | 355 map->SetWebsiteSettingDefaultScope( |
| 356 request_origin, GURL(), CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA, | 356 request_origin, GURL(), CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA, |
| 357 std::string(), std::move(dict)); | 357 std::string(), std::move(dict)); |
| 358 } | 358 } |
| 359 | 359 |
| 360 void PermissionDecisionAutoBlocker:: | 360 void PermissionDecisionAutoBlocker:: |
| 361 SetSafeBrowsingDatabaseManagerAndTimeoutForTesting( | 361 SetSafeBrowsingDatabaseManagerAndTimeoutForTesting( |
| 362 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> db_manager, | 362 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> db_manager, |
| 363 int timeout) { | 363 int timeout) { |
| 364 db_manager_ = db_manager; | 364 db_manager_ = db_manager; |
| 365 safe_browsing_timeout_ = timeout; | 365 safe_browsing_timeout_ = timeout; |
| 366 } | 366 } |
| 367 | 367 |
| 368 void PermissionDecisionAutoBlocker::SetClockForTesting( | 368 void PermissionDecisionAutoBlocker::SetClockForTesting( |
| 369 std::unique_ptr<base::Clock> clock) { | 369 std::unique_ptr<base::Clock> clock) { |
| 370 clock_ = std::move(clock); | 370 clock_ = std::move(clock); |
| 371 } | 371 } |
| OLD | NEW |