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

Unified 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, 11 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/android/banners/app_banner_settings_helper.cc
diff --git a/chrome/browser/android/banners/app_banner_settings_helper.cc b/chrome/browser/android/banners/app_banner_settings_helper.cc
index ed3298ccbb948de4c283d71f759ae221b8c7b62f..aa418ba193dcba9b5a3cc1f3fbd8afd3d998b279 100644
--- a/chrome/browser/android/banners/app_banner_settings_helper.cc
+++ b/chrome/browser/android/banners/app_banner_settings_helper.cc
@@ -11,35 +11,47 @@
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings_pattern.h"
#include "content/public/browser/web_contents.h"
+#include "net/base/escape.h"
#include "url/gurl.h"
namespace {
-std::string SanitizePackageName(std::string package_name) {
- // DictionaryValue doesn't allow '.' in the keys. Replace them with ' '
- // because you can't have a package name with a ' ' in it.
- std::replace(package_name.begin(), package_name.end(), '.', ' ');
- return package_name;
+
+std::string SanitizeKeyName(std::string key_name) {
+ // 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.
+ // by escaping, then replace dots with spaces.
+ key_name = net::EscapeUrlEncodedData(key_name, false);
+ std::replace(key_name.begin(), key_name.end(), '.', ' ');
+ return key_name;
}
-// Max number of apps that a particular site may show a banner for.
+// 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.
+// show a banner for.
const size_t kMaxAppsPerSite = 3;
-} // namespace
-bool AppBannerSettingsHelper::IsAllowed(content::WebContents* web_contents,
- const GURL& origin_url,
- const std::string& package_name) {
- std::string sanitized_package_name = SanitizePackageName(package_name);
- Profile* profile =
- Profile::FromBrowserContext(web_contents->GetBrowserContext());
- if (profile->IsOffTheRecord() || web_contents->GetURL() != origin_url ||
- sanitized_package_name.empty()) {
- return false;
- }
+// Oldest could show banner event we care about, in days.
+const unsigned int kOldestCouldShowBannerEventInDays = 14;
- // Check if this combination has been previously disabled.
- HostContentSettingsMap* settings = profile->GetHostContentSettingsMap();
+// Dictionary key to use for the 'could show banner' events.
+const char kCouldShowBannerEventsKey[] = "couldShowBannerEvents";
+
+// Dictionary key to use whether the banner has been blocked.
+const char kHasBlockedKey[] = "hasBlocked";
+
+base::Time DateFromTime(base::Time time) {
+ base::Time::Exploded exploded;
+ 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
+ exploded.hour = 0;
+ exploded.minute = 0;
+ exploded.second = 0;
+ return base::Time::FromLocalExploded(exploded);
+}
+
+scoped_ptr<base::DictionaryValue> GetOriginDict(
+ HostContentSettingsMap* settings,
+ const GURL& origin_url) {
if (!settings)
- return false;
+ return scoped_ptr<base::DictionaryValue>();
+
scoped_ptr<base::Value> value =
settings->GetWebsiteSetting(origin_url,
origin_url,
@@ -47,66 +59,155 @@ bool AppBannerSettingsHelper::IsAllowed(content::WebContents* web_contents,
std::string(),
NULL);
if (!value.get()) {
- // We've never blocked a banner on this site.
- return true;
- } else if (value->IsType(base::Value::TYPE_DICTIONARY)) {
- // We expect to get a Dictionary back, where the keys are the package names.
- base::DictionaryValue* banner_dict =
- static_cast<base::DictionaryValue*>(value.get());
- bool is_allowed = false;
- if (banner_dict->GetBoolean(sanitized_package_name, &is_allowed)) {
- return is_allowed;
- } else {
- return banner_dict->size() < ::kMaxAppsPerSite;
- }
- } else {
- // Somehow the value we got back is not a dictionary (e.g. the settings were
- // corrupted by malware). Try to clear it out.
- ContentSettingsPattern pattern(ContentSettingsPattern::FromURL(origin_url));
- if (pattern.IsValid()) {
- settings->SetWebsiteSetting(pattern,
- ContentSettingsPattern::Wildcard(),
- CONTENT_SETTINGS_TYPE_APP_BANNER,
- std::string(),
- NULL);
- return true;
+ return scoped_ptr<base::DictionaryValue>();
+ }
+
+ if (!value->IsType(base::Value::TYPE_DICTIONARY)) {
+ return scoped_ptr<base::DictionaryValue>();
+ }
+
+ 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
+ static_cast<base::DictionaryValue*>(value.release()));
+}
+
+base::DictionaryValue* GetAppDict(base::DictionaryValue* origin_dict,
+ const std::string& key_name) {
+ base::DictionaryValue* app_dict = nullptr;
+ if (!origin_dict->GetDictionary(key_name, &app_dict)) {
+ // Don't allow more than kMaxAppsPerSite dictionaries.
+ if (origin_dict->size() < kMaxAppsPerSite) {
+ app_dict = new base::DictionaryValue();
+ 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.
}
}
- return false;
+ return app_dict;
}
-void AppBannerSettingsHelper::Block(content::WebContents* web_contents,
- const GURL& origin_url,
- const std::string& package_name) {
- std::string sanitized_package_name = SanitizePackageName(package_name);
- DCHECK(!sanitized_package_name.empty());
+} // namespace
+void RecordCouldShowBannerEvent(content::WebContents* web_contents,
+ const GURL& origin_url,
+ const std::string& package_name_or_start_url,
+ base::Time time) {
+ std::string app_key = SanitizeKeyName(package_name_or_start_url);
Profile* profile =
Profile::FromBrowserContext(web_contents->GetBrowserContext());
- HostContentSettingsMap* settings = profile->GetHostContentSettingsMap();
+ if (profile->IsOffTheRecord() || web_contents->GetURL() != origin_url ||
+ app_key.empty()) {
+ return;
+ }
+
ContentSettingsPattern pattern(ContentSettingsPattern::FromURL(origin_url));
- if (!settings || !pattern.IsValid())
+ if (!pattern.IsValid())
return;
- scoped_ptr<base::Value> value =
- settings->GetWebsiteSetting(origin_url,
- origin_url,
- CONTENT_SETTINGS_TYPE_APP_BANNER,
- std::string(),
- NULL);
- base::DictionaryValue* banner_dict = NULL;
- if (value.get() && value->IsType(base::Value::TYPE_DICTIONARY)) {
- banner_dict = static_cast<base::DictionaryValue*>(value.release());
- } else {
- banner_dict = new base::DictionaryValue();
+ HostContentSettingsMap* settings = profile->GetHostContentSettingsMap();
+ scoped_ptr<base::DictionaryValue> origin_dict = GetOriginDict(
+ settings, origin_url);
+ if (!origin_dict)
+ origin_dict.reset(new base::DictionaryValue());
+
+ base::DictionaryValue* app_dict = GetAppDict(origin_dict.get(), app_key);
+ if (!app_dict)
+ return;
+
+ base::ListValue* could_show_list = nullptr;
+ if (!app_dict->GetList(kCouldShowBannerEventsKey, &could_show_list)) {
+ could_show_list = new base::ListValue();
+ app_dict->Set(kCouldShowBannerEventsKey,
+ scoped_ptr<base::ListValue>(could_show_list));
}
+ // Trim any items that are older than we should care about. If the list
+ // already contains the date of interest, just exit.
+ base::Time date = DateFromTime(time);
+ for (base::ValueVector::iterator it = could_show_list->begin();
+ it != could_show_list->end(); ++it) {
+ if ((*it)->IsType(base::Value::TYPE_DOUBLE)) {
+ double internal_date;
+ 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
+ base::Time other_date = base::Time::FromInternalValue(internal_date);
+ if (other_date == date)
+ return;
+
+ base::TimeDelta delta = date - other_date;
+ if (delta <= base::TimeDelta::FromDays(kOldestCouldShowBannerEventInDays))
+ continue;
+ }
+ could_show_list->Erase(it, nullptr);
+ }
+
+ could_show_list->AppendDouble(date.ToInternalValue());
+ settings->SetWebsiteSetting(pattern,
+ ContentSettingsPattern::Wildcard(),
+ CONTENT_SETTINGS_TYPE_APP_BANNER,
+ std::string(),
+ origin_dict.get());
+}
+
+bool AppBannerSettingsHelper::IsAllowed(
+ content::WebContents* web_contents,
+ const GURL& origin_url,
+ const std::string& package_name_or_start_url) {
+ std::string app_key = SanitizeKeyName(package_name_or_start_url);
+ Profile* profile =
+ Profile::FromBrowserContext(web_contents->GetBrowserContext());
+ if (profile->IsOffTheRecord() || web_contents->GetURL() != origin_url ||
+ app_key.empty()) {
+ return false;
+ }
+
+ HostContentSettingsMap* settings = profile->GetHostContentSettingsMap();
+ scoped_ptr<base::DictionaryValue> origin_dict = GetOriginDict(
+ settings, origin_url);
+
+ if (!origin_dict)
+ return true;
+
+ base::DictionaryValue* app_dict = GetAppDict(origin_dict.get(), app_key);
+ if (!app_dict)
+ return true;
+
+ bool has_blocked;
+ if (!app_dict->GetBoolean(kHasBlockedKey, &has_blocked))
+ return true;
+
+ return !has_blocked;
+}
+
+void AppBannerSettingsHelper::Block(
+ content::WebContents* web_contents,
+ const GURL& origin_url,
+ const std::string& package_name_or_start_url) {
+ std::string app_key = SanitizeKeyName(package_name_or_start_url);
+ Profile* profile =
+ Profile::FromBrowserContext(web_contents->GetBrowserContext());
+ if (profile->IsOffTheRecord() || web_contents->GetURL() != origin_url ||
+ app_key.empty()) {
+ return;
+ }
+
+ ContentSettingsPattern pattern(ContentSettingsPattern::FromURL(origin_url));
+ if (!pattern.IsValid())
+ return;
+
+ HostContentSettingsMap* settings = profile->GetHostContentSettingsMap();
+ scoped_ptr<base::DictionaryValue> origin_dict = GetOriginDict(
+ settings, origin_url);
+
+ if (!origin_dict)
+ return;
+
+ base::DictionaryValue* app_dict = GetAppDict(origin_dict.get(), app_key);
+ if (!app_dict)
+ return;
+
// Update the setting and save it back.
- banner_dict->SetBoolean(sanitized_package_name, false);
+ app_dict->SetBoolean(kHasBlockedKey, false);
settings->SetWebsiteSetting(pattern,
ContentSettingsPattern::Wildcard(),
CONTENT_SETTINGS_TYPE_APP_BANNER,
std::string(),
- banner_dict);
+ origin_dict.get());
}
« 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