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