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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/safe_browsing/incident_reporting/platform_state_store.cc
diff --git a/chrome/browser/safe_browsing/incident_reporting/platform_state_store.cc b/chrome/browser/safe_browsing/incident_reporting/platform_state_store.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0c657c6587918a955a5a2fda6a55777df1d73bc4
--- /dev/null
+++ b/chrome/browser/safe_browsing/incident_reporting/platform_state_store.cc
@@ -0,0 +1,200 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file implements the platform-neutral Load() and Store() functions for a
+// profile's safebrowsing.incidents_sent preference dictionary. The preference
+// dict is converted to a protocol buffer message which is then serialized into
+// a byte array. This serialized data is written to or read from some
+// platform-specific storage via {Read,Write}StoreData implemented elsewhere.
+//
+// A pref dict like so:
+// { "0": {"key1": "1235"}, {"key2": "6789"}}}
+// is converted to an identical protocol buffer message, where the top-level
+// mapping's keys are of type int, and the nested mappings' values are of type
+// uint32_t.
+
+#include "chrome/browser/safe_browsing/incident_reporting/platform_state_store.h"
+
+#include "base/values.h"
+
+#if defined(USE_PLATFORM_STATE_STORE)
+
+#include "base/metrics/histogram_macros.h"
+#include "base/strings/string_number_conversions.h"
+#include "chrome/browser/safe_browsing/incident_reporting/state_store_data.pb.h"
+#include "third_party/protobuf/src/google/protobuf/repeated_field.h"
+
+#endif // USE_PLATFORM_STATE_STORE
+
+namespace safe_browsing {
+namespace platform_state_store {
+
+#if defined(USE_PLATFORM_STATE_STORE)
+
+namespace {
+
+using google::protobuf::RepeatedPtrField;
+
+// Copies the (key, digest) pairs from |keys_and_digests| (a dict of string
+// values) to the |key_digest_pairs| protobuf.
+void KeysAndDigestsToProtobuf(
+ const base::DictionaryValue& keys_and_digests,
+ RepeatedPtrField<StateStoreData::Incidents::KeyDigestMapFieldEntry>*
+ key_digest_pairs) {
+ for (base::DictionaryValue::Iterator iter(keys_and_digests); !iter.IsAtEnd();
+ iter.Advance()) {
+ const base::StringValue* digest_value = nullptr;
+ if (!iter.value().GetAsString(&digest_value)) {
+ NOTREACHED();
+ continue;
+ }
+ uint32_t digest = 0;
+ if (!base::StringToUint(digest_value->GetString(), &digest)) {
+ NOTREACHED();
+ continue;
+ }
+ StateStoreData::Incidents::KeyDigestMapFieldEntry* key_digest =
+ key_digest_pairs->Add();
+ key_digest->set_key(iter.key());
+ key_digest->set_digest(digest);
+ }
+}
+
+// Copies the (type, dict) pairs from |incidents_sent| (a dict of dict values)
+// to the |typed_incidents| protobuf.
+void IncidentsSentToProtobuf(
+ const base::DictionaryValue& incidents_sent,
+ RepeatedPtrField<StateStoreData::TypeIncidentsMapFieldEntry>*
+ type_incidents_pairs) {
+ for (base::DictionaryValue::Iterator iter(incidents_sent); !iter.IsAtEnd();
+ iter.Advance()) {
+ const base::DictionaryValue* keys_and_digests = nullptr;
+ if (!iter.value().GetAsDictionary(&keys_and_digests)) {
+ NOTREACHED();
+ continue;
+ }
+ if (keys_and_digests->empty())
+ continue;
+ int incident_type = 0;
+ if (!base::StringToInt(iter.key(), &incident_type)) {
+ NOTREACHED();
+ continue;
+ }
+ StateStoreData::TypeIncidentsMapFieldEntry* entry =
+ type_incidents_pairs->Add();
+ entry->set_type(incident_type);
+ KeysAndDigestsToProtobuf(
+ *keys_and_digests, entry->mutable_incidents()->mutable_key_to_digest());
+ }
+}
+
+// Copies the (key, digest) pairs for a specific incident type into |type_dict|
+// (a dict of string values).
+void RestoreOfTypeFromProtobuf(
+ const RepeatedPtrField<StateStoreData::Incidents::KeyDigestMapFieldEntry>&
+ key_digest_pairs,
+ base::DictionaryValue* type_dict) {
+ for (const auto& key_digest : key_digest_pairs) {
+ if (!key_digest.has_key() || !key_digest.has_digest())
+ continue;
+ type_dict->SetStringWithoutPathExpansion(
+ key_digest.key(), base::UintToString(key_digest.digest()));
+ }
+}
+
+// Copies the (type, dict) pairs into |value_dict| (a dict of dict values).
+void RestoreFromProtobuf(
+ const RepeatedPtrField<StateStoreData::TypeIncidentsMapFieldEntry>&
+ type_incidents_pairs,
+ base::DictionaryValue* value_dict) {
+ for (const auto& type_incidents : type_incidents_pairs) {
+ if (!type_incidents.has_type() || !type_incidents.has_incidents() ||
+ type_incidents.incidents().key_to_digest_size() == 0) {
+ continue;
+ }
+ std::string type_string(base::IntToString(type_incidents.type()));
+ base::DictionaryValue* type_dict = nullptr;
+ if (!value_dict->GetDictionaryWithoutPathExpansion(type_string,
+ &type_dict)) {
+ type_dict = new base::DictionaryValue();
+ value_dict->SetWithoutPathExpansion(type_string, type_dict);
+ }
+ RestoreOfTypeFromProtobuf(type_incidents.incidents().key_to_digest(),
+ type_dict);
+ }
+}
+
+} // namespace
+
+#endif // USE_PLATFORM_STATE_STORE
+
+scoped_ptr<base::DictionaryValue> Load(Profile* profile) {
+#if defined(USE_PLATFORM_STATE_STORE)
+ scoped_ptr<base::DictionaryValue> value_dict(new base::DictionaryValue());
+ std::string data;
+ PlatformStateStoreLoadResult result = ReadStoreData(profile, &data);
+ if (result == PlatformStateStoreLoadResult::SUCCESS)
+ result = DeserializeIncidentsSent(data, value_dict.get());
+ switch (result) {
+ case PlatformStateStoreLoadResult::SUCCESS:
+ case PlatformStateStoreLoadResult::CLEARED_DATA:
+ case PlatformStateStoreLoadResult::CLEARED_NO_DATA:
+ // Return a (possibly empty) dictionary for the success cases.
+ break;
+ case PlatformStateStoreLoadResult::DATA_CLEAR_FAILED:
+ case PlatformStateStoreLoadResult::OPEN_FAILED:
+ case PlatformStateStoreLoadResult::READ_FAILED:
+ case PlatformStateStoreLoadResult::PARSE_ERROR:
+ // Return null for all error cases.
+ value_dict.reset();
+ break;
+ }
+ UMA_HISTOGRAM_ENUMERATION(
+ "SBIRS.PSSLoadResult", static_cast<uint32_t>(result),
+ static_cast<uint32_t>(PlatformStateStoreLoadResult::NUM_RESULTS));
+ return value_dict.Pass();
+#else
+ return scoped_ptr<base::DictionaryValue>();
+#endif
+}
+
+void Store(Profile* profile, const base::DictionaryValue* incidents_sent) {
+#if defined(USE_PLATFORM_STATE_STORE)
+ std::string data;
+ SerializeIncidentsSent(incidents_sent, &data);
+ UMA_HISTOGRAM_COUNTS("SBIRS.PSSDataStoreSize", data.size());
+ WriteStoreData(profile, data);
+#endif
+}
+
+#if defined(USE_PLATFORM_STATE_STORE)
+
+void SerializeIncidentsSent(const base::DictionaryValue* incidents_sent,
+ std::string* data) {
+ StateStoreData store_data;
+
+ IncidentsSentToProtobuf(*incidents_sent,
+ store_data.mutable_type_to_incidents());
+ store_data.SerializeToString(data);
+}
+
+PlatformStateStoreLoadResult DeserializeIncidentsSent(
+ const std::string& data,
+ base::DictionaryValue* value_dict) {
+ StateStoreData store_data;
+ if (data.empty()) {
+ value_dict->Clear();
+ return PlatformStateStoreLoadResult::SUCCESS;
+ }
+ if (!store_data.ParseFromString(data))
+ return PlatformStateStoreLoadResult::PARSE_ERROR;
+ value_dict->Clear();
+ RestoreFromProtobuf(store_data.type_to_incidents(), value_dict);
+ return PlatformStateStoreLoadResult::SUCCESS;
+}
+
+#endif // USE_PLATFORM_STATE_STORE
+
+} // namespace platform_state_store
+} // namespace safe_browsing

Powered by Google App Engine
This is Rietveld 408576698