blob: 29859d65b33a11378b16b452a8e06c7177308d02 [file] [log] [blame]
brettw58cd1f12016-01-30 05:56:051// 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
brettw066508682016-02-03 08:22:028#ifndef COMPONENTS_PREFS_SCOPED_USER_PREF_UPDATE_H_
9#define COMPONENTS_PREFS_SCOPED_USER_PREF_UPDATE_H_
brettw58cd1f12016-01-30 05:56:0510
11#include <string>
12
13#include "base/macros.h"
brettw58cd1f12016-01-30 05:56:0514#include "base/threading/non_thread_safe.h"
15#include "base/values.h"
brettwf00b9b42016-02-01 22:11:3816#include "components/prefs/base_prefs_export.h"
17#include "components/prefs/pref_service.h"
brettw58cd1f12016-01-30 05:56:0518
19class PrefService;
20
21namespace base {
22class DictionaryValue;
23class ListValue;
24}
25
26namespace 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.
brettw066508682016-02-03 08:22:0234class COMPONENTS_PREFS_EXPORT ScopedUserPrefUpdateBase
35 : public base::NonThreadSafe {
brettw58cd1f12016-01-30 05:56:0536 protected:
37 ScopedUserPrefUpdateBase(PrefService* service, const std::string& path);
38
39 // Calls Notify().
40 ~ScopedUserPrefUpdateBase();
41
42 // Sets |value_| to |service_|->GetMutableUserPref and returns it.
43 base::Value* GetValueOfType(base::Value::Type type);
44
45 private:
46 // If |value_| is not null, triggers a notification of PrefObservers and
47 // resets |value_|.
48 void Notify();
49
50 // Weak pointer.
51 PrefService* service_;
52 // Path of the preference being updated.
53 std::string path_;
54 // Cache of value from user pref store (set between Get() and Notify() calls).
55 base::Value* value_;
56
57 DISALLOW_COPY_AND_ASSIGN(ScopedUserPrefUpdateBase);
58};
59
60} // namespace subtle
61
62// Class to support modifications to DictionaryValues and ListValues while
63// guaranteeing that PrefObservers are notified of changed values.
64//
65// This class may only be used on the UI thread as it requires access to the
66// PrefService.
67template <typename T, base::Value::Type type_enum_value>
68class ScopedUserPrefUpdate : public subtle::ScopedUserPrefUpdateBase {
69 public:
70 ScopedUserPrefUpdate(PrefService* service, const std::string& path)
71 : ScopedUserPrefUpdateBase(service, path) {}
72
73 // Triggers an update notification if Get() was called.
74 virtual ~ScopedUserPrefUpdate() {}
75
76 // Returns a mutable |T| instance that
77 // - is already in the user pref store, or
78 // - is (silently) created and written to the user pref store if none existed
79 // before.
80 //
81 // Calling Get() implies that an update notification is necessary at
82 // destruction time.
83 //
84 // The ownership of the return value remains with the user pref store.
85 // Virtual so it can be overriden in subclasses that transform the value
86 // before returning it (for example to return a subelement of a dictionary).
87 virtual T* Get() {
88 return static_cast<T*>(GetValueOfType(type_enum_value));
89 }
90
91 T& operator*() {
92 return *Get();
93 }
94
95 T* operator->() {
96 return Get();
97 }
98
99 private:
100 DISALLOW_COPY_AND_ASSIGN(ScopedUserPrefUpdate);
101};
102
103typedef ScopedUserPrefUpdate<base::DictionaryValue,
jdoerriedc72ee942016-12-07 15:43:28104 base::Value::Type::DICTIONARY>
brettw58cd1f12016-01-30 05:56:05105 DictionaryPrefUpdate;
jdoerriedc72ee942016-12-07 15:43:28106typedef ScopedUserPrefUpdate<base::ListValue, base::Value::Type::LIST>
brettw58cd1f12016-01-30 05:56:05107 ListPrefUpdate;
108
brettw066508682016-02-03 08:22:02109#endif // COMPONENTS_PREFS_SCOPED_USER_PREF_UPDATE_H_