Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/permissions/permission_prompt_decision_log.h" | |
| 6 | |
| 7 #include <memory> | |
| 8 | |
| 9 #include "base/feature_list.h" | |
| 10 #include "base/logging.h" | |
| 11 #include "base/memory/ptr_util.h" | |
| 12 #include "base/strings/string_number_conversions.h" | |
| 13 #include "base/values.h" | |
| 14 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" | |
| 15 #include "chrome/browser/permissions/permission_util.h" | |
| 16 #include "chrome/common/chrome_features.h" | |
| 17 #include "components/content_settings/core/browser/host_content_settings_map.h" | |
| 18 #include "components/variations/variations_associated_data.h" | |
| 19 #include "content/public/browser/permission_type.h" | |
| 20 #include "url/gurl.h" | |
| 21 | |
| 22 namespace { | |
| 23 | |
| 24 // The default number of times that users may explicitly dismiss a permission | |
| 25 // prompt from an origin before it is automatically blocked. | |
| 26 int kPromptDismissalsBeforeBlock = 3; | |
| 27 | |
| 28 const char kPromptStudyName[] = "PermissionPromptsUX"; | |
| 29 const char kPromptDismissCountKey[] = "dismiss_count"; | |
| 30 | |
| 31 std::unique_ptr<base::DictionaryValue> GetOriginDict( | |
| 32 HostContentSettingsMap* settings, | |
| 33 const GURL& origin_url) { | |
| 34 std::unique_ptr<base::DictionaryValue> dict = | |
| 35 base::DictionaryValue::From(settings->GetWebsiteSetting( | |
| 36 origin_url, origin_url, | |
| 37 CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT, std::string(), | |
| 38 nullptr)); | |
| 39 if (!dict) | |
| 40 return base::WrapUnique(new base::DictionaryValue()); | |
| 41 | |
| 42 return dict; | |
| 43 } | |
| 44 | |
| 45 base::DictionaryValue* GetOrCreatePermissionDict( | |
| 46 base::DictionaryValue* origin_dict, | |
| 47 const std::string& permission) { | |
| 48 base::DictionaryValue* permission_dict = nullptr; | |
| 49 if (!origin_dict->GetDictionaryWithoutPathExpansion(permission, | |
| 50 &permission_dict)) { | |
| 51 permission_dict = new base::DictionaryValue(); | |
| 52 origin_dict->SetWithoutPathExpansion(permission, | |
| 53 base::WrapUnique(permission_dict)); | |
| 54 } | |
| 55 | |
| 56 return permission_dict; | |
| 57 } | |
| 58 | |
| 59 // Records that the user dismissed a permission prompt for type |permission| | |
| 60 // on |url| to a website setting. Returns the updated number of dismissals. | |
| 61 int RecordDismissalCount(Profile* profile, | |
| 62 const GURL& url, | |
| 63 content::PermissionType permission) { | |
| 64 HostContentSettingsMap* map = | |
| 65 HostContentSettingsMapFactory::GetForProfile(profile); | |
| 66 std::unique_ptr<base::DictionaryValue> dict = GetOriginDict(map, url); | |
| 67 | |
| 68 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict( | |
| 69 dict.get(), PermissionUtil::GetPermissionString(permission)); | |
| 70 | |
| 71 int current_count = 0; | |
| 72 permission_dict->GetInteger(kPromptDismissCountKey, ¤t_count); | |
| 73 permission_dict->SetInteger(kPromptDismissCountKey, ++current_count); | |
| 74 | |
| 75 map->SetWebsiteSettingDefaultScope( | |
| 76 url, GURL(), CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT, | |
| 77 std::string(), std::move(dict)); | |
| 78 | |
| 79 return current_count; | |
| 80 } | |
| 81 | |
| 82 } // anonymous namespace | |
|
raymes
2016/08/01 05:09:11
nit: I think // namespace is more common
dominickn
2016/08/03 05:38:46
Done.
| |
| 83 | |
| 84 PermissionPromptDecisionLog::PermissionPromptDecisionLog() | |
| 85 : prompt_dismissals_before_block_(kPromptDismissalsBeforeBlock) { | |
| 86 UpdateFromVariations(); | |
| 87 } | |
| 88 | |
| 89 bool PermissionPromptDecisionLog::ShouldChangeDismissalToBlock( | |
| 90 Profile* profile, | |
| 91 const GURL& url, | |
| 92 content::PermissionType permission) { | |
| 93 int current_dismissal_count = RecordDismissalCount(profile, url, permission); | |
| 94 | |
| 95 if (!base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften)) | |
| 96 return false; | |
| 97 | |
| 98 return current_dismissal_count >= prompt_dismissals_before_block_; | |
| 99 } | |
| 100 | |
| 101 void PermissionPromptDecisionLog::UpdateFromVariations() { | |
| 102 int prompt_dismissals = -1; | |
| 103 std::string value = variations::GetVariationParamValue( | |
| 104 kPromptStudyName, kPromptDismissCountKey); | |
| 105 | |
| 106 // If converting the value fails, stick with the default value. | |
| 107 if (base::StringToInt(value, &prompt_dismissals) && prompt_dismissals > 0) | |
| 108 prompt_dismissals_before_block_ = prompt_dismissals; | |
| 109 } | |
| OLD | NEW |