1// Copyright (c) 2011 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// A helper class that assists preferences in firing notifications when lists 6// or dictionaries are changed. 7 8#ifndef CHROME_BROWSER_PREFS_SCOPED_USER_PREF_UPDATE_H_ 9#define CHROME_BROWSER_PREFS_SCOPED_USER_PREF_UPDATE_H_ 10#pragma once 11 12#include <string> 13 14#include "base/basictypes.h" 15#include "base/scoped_ptr.h" 16#include "base/threading/non_thread_safe.h" 17#include "base/values.h" 18#include "chrome/browser/prefs/pref_service.h" 19 20class DictionaryValue; 21class ListValue; 22class PrefService; 23 24namespace subtle { 25 26// Base class for ScopedUserPrefUpdateTemplate that contains the parts 27// that do not depend on ScopedUserPrefUpdateTemplate's template parameter. 28// 29// We need this base class mostly for making it a friend of PrefService 30// and getting access to PrefService::GetMutableUserPref and 31// PrefService::ReportUserPrefChanged. 32class ScopedUserPrefUpdateBase : public base::NonThreadSafe { 33 protected: 34 ScopedUserPrefUpdateBase(PrefService* service, const char* path); 35 36 // Calls Notify(). 37 virtual ~ScopedUserPrefUpdateBase(); 38 39 // Sets |value_| to |service_|->GetMutableUserPref and returns it. 40 Value* Get(Value::ValueType type); 41 42 private: 43 // If |value_| is not null, triggers a notification of PrefObservers and 44 // resets |value_|. 45 virtual void Notify(); 46 47 // Weak pointer. 48 PrefService* service_; 49 // Path of the preference being updated. 50 std::string path_; 51 // Cache of value from user pref store (set between Get() and Notify() calls). 52 Value* value_; 53 54 DISALLOW_COPY_AND_ASSIGN(ScopedUserPrefUpdateBase); 55}; 56 57} // namespace subtle 58 59// Class to support modifications to DictionaryValues and ListValues while 60// guaranteeing that PrefObservers are notified of changed values. 61// 62// This class may only be used on the UI thread as it requires access to the 63// PrefService. 64template <typename T, Value::ValueType type_enum_value> 65class ScopedUserPrefUpdate : public subtle::ScopedUserPrefUpdateBase { 66 public: 67 ScopedUserPrefUpdate(PrefService* service, const char* path) 68 : ScopedUserPrefUpdateBase(service, path) {} 69 70 // Triggers an update notification if Get() was called. 71 virtual ~ScopedUserPrefUpdate() {} 72 73 // Returns a mutable |T| instance that 74 // - is already in the user pref store, or 75 // - is (silently) created and written to the user pref store if none existed 76 // before. 77 // 78 // Calling Get() implies that an update notification is necessary at 79 // destruction time. 80 // 81 // The ownership of the return value remains with the user pref store. 82 virtual T* Get() { 83 return static_cast<T*>( 84 subtle::ScopedUserPrefUpdateBase::Get(type_enum_value)); 85 } 86 87 T& operator*() { 88 return *Get(); 89 } 90 91 T* operator->() { 92 return Get(); 93 } 94 95 private: 96 DISALLOW_COPY_AND_ASSIGN(ScopedUserPrefUpdate); 97}; 98 99typedef ScopedUserPrefUpdate<DictionaryValue, Value::TYPE_DICTIONARY> 100 DictionaryPrefUpdate; 101typedef ScopedUserPrefUpdate<ListValue, Value::TYPE_LIST> ListPrefUpdate; 102 103#endif // CHROME_BROWSER_PREFS_SCOPED_USER_PREF_UPDATE_H_ 104