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 "chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate.h"
6
7#include <string>
8#include <vector>
9
10#include "base/callback.h"
11#include "base/json/json_writer.h"
12#include "chrome/browser/prefs/pref_hash_store_transaction.h"
13#include "chrome/browser/prefs/tracked/tracked_preference_helper.h"
14#include "chrome/common/safe_browsing/csd.pb.h"
15
16namespace safe_browsing {
17
18namespace {
19
20typedef ClientIncidentReport_IncidentData_TrackedPreferenceIncident TPIncident;
21typedef ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState
22    TPIncident_ValueState;
23
24// Maps a PrefHashStoreTransaction::ValueState to a
25// TrackedPreferenceIncident::ValueState.
26TPIncident_ValueState MapValueState(
27    PrefHashStoreTransaction::ValueState value_state) {
28  switch (value_state) {
29    case PrefHashStoreTransaction::CLEARED:
30      return TPIncident::CLEARED;
31    case PrefHashStoreTransaction::CHANGED:
32      return TPIncident::CHANGED;
33    case PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE:
34      return TPIncident::UNTRUSTED_UNKNOWN_VALUE;
35    default:
36      return TPIncident::UNKNOWN;
37  }
38}
39
40}  // namespace
41
42PreferenceValidationDelegate::PreferenceValidationDelegate(
43    const AddIncidentCallback& add_incident)
44    : add_incident_(add_incident) {
45}
46
47PreferenceValidationDelegate::~PreferenceValidationDelegate() {
48}
49
50void PreferenceValidationDelegate::OnAtomicPreferenceValidation(
51    const std::string& pref_path,
52    const base::Value* value,
53    PrefHashStoreTransaction::ValueState value_state,
54    TrackedPreferenceHelper::ResetAction /* reset_action */) {
55  TPIncident_ValueState proto_value_state = MapValueState(value_state);
56  if (proto_value_state != TPIncident::UNKNOWN) {
57    scoped_ptr<ClientIncidentReport_IncidentData> incident_data(
58        new ClientIncidentReport_IncidentData());
59    TPIncident* incident = incident_data->mutable_tracked_preference();
60    incident->set_path(pref_path);
61    if (!value ||
62        (!value->GetAsString(incident->mutable_atomic_value()) &&
63         !base::JSONWriter::Write(value, incident->mutable_atomic_value()))) {
64      incident->clear_atomic_value();
65    }
66    incident->set_value_state(proto_value_state);
67    add_incident_.Run(incident_data.Pass());
68  }
69}
70
71void PreferenceValidationDelegate::OnSplitPreferenceValidation(
72    const std::string& pref_path,
73    const base::DictionaryValue* /* dict_value */,
74    const std::vector<std::string>& invalid_keys,
75    PrefHashStoreTransaction::ValueState value_state,
76    TrackedPreferenceHelper::ResetAction /* reset_action */) {
77  TPIncident_ValueState proto_value_state = MapValueState(value_state);
78  if (proto_value_state != TPIncident::UNKNOWN) {
79    scoped_ptr<ClientIncidentReport_IncidentData> incident_data(
80        new ClientIncidentReport_IncidentData());
81    TPIncident* incident = incident_data->mutable_tracked_preference();
82    incident->set_path(pref_path);
83    for (std::vector<std::string>::const_iterator scan(invalid_keys.begin());
84         scan != invalid_keys.end();
85         ++scan) {
86      incident->add_split_key(*scan);
87    }
88    incident->set_value_state(proto_value_state);
89    add_incident_.Run(incident_data.Pass());
90  }
91}
92
93}  // namespace safe_browsing
94