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

Side by Side Diff: chrome/browser/android/banners/app_banner_settings_helper.cc

Issue 884373002: Update content setting for app banners to store more information. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove unimplemented function Created 5 years, 10 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 unified diff | Download patch
« no previous file with comments | « chrome/browser/android/banners/app_banner_settings_helper.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/android/banners/app_banner_settings_helper.h" 5 #include "chrome/browser/android/banners/app_banner_settings_helper.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "chrome/browser/profiles/profile.h" 10 #include "chrome/browser/profiles/profile.h"
11 #include "components/content_settings/core/browser/host_content_settings_map.h" 11 #include "components/content_settings/core/browser/host_content_settings_map.h"
12 #include "components/content_settings/core/common/content_settings_pattern.h" 12 #include "components/content_settings/core/common/content_settings_pattern.h"
13 #include "content/public/browser/web_contents.h" 13 #include "content/public/browser/web_contents.h"
14 #include "net/base/escape.h"
14 #include "url/gurl.h" 15 #include "url/gurl.h"
15 16
16 namespace { 17 namespace {
17 std::string SanitizePackageName(std::string package_name) { 18
18 // DictionaryValue doesn't allow '.' in the keys. Replace them with ' ' 19 std::string SanitizeKeyName(std::string key_name) {
19 // because you can't have a package name with a ' ' in it. 20 // DictionaryValue doesn't allow '.' in the keys. So, first get rid of spaces
Bernhard Bauer 2015/01/29 16:49:36 Yes, it does :) You can use SetWithoutPathExpansio
benwells 2015/01/30 06:27:02 Done.
20 std::replace(package_name.begin(), package_name.end(), '.', ' '); 21 // by escaping, then replace dots with spaces.
21 return package_name; 22 key_name = net::EscapeUrlEncodedData(key_name, false);
23 std::replace(key_name.begin(), key_name.end(), '.', ' ');
24 return key_name;
22 } 25 }
23 26
24 // Max number of apps that a particular site may show a banner for. 27 // Max number of apps (including web native apps) that a particular site may
Bernhard Bauer 2015/01/29 16:49:35 What is a web native app? Does that mean Fizz?
benwells 2015/01/30 06:27:02 Yes it means Fizz. I'll explain better.
28 // show a banner for.
25 const size_t kMaxAppsPerSite = 3; 29 const size_t kMaxAppsPerSite = 3;
26 } // namespace
27 30
28 bool AppBannerSettingsHelper::IsAllowed(content::WebContents* web_contents, 31 // Oldest could show banner event we care about, in days.
29 const GURL& origin_url, 32 const unsigned int kOldestCouldShowBannerEventInDays = 14;
30 const std::string& package_name) {
31 std::string sanitized_package_name = SanitizePackageName(package_name);
32 Profile* profile =
33 Profile::FromBrowserContext(web_contents->GetBrowserContext());
34 if (profile->IsOffTheRecord() || web_contents->GetURL() != origin_url ||
35 sanitized_package_name.empty()) {
36 return false;
37 }
38 33
39 // Check if this combination has been previously disabled. 34 // Dictionary key to use for the 'could show banner' events.
40 HostContentSettingsMap* settings = profile->GetHostContentSettingsMap(); 35 const char kCouldShowBannerEventsKey[] = "couldShowBannerEvents";
36
37 // Dictionary key to use whether the banner has been blocked.
38 const char kHasBlockedKey[] = "hasBlocked";
39
40 base::Time DateFromTime(base::Time time) {
41 base::Time::Exploded exploded;
42 time.LocalExplode(&exploded);
Bernhard Bauer 2015/01/29 16:49:36 If we are using local time here, there could of co
benwells 2015/01/30 06:27:02 Yep that's right, its a heuristic. I think the sam
43 exploded.hour = 0;
44 exploded.minute = 0;
45 exploded.second = 0;
46 return base::Time::FromLocalExploded(exploded);
47 }
48
49 scoped_ptr<base::DictionaryValue> GetOriginDict(
50 HostContentSettingsMap* settings,
51 const GURL& origin_url) {
41 if (!settings) 52 if (!settings)
42 return false; 53 return scoped_ptr<base::DictionaryValue>();
54
43 scoped_ptr<base::Value> value = 55 scoped_ptr<base::Value> value =
44 settings->GetWebsiteSetting(origin_url, 56 settings->GetWebsiteSetting(origin_url,
45 origin_url, 57 origin_url,
46 CONTENT_SETTINGS_TYPE_APP_BANNER, 58 CONTENT_SETTINGS_TYPE_APP_BANNER,
47 std::string(), 59 std::string(),
48 NULL); 60 NULL);
49 if (!value.get()) { 61 if (!value.get()) {
50 // We've never blocked a banner on this site. 62 return scoped_ptr<base::DictionaryValue>();
51 return true; 63 }
52 } else if (value->IsType(base::Value::TYPE_DICTIONARY)) { 64
53 // We expect to get a Dictionary back, where the keys are the package names. 65 if (!value->IsType(base::Value::TYPE_DICTIONARY)) {
54 base::DictionaryValue* banner_dict = 66 return scoped_ptr<base::DictionaryValue>();
55 static_cast<base::DictionaryValue*>(value.get()); 67 }
56 bool is_allowed = false; 68
57 if (banner_dict->GetBoolean(sanitized_package_name, &is_allowed)) { 69 return scoped_ptr<base::DictionaryValue>(
Bernhard Bauer 2015/01/29 16:49:35 You can use make_scoped_ptr() here, which is a bit
benwells 2015/01/30 06:27:02 nice, thanks. I think I've used it everywhere I ca
58 return is_allowed; 70 static_cast<base::DictionaryValue*>(value.release()));
59 } else { 71 }
60 return banner_dict->size() < ::kMaxAppsPerSite; 72
61 } 73 base::DictionaryValue* GetAppDict(base::DictionaryValue* origin_dict,
62 } else { 74 const std::string& key_name) {
63 // Somehow the value we got back is not a dictionary (e.g. the settings were 75 base::DictionaryValue* app_dict = nullptr;
64 // corrupted by malware). Try to clear it out. 76 if (!origin_dict->GetDictionary(key_name, &app_dict)) {
65 ContentSettingsPattern pattern(ContentSettingsPattern::FromURL(origin_url)); 77 // Don't allow more than kMaxAppsPerSite dictionaries.
66 if (pattern.IsValid()) { 78 if (origin_dict->size() < kMaxAppsPerSite) {
67 settings->SetWebsiteSetting(pattern, 79 app_dict = new base::DictionaryValue();
68 ContentSettingsPattern::Wildcard(), 80 origin_dict->Set(key_name, scoped_ptr<base::DictionaryValue>(app_dict));
Bernhard Bauer 2015/01/29 16:49:36 Same here, just use make_scoped_ptr.
benwells 2015/01/30 06:27:02 Done.
69 CONTENT_SETTINGS_TYPE_APP_BANNER,
70 std::string(),
71 NULL);
72 return true;
73 } 81 }
74 } 82 }
75 83
76 return false; 84 return app_dict;
77 } 85 }
78 86
79 void AppBannerSettingsHelper::Block(content::WebContents* web_contents, 87 } // namespace
80 const GURL& origin_url,
81 const std::string& package_name) {
82 std::string sanitized_package_name = SanitizePackageName(package_name);
83 DCHECK(!sanitized_package_name.empty());
84 88
89 void RecordCouldShowBannerEvent(content::WebContents* web_contents,
90 const GURL& origin_url,
91 const std::string& package_name_or_start_url,
92 base::Time time) {
93 std::string app_key = SanitizeKeyName(package_name_or_start_url);
85 Profile* profile = 94 Profile* profile =
86 Profile::FromBrowserContext(web_contents->GetBrowserContext()); 95 Profile::FromBrowserContext(web_contents->GetBrowserContext());
87 HostContentSettingsMap* settings = profile->GetHostContentSettingsMap(); 96 if (profile->IsOffTheRecord() || web_contents->GetURL() != origin_url ||
97 app_key.empty()) {
98 return;
99 }
100
88 ContentSettingsPattern pattern(ContentSettingsPattern::FromURL(origin_url)); 101 ContentSettingsPattern pattern(ContentSettingsPattern::FromURL(origin_url));
89 if (!settings || !pattern.IsValid()) 102 if (!pattern.IsValid())
90 return; 103 return;
91 104
92 scoped_ptr<base::Value> value = 105 HostContentSettingsMap* settings = profile->GetHostContentSettingsMap();
93 settings->GetWebsiteSetting(origin_url, 106 scoped_ptr<base::DictionaryValue> origin_dict = GetOriginDict(
94 origin_url, 107 settings, origin_url);
95 CONTENT_SETTINGS_TYPE_APP_BANNER, 108 if (!origin_dict)
96 std::string(), 109 origin_dict.reset(new base::DictionaryValue());
97 NULL); 110
98 base::DictionaryValue* banner_dict = NULL; 111 base::DictionaryValue* app_dict = GetAppDict(origin_dict.get(), app_key);
99 if (value.get() && value->IsType(base::Value::TYPE_DICTIONARY)) { 112 if (!app_dict)
100 banner_dict = static_cast<base::DictionaryValue*>(value.release()); 113 return;
101 } else { 114
102 banner_dict = new base::DictionaryValue(); 115 base::ListValue* could_show_list = nullptr;
116 if (!app_dict->GetList(kCouldShowBannerEventsKey, &could_show_list)) {
117 could_show_list = new base::ListValue();
118 app_dict->Set(kCouldShowBannerEventsKey,
119 scoped_ptr<base::ListValue>(could_show_list));
103 } 120 }
104 121
105 // Update the setting and save it back. 122 // Trim any items that are older than we should care about. If the list
106 banner_dict->SetBoolean(sanitized_package_name, false); 123 // already contains the date of interest, just exit.
124 base::Time date = DateFromTime(time);
125 for (base::ValueVector::iterator it = could_show_list->begin();
126 it != could_show_list->end(); ++it) {
127 if ((*it)->IsType(base::Value::TYPE_DOUBLE)) {
128 double internal_date;
129 DCHECK((*it)->GetAsDouble(&internal_date));
Bernhard Bauer 2015/01/29 16:49:35 This will be compiled out in a Release build! The
benwells 2015/01/30 06:27:02 Ah, of course! Thanks for finding that. I don't th
130 base::Time other_date = base::Time::FromInternalValue(internal_date);
131 if (other_date == date)
132 return;
133
134 base::TimeDelta delta = date - other_date;
135 if (delta <= base::TimeDelta::FromDays(kOldestCouldShowBannerEventInDays))
136 continue;
137 }
138 could_show_list->Erase(it, nullptr);
139 }
140
141 could_show_list->AppendDouble(date.ToInternalValue());
107 settings->SetWebsiteSetting(pattern, 142 settings->SetWebsiteSetting(pattern,
108 ContentSettingsPattern::Wildcard(), 143 ContentSettingsPattern::Wildcard(),
109 CONTENT_SETTINGS_TYPE_APP_BANNER, 144 CONTENT_SETTINGS_TYPE_APP_BANNER,
110 std::string(), 145 std::string(),
111 banner_dict); 146 origin_dict.get());
112 } 147 }
148
149 bool AppBannerSettingsHelper::IsAllowed(
150 content::WebContents* web_contents,
151 const GURL& origin_url,
152 const std::string& package_name_or_start_url) {
153 std::string app_key = SanitizeKeyName(package_name_or_start_url);
154 Profile* profile =
155 Profile::FromBrowserContext(web_contents->GetBrowserContext());
156 if (profile->IsOffTheRecord() || web_contents->GetURL() != origin_url ||
157 app_key.empty()) {
158 return false;
159 }
160
161 HostContentSettingsMap* settings = profile->GetHostContentSettingsMap();
162 scoped_ptr<base::DictionaryValue> origin_dict = GetOriginDict(
163 settings, origin_url);
164
165 if (!origin_dict)
166 return true;
167
168 base::DictionaryValue* app_dict = GetAppDict(origin_dict.get(), app_key);
169 if (!app_dict)
170 return true;
171
172 bool has_blocked;
173 if (!app_dict->GetBoolean(kHasBlockedKey, &has_blocked))
174 return true;
175
176 return !has_blocked;
177 }
178
179 void AppBannerSettingsHelper::Block(
180 content::WebContents* web_contents,
181 const GURL& origin_url,
182 const std::string& package_name_or_start_url) {
183 std::string app_key = SanitizeKeyName(package_name_or_start_url);
184 Profile* profile =
185 Profile::FromBrowserContext(web_contents->GetBrowserContext());
186 if (profile->IsOffTheRecord() || web_contents->GetURL() != origin_url ||
187 app_key.empty()) {
188 return;
189 }
190
191 ContentSettingsPattern pattern(ContentSettingsPattern::FromURL(origin_url));
192 if (!pattern.IsValid())
193 return;
194
195 HostContentSettingsMap* settings = profile->GetHostContentSettingsMap();
196 scoped_ptr<base::DictionaryValue> origin_dict = GetOriginDict(
197 settings, origin_url);
198
199 if (!origin_dict)
200 return;
201
202 base::DictionaryValue* app_dict = GetAppDict(origin_dict.get(), app_key);
203 if (!app_dict)
204 return;
205
206 // Update the setting and save it back.
207 app_dict->SetBoolean(kHasBlockedKey, false);
208 settings->SetWebsiteSetting(pattern,
209 ContentSettingsPattern::Wildcard(),
210 CONTENT_SETTINGS_TYPE_APP_BANNER,
211 std::string(),
212 origin_dict.get());
213 }
OLDNEW
« no previous file with comments | « chrome/browser/android/banners/app_banner_settings_helper.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698