Chromium Code Reviews| Index: chrome/browser/permissions/permission_prompt_decision_log.cc |
| diff --git a/chrome/browser/permissions/permission_prompt_decision_log.cc b/chrome/browser/permissions/permission_prompt_decision_log.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..cebb54247cf5b81b453c0fe8f5731d159a4d4a87 |
| --- /dev/null |
| +++ b/chrome/browser/permissions/permission_prompt_decision_log.cc |
| @@ -0,0 +1,109 @@ |
| +// Copyright 2016 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/permissions/permission_prompt_decision_log.h" |
| + |
| +#include <memory> |
| + |
| +#include "base/feature_list.h" |
| +#include "base/logging.h" |
| +#include "base/memory/ptr_util.h" |
| +#include "base/strings/string_number_conversions.h" |
| +#include "base/values.h" |
| +#include "chrome/browser/content_settings/host_content_settings_map_factory.h" |
| +#include "chrome/browser/permissions/permission_util.h" |
| +#include "chrome/common/chrome_features.h" |
| +#include "components/content_settings/core/browser/host_content_settings_map.h" |
| +#include "components/variations/variations_associated_data.h" |
| +#include "content/public/browser/permission_type.h" |
| +#include "url/gurl.h" |
| + |
| +namespace { |
| + |
| +// The default number of times that users may explicitly dismiss a permission |
| +// prompt from an origin before it is automatically blocked. |
| +int kPromptDismissalsBeforeBlock = 3; |
| + |
| +const char kPromptStudyName[] = "PermissionPromptsUX"; |
| +const char kPromptDismissCountKey[] = "dismiss_count"; |
| + |
| +std::unique_ptr<base::DictionaryValue> GetOriginDict( |
| + HostContentSettingsMap* settings, |
| + const GURL& origin_url) { |
| + std::unique_ptr<base::DictionaryValue> dict = |
| + base::DictionaryValue::From(settings->GetWebsiteSetting( |
| + origin_url, origin_url, |
| + CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT, std::string(), |
| + nullptr)); |
| + if (!dict) |
| + return base::WrapUnique(new base::DictionaryValue()); |
| + |
| + return dict; |
| +} |
| + |
| +base::DictionaryValue* GetOrCreatePermissionDict( |
| + base::DictionaryValue* origin_dict, |
| + const std::string& permission) { |
| + base::DictionaryValue* permission_dict = nullptr; |
| + if (!origin_dict->GetDictionaryWithoutPathExpansion(permission, |
| + &permission_dict)) { |
| + permission_dict = new base::DictionaryValue(); |
| + origin_dict->SetWithoutPathExpansion(permission, |
| + base::WrapUnique(permission_dict)); |
| + } |
| + |
| + return permission_dict; |
| +} |
| + |
| +// Records that the user dismissed a permission prompt for type |permission| |
| +// on |url| to a website setting. Returns the updated number of dismissals. |
| +int RecordDismissalCount(Profile* profile, |
| + const GURL& url, |
| + content::PermissionType permission) { |
| + HostContentSettingsMap* map = |
| + HostContentSettingsMapFactory::GetForProfile(profile); |
| + std::unique_ptr<base::DictionaryValue> dict = GetOriginDict(map, url); |
| + |
| + base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( |
| + dict.get(), PermissionUtil::GetPermissionString(permission)); |
| + |
| + int current_count = 0; |
| + permission_dict->GetInteger(kPromptDismissCountKey, ¤t_count); |
| + permission_dict->SetInteger(kPromptDismissCountKey, ++current_count); |
| + |
| + map->SetWebsiteSettingDefaultScope( |
| + url, GURL(), CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT, |
| + std::string(), std::move(dict)); |
| + |
| + return current_count; |
| +} |
| + |
| +} // anonymous namespace |
|
raymes
2016/08/01 05:09:11
nit: I think // namespace is more common
dominickn
2016/08/03 05:38:46
Done.
|
| + |
| +PermissionPromptDecisionLog::PermissionPromptDecisionLog() |
| + : prompt_dismissals_before_block_(kPromptDismissalsBeforeBlock) { |
| + UpdateFromVariations(); |
| +} |
| + |
| +bool PermissionPromptDecisionLog::ShouldChangeDismissalToBlock( |
| + Profile* profile, |
| + const GURL& url, |
| + content::PermissionType permission) { |
| + int current_dismissal_count = RecordDismissalCount(profile, url, permission); |
| + |
| + if (!base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften)) |
| + return false; |
| + |
| + return current_dismissal_count >= prompt_dismissals_before_block_; |
| +} |
| + |
| +void PermissionPromptDecisionLog::UpdateFromVariations() { |
| + int prompt_dismissals = -1; |
| + std::string value = variations::GetVariationParamValue( |
| + kPromptStudyName, kPromptDismissCountKey); |
| + |
| + // If converting the value fails, stick with the default value. |
| + if (base::StringToInt(value, &prompt_dismissals) && prompt_dismissals > 0) |
| + prompt_dismissals_before_block_ = prompt_dismissals; |
| +} |