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 3 // found in the LICENSE file. 4 5 #include "components/suggestions/suggestions_store.h" 6 7 #include <string> 8 9 #include "base/base64.h" 10 #include "base/prefs/pref_service.h" 11 #include "base/time/time.h" 12 #include "components/pref_registry/pref_registry_syncable.h" 13 #include "components/suggestions/suggestions_pref_names.h" 14 15 namespace suggestions { 16 17 SuggestionsStore::SuggestionsStore(PrefService* profile_prefs) 18 : pref_service_(profile_prefs) { 19 DCHECK(profile_prefs); 20 } 21 22 SuggestionsStore::~SuggestionsStore() {} 23 24 bool SuggestionsStore::LoadSuggestions(SuggestionsProfile* suggestions) { 25 DCHECK(suggestions); 26 27 const std::string base64_suggestions_data = 28 pref_service_->GetString(prefs::kSuggestionsData); 29 if (base64_suggestions_data.empty()) { 30 suggestions->Clear(); 31 return false; 32 } 33 34 // If the decode process fails, assume the pref value is corrupt and clear it. 35 std::string suggestions_data; 36 if (!base::Base64Decode(base64_suggestions_data, &suggestions_data) || 37 !suggestions->ParseFromString(suggestions_data)) { 38 VLOG(1) << "Suggestions data in profile pref is corrupt, clearing it."; 39 suggestions->Clear(); 40 ClearSuggestions(); 41 return false; 42 } 43 44 // Filter expired suggestions and update the stored suggestions if at least 45 // one was filtered. Return false if all suggestions are filtered. 46 int unfiltered_size = suggestions->suggestions_size(); 47 FilterExpiredSuggestions(suggestions); 48 if (suggestions->suggestions_size() != unfiltered_size) { 49 if (!suggestions->suggestions_size()) { 50 suggestions->Clear(); 51 ClearSuggestions(); 52 return false; 53 } else { 54 StoreSuggestions(*suggestions); 55 } 56 } 57 58 return true; 59 } 60 61 void SuggestionsStore::FilterExpiredSuggestions( 62 SuggestionsProfile* suggestions) { 63 SuggestionsProfile filtered_suggestions; 64 int64 now_usec = (base::Time::NowFromSystemTime() - base::Time::UnixEpoch()) 65 .ToInternalValue(); 66 67 for (int i = 0; i < suggestions->suggestions_size(); ++i) { 68 ChromeSuggestion* suggestion = suggestions->mutable_suggestions(i); 69 if (!suggestion->has_expiry_ts() || suggestion->expiry_ts() > now_usec) { 70 filtered_suggestions.add_suggestions()->Swap(suggestion); 71 } 72 } 73 suggestions->Swap(&filtered_suggestions); 74 } 75 76 bool SuggestionsStore::StoreSuggestions(const SuggestionsProfile& suggestions) { 77 std::string suggestions_data; 78 if (!suggestions.SerializeToString(&suggestions_data)) return false; 79 80 std::string base64_suggestions_data; 81 base::Base64Encode(suggestions_data, &base64_suggestions_data); 82 83 pref_service_->SetString(prefs::kSuggestionsData, base64_suggestions_data); 84 return true; 85 } 86 87 void SuggestionsStore::ClearSuggestions() { 88 pref_service_->ClearPref(prefs::kSuggestionsData); 89 } 90 91 // static 92 void SuggestionsStore::RegisterProfilePrefs( 93 user_prefs::PrefRegistrySyncable* registry) { 94 registry->RegisterStringPref( 95 prefs::kSuggestionsData, std::string(), 96 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 97 } 98 99 } // namespace suggestions 100