Chromium Code Reviews| 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..14c0bdbb2925021b488640899ff27354d01c85fa 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_(scoped_ptr<base::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,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) { |
|
Michael van Ouwerkerk
2014/07/01 11:02:23
Why would this be false? A new one is instantiated
Daniel Nishi
2014/07/01 18:37:48
Good point. The defensive check is unneeded.
Remo
|
| + 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 +659,8 @@ void PrefProvider::AssertLockNotHeld() const { |
| #endif |
| } |
| +void PrefProvider::SetClockForTesting(base::Clock* clock) { |
| + clock_.reset(clock); |
| +} |
| + |
| } // namespace content_settings |