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

Side by Side Diff: chrome/browser/safe_browsing/incident_reporting/platform_state_store.cc

Issue 1243293003: Platform-specific prune state storage. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@prune1
Patch Set: moved uninstall cleanup to separate cl Created 5 years, 3 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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 // This file implements the platform-neutral Load() and Store() functions for a
6 // profile's safebrowsing.incidents_sent preference dictionary. The preference
7 // dict is converted to a protocol buffer message which is then serialized into
8 // a byte array. This serialized data is written to or read from some
9 // platform-specific storage via {Read,Write}StoreData implemented elsewhere.
10 //
11 // A pref dict like so:
12 // { "0": {"key1": "1235"}, {"key2": "6789"}}}
13 // is converted to an identical protocol buffer message, where the top-level
14 // mapping's keys are of type int, and the nested mappings' values are of type
15 // uint32_t.
16
17 #include "chrome/browser/safe_browsing/incident_reporting/platform_state_store.h "
18
19 #include "base/values.h"
20
21 #if defined(USE_PLATFORM_STATE_STORE)
22
23 #include "base/metrics/histogram_macros.h"
24 #include "base/strings/string_number_conversions.h"
25 #include "chrome/browser/safe_browsing/incident_reporting/state_store_data.pb.h"
26 #include "third_party/protobuf/src/google/protobuf/repeated_field.h"
27
28 #endif // USE_PLATFORM_STATE_STORE
29
30 namespace safe_browsing {
31 namespace platform_state_store {
32
33 #if defined(USE_PLATFORM_STATE_STORE)
34
35 namespace {
36
37 using google::protobuf::RepeatedPtrField;
38
39 // Copies the (key, digest) pairs from |keys_and_digests| (a dict of string
40 // values) to the |key_digest_pairs| protobuf.
41 void KeysAndDigestsToProtobuf(
42 const base::DictionaryValue& keys_and_digests,
43 RepeatedPtrField<StateStoreData::Incidents::KeyDigestMapFieldEntry>*
44 key_digest_pairs) {
45 for (base::DictionaryValue::Iterator iter(keys_and_digests); !iter.IsAtEnd();
46 iter.Advance()) {
47 const base::StringValue* digest_value = nullptr;
48 if (!iter.value().GetAsString(&digest_value)) {
49 NOTREACHED();
50 continue;
51 }
52 uint32_t digest = 0;
53 if (!base::StringToUint(digest_value->GetString(), &digest)) {
54 NOTREACHED();
55 continue;
56 }
57 StateStoreData::Incidents::KeyDigestMapFieldEntry* key_digest =
58 key_digest_pairs->Add();
59 key_digest->set_key(iter.key());
60 key_digest->set_digest(digest);
61 }
62 }
63
64 // Copies the (type, dict) pairs from |incidents_sent| (a dict of dict values)
65 // to the |typed_incidents| protobuf.
66 void IncidentsSentToProtobuf(
67 const base::DictionaryValue& incidents_sent,
68 RepeatedPtrField<StateStoreData::TypeIncidentsMapFieldEntry>*
69 type_incidents_pairs) {
70 for (base::DictionaryValue::Iterator iter(incidents_sent); !iter.IsAtEnd();
71 iter.Advance()) {
72 const base::DictionaryValue* keys_and_digests = nullptr;
73 if (!iter.value().GetAsDictionary(&keys_and_digests)) {
74 NOTREACHED();
75 continue;
76 }
77 if (keys_and_digests->empty())
78 continue;
79 int incident_type = 0;
80 if (!base::StringToInt(iter.key(), &incident_type)) {
81 NOTREACHED();
82 continue;
83 }
84 StateStoreData::TypeIncidentsMapFieldEntry* entry =
85 type_incidents_pairs->Add();
86 entry->set_type(incident_type);
87 KeysAndDigestsToProtobuf(
88 *keys_and_digests, entry->mutable_incidents()->mutable_key_to_digest());
89 }
90 }
91
92 // Copies the (key, digest) pairs for a specific incident type into |type_dict|
93 // (a dict of string values).
94 void RestoreOfTypeFromProtobuf(
95 const RepeatedPtrField<StateStoreData::Incidents::KeyDigestMapFieldEntry>&
96 key_digest_pairs,
97 base::DictionaryValue* type_dict) {
98 for (const auto& key_digest : key_digest_pairs) {
99 if (!key_digest.has_key() || !key_digest.has_digest())
100 continue;
101 type_dict->SetStringWithoutPathExpansion(
102 key_digest.key(), base::UintToString(key_digest.digest()));
103 }
104 }
105
106 // Copies the (type, dict) pairs into |value_dict| (a dict of dict values).
107 void RestoreFromProtobuf(
108 const RepeatedPtrField<StateStoreData::TypeIncidentsMapFieldEntry>&
109 type_incidents_pairs,
110 base::DictionaryValue* value_dict) {
111 for (const auto& type_incidents : type_incidents_pairs) {
112 if (!type_incidents.has_type() || !type_incidents.has_incidents() ||
113 type_incidents.incidents().key_to_digest_size() == 0) {
114 continue;
115 }
116 std::string type_string(base::IntToString(type_incidents.type()));
117 base::DictionaryValue* type_dict = nullptr;
118 if (!value_dict->GetDictionaryWithoutPathExpansion(type_string,
119 &type_dict)) {
120 type_dict = new base::DictionaryValue();
121 value_dict->SetWithoutPathExpansion(type_string, type_dict);
122 }
123 RestoreOfTypeFromProtobuf(type_incidents.incidents().key_to_digest(),
124 type_dict);
125 }
126 }
127
128 } // namespace
129
130 #endif // USE_PLATFORM_STATE_STORE
131
132 scoped_ptr<base::DictionaryValue> Load(Profile* profile) {
133 #if defined(USE_PLATFORM_STATE_STORE)
134 scoped_ptr<base::DictionaryValue> value_dict(new base::DictionaryValue());
135 std::string data;
136 PlatformStateStoreLoadResult result = ReadStoreData(profile, &data);
137 if (result == PlatformStateStoreLoadResult::SUCCESS)
138 result = DeserializeIncidentsSent(data, value_dict.get());
139 switch (result) {
140 case PlatformStateStoreLoadResult::SUCCESS:
141 case PlatformStateStoreLoadResult::CLEARED_DATA:
142 case PlatformStateStoreLoadResult::CLEARED_NO_DATA:
143 // Return a (possibly empty) dictionary for the success cases.
144 break;
145 case PlatformStateStoreLoadResult::DATA_CLEAR_FAILED:
146 case PlatformStateStoreLoadResult::OPEN_FAILED:
147 case PlatformStateStoreLoadResult::READ_FAILED:
148 case PlatformStateStoreLoadResult::PARSE_ERROR:
149 // Return null for all error cases.
150 value_dict.reset();
151 break;
152 }
153 UMA_HISTOGRAM_ENUMERATION(
154 "SBIRS.PSSLoadResult", static_cast<uint32_t>(result),
155 static_cast<uint32_t>(PlatformStateStoreLoadResult::NUM_RESULTS));
156 return value_dict.Pass();
157 #else
158 return scoped_ptr<base::DictionaryValue>();
159 #endif
160 }
161
162 void Store(Profile* profile, const base::DictionaryValue* incidents_sent) {
163 #if defined(USE_PLATFORM_STATE_STORE)
164 std::string data;
165 SerializeIncidentsSent(incidents_sent, &data);
166 UMA_HISTOGRAM_COUNTS("SBIRS.PSSDataStoreSize", data.size());
167 WriteStoreData(profile, data);
168 #endif
169 }
170
171 #if defined(USE_PLATFORM_STATE_STORE)
172
173 void SerializeIncidentsSent(const base::DictionaryValue* incidents_sent,
174 std::string* data) {
175 StateStoreData store_data;
176
177 IncidentsSentToProtobuf(*incidents_sent,
178 store_data.mutable_type_to_incidents());
179 store_data.SerializeToString(data);
180 }
181
182 PlatformStateStoreLoadResult DeserializeIncidentsSent(
183 const std::string& data,
184 base::DictionaryValue* value_dict) {
185 StateStoreData store_data;
186 if (data.empty()) {
187 value_dict->Clear();
188 return PlatformStateStoreLoadResult::SUCCESS;
189 }
190 if (!store_data.ParseFromString(data))
191 return PlatformStateStoreLoadResult::PARSE_ERROR;
192 value_dict->Clear();
193 RestoreFromProtobuf(store_data.type_to_incidents(), value_dict);
194 return PlatformStateStoreLoadResult::SUCCESS;
195 }
196
197 #endif // USE_PLATFORM_STATE_STORE
198
199 } // namespace platform_state_store
200 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698