| Index: chrome/browser/content_settings/content_settings_pref_provider.cc
|
| diff --git a/chrome/browser/content_settings/content_settings_pref_provider.cc b/chrome/browser/content_settings/content_settings_pref_provider.cc
|
| index 0eaf68532b416144bf2f41709f164a8ae14f98d2..a53851eb05263ca97b2663dae53e21d26cfcfeed 100644
|
| --- a/chrome/browser/content_settings/content_settings_pref_provider.cc
|
| +++ b/chrome/browser/content_settings/content_settings_pref_provider.cc
|
| @@ -14,6 +14,8 @@
|
| #include "base/metrics/histogram.h"
|
| #include "base/prefs/pref_service.h"
|
| #include "base/prefs/scoped_user_pref_update.h"
|
| +#include "base/time/clock.h"
|
| +#include "base/time/default_clock.h"
|
| #include "chrome/browser/chrome_notification_types.h"
|
| #include "chrome/browser/content_settings/content_settings_rule.h"
|
| #include "chrome/browser/content_settings/content_settings_utils.h"
|
| @@ -40,6 +42,7 @@ typedef std::map<std::string, std::string> StringMap;
|
| const char kPerPluginPrefName[] = "per_plugin";
|
| const char kAudioKey[] = "audio";
|
| const char kVideoKey[] = "video";
|
| +const char kLastUsed[] = "last_used";
|
|
|
| ContentSetting FixObsoleteCookiePromptMode(ContentSettingsType content_type,
|
| ContentSetting setting) {
|
| @@ -86,7 +89,9 @@ void PrefProvider::RegisterProfilePrefs(
|
| PrefProvider::PrefProvider(PrefService* prefs,
|
| bool incognito)
|
| : prefs_(prefs),
|
| + clock_(new base::DefaultClock()),
|
| is_incognito_(incognito),
|
| + owns_clock_(true),
|
| updating_preferences_(false) {
|
| DCHECK(prefs_);
|
| // Verify preferences version.
|
| @@ -214,6 +219,8 @@ void PrefProvider::ClearAllContentSettingsRules(
|
|
|
| PrefProvider::~PrefProvider() {
|
| DCHECK(!prefs_);
|
| + if (owns_clock_)
|
| + delete clock_;
|
| }
|
|
|
| RuleIterator* PrefProvider::GetRuleIterator(
|
| @@ -290,6 +297,7 @@ void PrefProvider::UpdatePref(
|
| if (value == NULL) {
|
| settings_dictionary->RemoveWithoutPathExpansion(setting_path,
|
| NULL);
|
| + settings_dictionary->RemoveWithoutPathExpansion(kLastUsed, NULL);
|
| } else {
|
| settings_dictionary->SetWithoutPathExpansion(
|
| setting_path, value->DeepCopy());
|
| @@ -566,6 +574,87 @@ void PrefProvider::ShutdownOnUIThread() {
|
| prefs_ = NULL;
|
| }
|
|
|
| +void PrefProvider::UpdateLastUsage(
|
| + const ContentSettingsPattern& primary_pattern,
|
| + const ContentSettingsPattern& secondary_pattern,
|
| + ContentSettingsType content_type) {
|
| + // Don't write if in incognito.
|
| + if (is_incognito_) {
|
| + return;
|
| + }
|
| +
|
| + // Ensure that |lock_| is not held by this thread, since this function will
|
| + // send out notifications (by |~DictionaryPrefUpdate|).
|
| + AssertLockNotHeld();
|
| +
|
| + base::AutoReset<bool> auto_reset(&updating_preferences_, true);
|
| + {
|
| + DictionaryPrefUpdate update(prefs_, prefs::kContentSettingsPatternPairs);
|
| + base::DictionaryValue* pattern_pairs_settings = update.Get();
|
| +
|
| + std::string pattern_str(
|
| + CreatePatternString(primary_pattern, secondary_pattern));
|
| + base::DictionaryValue* settings_dictionary = NULL;
|
| + bool found = pattern_pairs_settings->GetDictionaryWithoutPathExpansion(
|
| + pattern_str, &settings_dictionary);
|
| +
|
| + if (!found) {
|
| + settings_dictionary = new base::DictionaryValue;
|
| + pattern_pairs_settings->SetWithoutPathExpansion(pattern_str,
|
| + settings_dictionary);
|
| + }
|
| +
|
| + if (settings_dictionary) {
|
| + base::DictionaryValue* last_used_dictionary = NULL;
|
| + found = settings_dictionary->GetDictionaryWithoutPathExpansion(
|
| + kLastUsed, &last_used_dictionary);
|
| +
|
| + if (!found) {
|
| + last_used_dictionary = new base::DictionaryValue;
|
| + settings_dictionary->SetWithoutPathExpansion(kLastUsed,
|
| + last_used_dictionary);
|
| + }
|
| +
|
| + std::string settings_path = GetTypeName(content_type);
|
| + last_used_dictionary->Set(
|
| + settings_path, new base::FundamentalValue(clock_->Now().ToDoubleT()));
|
| + }
|
| + }
|
| +}
|
| +
|
| +base::Time PrefProvider::GetLastUsage(
|
| + const ContentSettingsPattern& primary_pattern,
|
| + const ContentSettingsPattern& secondary_pattern,
|
| + ContentSettingsType content_type) {
|
| + const base::DictionaryValue* pattern_pairs_settings =
|
| + prefs_->GetDictionary(prefs::kContentSettingsPatternPairs);
|
| + std::string pattern_str(
|
| + CreatePatternString(primary_pattern, secondary_pattern));
|
| +
|
| + const base::DictionaryValue* settings_dictionary = NULL;
|
| + bool found = pattern_pairs_settings->GetDictionaryWithoutPathExpansion(
|
| + pattern_str, &settings_dictionary);
|
| +
|
| + if (!found)
|
| + return base::Time();
|
| +
|
| + const base::DictionaryValue* last_used_dictionary = NULL;
|
| + found = settings_dictionary->GetDictionaryWithoutPathExpansion(
|
| + kLastUsed, &last_used_dictionary);
|
| +
|
| + if (!found)
|
| + return base::Time();
|
| +
|
| + double last_used_time;
|
| + found = last_used_dictionary->GetDoubleWithoutPathExpansion(
|
| + GetTypeName(content_type), &last_used_time);
|
| +
|
| + if (!found)
|
| + return base::Time();
|
| +
|
| + return base::Time::FromDoubleT(last_used_time);
|
| +}
|
| +
|
| void PrefProvider::AssertLockNotHeld() const {
|
| #if !defined(NDEBUG)
|
| // |Lock::Acquire()| will assert if the lock is held by this thread.
|
| @@ -574,4 +663,11 @@ void PrefProvider::AssertLockNotHeld() const {
|
| #endif
|
| }
|
|
|
| +void PrefProvider::SetClockForTesting(base::Clock* clock) {
|
| + if (owns_clock_)
|
| + delete clock_;
|
| + clock_ = clock;
|
| + owns_clock_ = false;
|
| +}
|
| +
|
| } // namespace content_settings
|
|
|