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..fd5cf24b9b5412ee21b44b68c6af090941d9cd19 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) { |
@@ -83,11 +86,11 @@ void PrefProvider::RegisterProfilePrefs( |
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); |
} |
-PrefProvider::PrefProvider(PrefService* prefs, |
- bool incognito) |
- : prefs_(prefs), |
- is_incognito_(incognito), |
- updating_preferences_(false) { |
+PrefProvider::PrefProvider(PrefService* prefs, bool incognito) |
+ : prefs_(prefs), |
+ clock_(new base::DefaultClock()), |
+ is_incognito_(incognito), |
+ updating_preferences_(false) { |
DCHECK(prefs_); |
// Verify preferences version. |
if (!prefs_->HasPrefPath(prefs::kContentSettingsVersion)) { |
@@ -290,6 +293,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 +570,85 @@ 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); |
+ } |
+ |
+ 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 +657,8 @@ void PrefProvider::AssertLockNotHeld() const { |
#endif |
} |
+void PrefProvider::SetClockForTesting(scoped_ptr<base::Clock> clock) { |
+ clock_ = clock.Pass(); |
+} |
+ |
} // namespace content_settings |