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/prefs/tracked/tracked_split_preference.h" 6 7#include <vector> 8 9#include "base/logging.h" 10#include "base/values.h" 11#include "chrome/browser/prefs/pref_hash_store_transaction.h" 12#include "chrome/browser/prefs/tracked/tracked_preference_validation_delegate.h" 13 14TrackedSplitPreference::TrackedSplitPreference( 15 const std::string& pref_path, 16 size_t reporting_id, 17 size_t reporting_ids_count, 18 PrefHashFilter::EnforcementLevel enforcement_level, 19 TrackedPreferenceValidationDelegate* delegate) 20 : pref_path_(pref_path), 21 helper_(pref_path, reporting_id, reporting_ids_count, enforcement_level), 22 delegate_(delegate) { 23} 24 25void TrackedSplitPreference::OnNewValue( 26 const base::Value* value, 27 PrefHashStoreTransaction* transaction) const { 28 const base::DictionaryValue* dict_value = NULL; 29 if (value && !value->GetAsDictionary(&dict_value)) { 30 NOTREACHED(); 31 return; 32 } 33 transaction->StoreSplitHash(pref_path_, dict_value); 34} 35 36bool TrackedSplitPreference::EnforceAndReport( 37 base::DictionaryValue* pref_store_contents, 38 PrefHashStoreTransaction* transaction) const { 39 base::DictionaryValue* dict_value = NULL; 40 if (!pref_store_contents->GetDictionary(pref_path_, &dict_value) && 41 pref_store_contents->Get(pref_path_, NULL)) { 42 // There should be a dictionary or nothing at |pref_path_|. 43 NOTREACHED(); 44 return false; 45 } 46 47 std::vector<std::string> invalid_keys; 48 PrefHashStoreTransaction::ValueState value_state = 49 transaction->CheckSplitValue(pref_path_, dict_value, &invalid_keys); 50 51 if (value_state == PrefHashStoreTransaction::CHANGED) 52 helper_.ReportSplitPreferenceChangedCount(invalid_keys.size()); 53 54 helper_.ReportValidationResult(value_state); 55 56 TrackedPreferenceHelper::ResetAction reset_action = 57 helper_.GetAction(value_state); 58 if (delegate_) { 59 delegate_->OnSplitPreferenceValidation( 60 pref_path_, dict_value, invalid_keys, value_state, reset_action); 61 } 62 helper_.ReportAction(reset_action); 63 64 bool was_reset = false; 65 if (reset_action == TrackedPreferenceHelper::DO_RESET) { 66 if (value_state == PrefHashStoreTransaction::CHANGED) { 67 DCHECK(!invalid_keys.empty()); 68 69 for (std::vector<std::string>::const_iterator it = 70 invalid_keys.begin(); it != invalid_keys.end(); ++it) { 71 dict_value->Remove(*it, NULL); 72 } 73 } else { 74 pref_store_contents->RemovePath(pref_path_, NULL); 75 } 76 was_reset = true; 77 } 78 79 if (value_state != PrefHashStoreTransaction::UNCHANGED) { 80 // Store the hash for the new value (whether it was reset or not). 81 const base::DictionaryValue* new_dict_value = NULL; 82 pref_store_contents->GetDictionary(pref_path_, &new_dict_value); 83 transaction->StoreSplitHash(pref_path_, new_dict_value); 84 } 85 86 return was_reset; 87} 88