|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #ifndef mozilla_Preferences_h |
|
7 #define mozilla_Preferences_h |
|
8 |
|
9 #ifndef MOZILLA_INTERNAL_API |
|
10 #error "This header is only usable from within libxul (MOZILLA_INTERNAL_API)." |
|
11 #endif |
|
12 |
|
13 #include "nsIPrefService.h" |
|
14 #include "nsIPrefBranch.h" |
|
15 #include "nsIPrefBranchInternal.h" |
|
16 #include "nsIObserver.h" |
|
17 #include "nsCOMPtr.h" |
|
18 #include "nsTArray.h" |
|
19 #include "nsWeakReference.h" |
|
20 #include "mozilla/MemoryReporting.h" |
|
21 |
|
22 class nsIFile; |
|
23 class nsCString; |
|
24 class nsString; |
|
25 class nsAdoptingString; |
|
26 class nsAdoptingCString; |
|
27 |
|
28 #ifndef have_PrefChangedFunc_typedef |
|
29 typedef void (*PrefChangedFunc)(const char *, void *); |
|
30 #define have_PrefChangedFunc_typedef |
|
31 #endif |
|
32 |
|
33 namespace mozilla { |
|
34 |
|
35 namespace dom { |
|
36 class PrefSetting; |
|
37 } |
|
38 |
|
39 class Preferences : public nsIPrefService, |
|
40 public nsIObserver, |
|
41 public nsIPrefBranchInternal, |
|
42 public nsSupportsWeakReference |
|
43 { |
|
44 public: |
|
45 typedef mozilla::dom::PrefSetting PrefSetting; |
|
46 |
|
47 NS_DECL_THREADSAFE_ISUPPORTS |
|
48 NS_DECL_NSIPREFSERVICE |
|
49 NS_FORWARD_NSIPREFBRANCH(sRootBranch->) |
|
50 NS_DECL_NSIOBSERVER |
|
51 |
|
52 Preferences(); |
|
53 virtual ~Preferences(); |
|
54 |
|
55 nsresult Init(); |
|
56 |
|
57 /** |
|
58 * Reset loaded user prefs then read them |
|
59 */ |
|
60 static nsresult ResetAndReadUserPrefs(); |
|
61 |
|
62 /** |
|
63 * Returns the singleton instance which is addreffed. |
|
64 */ |
|
65 static Preferences* GetInstanceForService(); |
|
66 |
|
67 /** |
|
68 * Finallizes global members. |
|
69 */ |
|
70 static void Shutdown(); |
|
71 |
|
72 /** |
|
73 * Returns shared pref service instance |
|
74 * NOTE: not addreffed. |
|
75 */ |
|
76 static nsIPrefService* GetService() |
|
77 { |
|
78 NS_ENSURE_TRUE(InitStaticMembers(), nullptr); |
|
79 return sPreferences; |
|
80 } |
|
81 |
|
82 /** |
|
83 * Returns shared pref branch instance. |
|
84 * NOTE: not addreffed. |
|
85 */ |
|
86 static nsIPrefBranch* GetRootBranch() |
|
87 { |
|
88 NS_ENSURE_TRUE(InitStaticMembers(), nullptr); |
|
89 return sRootBranch; |
|
90 } |
|
91 |
|
92 /** |
|
93 * Returns shared default pref branch instance. |
|
94 * NOTE: not addreffed. |
|
95 */ |
|
96 static nsIPrefBranch* GetDefaultRootBranch() |
|
97 { |
|
98 NS_ENSURE_TRUE(InitStaticMembers(), nullptr); |
|
99 return sDefaultRootBranch; |
|
100 } |
|
101 |
|
102 /** |
|
103 * Gets int or bool type pref value with default value if failed to get |
|
104 * the pref. |
|
105 */ |
|
106 static bool GetBool(const char* aPref, bool aDefault = false) |
|
107 { |
|
108 bool result = aDefault; |
|
109 GetBool(aPref, &result); |
|
110 return result; |
|
111 } |
|
112 |
|
113 static int32_t GetInt(const char* aPref, int32_t aDefault = 0) |
|
114 { |
|
115 int32_t result = aDefault; |
|
116 GetInt(aPref, &result); |
|
117 return result; |
|
118 } |
|
119 |
|
120 static uint32_t GetUint(const char* aPref, uint32_t aDefault = 0) |
|
121 { |
|
122 uint32_t result = aDefault; |
|
123 GetUint(aPref, &result); |
|
124 return result; |
|
125 } |
|
126 |
|
127 static float GetFloat(const char* aPref, float aDefault = 0) |
|
128 { |
|
129 float result = aDefault; |
|
130 GetFloat(aPref, &result); |
|
131 return result; |
|
132 } |
|
133 |
|
134 /** |
|
135 * Gets char type pref value directly. If failed, the get() of result |
|
136 * returns nullptr. Even if succeeded but the result was empty string, the |
|
137 * get() does NOT return nullptr. So, you can check whether the method |
|
138 * succeeded or not by: |
|
139 * |
|
140 * nsAdoptingString value = Prefereces::GetString("foo.bar"); |
|
141 * if (!value) { |
|
142 * // failed |
|
143 * } |
|
144 * |
|
145 * Be aware. If you wrote as: |
|
146 * |
|
147 * nsAutoString value = Preferences::GetString("foo.bar"); |
|
148 * if (!value.get()) { |
|
149 * // the condition is always FALSE!! |
|
150 * } |
|
151 * |
|
152 * The value.get() doesn't return nullptr. You must use nsAdoptingString |
|
153 * when you need to check whether it was failure or not. |
|
154 */ |
|
155 static nsAdoptingCString GetCString(const char* aPref); |
|
156 static nsAdoptingString GetString(const char* aPref); |
|
157 static nsAdoptingCString GetLocalizedCString(const char* aPref); |
|
158 static nsAdoptingString GetLocalizedString(const char* aPref); |
|
159 |
|
160 /** |
|
161 * Gets int, float, or bool type pref value with raw return value of |
|
162 * nsIPrefBranch. |
|
163 * |
|
164 * @param aPref A pref name. |
|
165 * @param aResult Must not be nullptr. The value is never modified |
|
166 * when these methods fail. |
|
167 */ |
|
168 static nsresult GetBool(const char* aPref, bool* aResult); |
|
169 static nsresult GetInt(const char* aPref, int32_t* aResult); |
|
170 static nsresult GetFloat(const char* aPref, float* aResult); |
|
171 static nsresult GetUint(const char* aPref, uint32_t* aResult) |
|
172 { |
|
173 int32_t result; |
|
174 nsresult rv = GetInt(aPref, &result); |
|
175 if (NS_SUCCEEDED(rv)) { |
|
176 *aResult = static_cast<uint32_t>(result); |
|
177 } |
|
178 return rv; |
|
179 } |
|
180 |
|
181 /** |
|
182 * Gets string type pref value with raw return value of nsIPrefBranch. |
|
183 * |
|
184 * @param aPref A pref name. |
|
185 * @param aResult Must not be nullptr. The value is never modified |
|
186 * when these methods fail. |
|
187 */ |
|
188 static nsresult GetCString(const char* aPref, nsACString* aResult); |
|
189 static nsresult GetString(const char* aPref, nsAString* aResult); |
|
190 static nsresult GetLocalizedCString(const char* aPref, nsACString* aResult); |
|
191 static nsresult GetLocalizedString(const char* aPref, nsAString* aResult); |
|
192 |
|
193 static nsresult GetComplex(const char* aPref, const nsIID &aType, |
|
194 void** aResult); |
|
195 |
|
196 /** |
|
197 * Sets various type pref values. |
|
198 */ |
|
199 static nsresult SetBool(const char* aPref, bool aValue); |
|
200 static nsresult SetInt(const char* aPref, int32_t aValue); |
|
201 static nsresult SetUint(const char* aPref, uint32_t aValue) |
|
202 { |
|
203 return SetInt(aPref, static_cast<int32_t>(aValue)); |
|
204 } |
|
205 static nsresult SetCString(const char* aPref, const char* aValue); |
|
206 static nsresult SetCString(const char* aPref, const nsACString &aValue); |
|
207 static nsresult SetString(const char* aPref, const char16_t* aValue); |
|
208 static nsresult SetString(const char* aPref, const nsAString &aValue); |
|
209 |
|
210 static nsresult SetComplex(const char* aPref, const nsIID &aType, |
|
211 nsISupports* aValue); |
|
212 |
|
213 /** |
|
214 * Clears user set pref. |
|
215 */ |
|
216 static nsresult ClearUser(const char* aPref); |
|
217 |
|
218 /** |
|
219 * Whether the pref has a user value or not. |
|
220 */ |
|
221 static bool HasUserValue(const char* aPref); |
|
222 |
|
223 /** |
|
224 * Gets the type of the pref. |
|
225 */ |
|
226 static int32_t GetType(const char* aPref); |
|
227 |
|
228 /** |
|
229 * Adds/Removes the observer for the root pref branch. |
|
230 * The observer is referenced strongly if AddStrongObserver is used. On the |
|
231 * other hand, it is referenced weakly, if AddWeakObserver is used. |
|
232 * See nsIPrefBranch.idl for details. |
|
233 */ |
|
234 static nsresult AddStrongObserver(nsIObserver* aObserver, const char* aPref); |
|
235 static nsresult AddWeakObserver(nsIObserver* aObserver, const char* aPref); |
|
236 static nsresult RemoveObserver(nsIObserver* aObserver, const char* aPref); |
|
237 |
|
238 /** |
|
239 * Adds/Removes two or more observers for the root pref branch. |
|
240 * Pass to aPrefs an array of const char* whose last item is nullptr. |
|
241 */ |
|
242 static nsresult AddStrongObservers(nsIObserver* aObserver, |
|
243 const char** aPrefs); |
|
244 static nsresult AddWeakObservers(nsIObserver* aObserver, |
|
245 const char** aPrefs); |
|
246 static nsresult RemoveObservers(nsIObserver* aObserver, |
|
247 const char** aPrefs); |
|
248 |
|
249 /** |
|
250 * Registers/Unregisters the callback function for the aPref. |
|
251 */ |
|
252 static nsresult RegisterCallback(PrefChangedFunc aCallback, |
|
253 const char* aPref, |
|
254 void* aClosure = nullptr); |
|
255 static nsresult UnregisterCallback(PrefChangedFunc aCallback, |
|
256 const char* aPref, |
|
257 void* aClosure = nullptr); |
|
258 // Like RegisterCallback, but also calls the callback immediately for |
|
259 // initialization. |
|
260 static nsresult RegisterCallbackAndCall(PrefChangedFunc aCallback, |
|
261 const char* aPref, |
|
262 void* aClosure = nullptr); |
|
263 |
|
264 /** |
|
265 * Adds the aVariable to cache table. aVariable must be a pointer for a |
|
266 * static variable. The value will be modified when the pref value is |
|
267 * changed but note that even if you modified it, the value isn't assigned to |
|
268 * the pref. |
|
269 */ |
|
270 static nsresult AddBoolVarCache(bool* aVariable, |
|
271 const char* aPref, |
|
272 bool aDefault = false); |
|
273 static nsresult AddIntVarCache(int32_t* aVariable, |
|
274 const char* aPref, |
|
275 int32_t aDefault = 0); |
|
276 static nsresult AddUintVarCache(uint32_t* aVariable, |
|
277 const char* aPref, |
|
278 uint32_t aDefault = 0); |
|
279 static nsresult AddFloatVarCache(float* aVariable, |
|
280 const char* aPref, |
|
281 float aDefault = 0.0f); |
|
282 |
|
283 /** |
|
284 * Gets the default bool, int or uint value of the pref. |
|
285 * The result is raw result of nsIPrefBranch::Get*Pref(). |
|
286 * If the pref could have any value, you needed to use these methods. |
|
287 * If not so, you could use below methods. |
|
288 */ |
|
289 static nsresult GetDefaultBool(const char* aPref, bool* aResult); |
|
290 static nsresult GetDefaultInt(const char* aPref, int32_t* aResult); |
|
291 static nsresult GetDefaultUint(const char* aPref, uint32_t* aResult) |
|
292 { |
|
293 return GetDefaultInt(aPref, reinterpret_cast<int32_t*>(aResult)); |
|
294 } |
|
295 |
|
296 /** |
|
297 * Gets the default bool, int or uint value of the pref directly. |
|
298 * You can set an invalid value of the pref to aFailedResult. If these |
|
299 * methods failed to get the default value, they would return the |
|
300 * aFailedResult value. |
|
301 */ |
|
302 static bool GetDefaultBool(const char* aPref, bool aFailedResult) |
|
303 { |
|
304 bool result; |
|
305 return NS_SUCCEEDED(GetDefaultBool(aPref, &result)) ? result : |
|
306 aFailedResult; |
|
307 } |
|
308 static int32_t GetDefaultInt(const char* aPref, int32_t aFailedResult) |
|
309 { |
|
310 int32_t result; |
|
311 return NS_SUCCEEDED(GetDefaultInt(aPref, &result)) ? result : aFailedResult; |
|
312 } |
|
313 static uint32_t GetDefaultUint(const char* aPref, uint32_t aFailedResult) |
|
314 { |
|
315 return static_cast<uint32_t>( |
|
316 GetDefaultInt(aPref, static_cast<int32_t>(aFailedResult))); |
|
317 } |
|
318 |
|
319 /** |
|
320 * Gets the default value of the char type pref. |
|
321 * If the get() of the result returned nullptr, that meant the value didn't |
|
322 * have default value. |
|
323 * |
|
324 * See the comment at definition at GetString() and GetCString() for more |
|
325 * details of the result. |
|
326 */ |
|
327 static nsAdoptingString GetDefaultString(const char* aPref); |
|
328 static nsAdoptingCString GetDefaultCString(const char* aPref); |
|
329 static nsAdoptingString GetDefaultLocalizedString(const char* aPref); |
|
330 static nsAdoptingCString GetDefaultLocalizedCString(const char* aPref); |
|
331 |
|
332 static nsresult GetDefaultCString(const char* aPref, nsACString* aResult); |
|
333 static nsresult GetDefaultString(const char* aPref, nsAString* aResult); |
|
334 static nsresult GetDefaultLocalizedCString(const char* aPref, |
|
335 nsACString* aResult); |
|
336 static nsresult GetDefaultLocalizedString(const char* aPref, |
|
337 nsAString* aResult); |
|
338 |
|
339 static nsresult GetDefaultComplex(const char* aPref, const nsIID &aType, |
|
340 void** aResult); |
|
341 |
|
342 /** |
|
343 * Gets the type of the pref. |
|
344 */ |
|
345 static int32_t GetDefaultType(const char* aPref); |
|
346 |
|
347 // Used to synchronise preferences between chrome and content processes. |
|
348 static void GetPreferences(InfallibleTArray<PrefSetting>* aPrefs); |
|
349 static void GetPreference(PrefSetting* aPref); |
|
350 static void SetPreference(const PrefSetting& aPref); |
|
351 |
|
352 static int64_t SizeOfIncludingThisAndOtherStuff(mozilla::MallocSizeOf aMallocSizeOf); |
|
353 static nsresult SetFloat(const char* aPref, float aValue); |
|
354 |
|
355 protected: |
|
356 nsresult NotifyServiceObservers(const char *aSubject); |
|
357 /** |
|
358 * Reads the default pref file or, if that failed, try to save a new one. |
|
359 * |
|
360 * @return NS_OK if either action succeeded, |
|
361 * or the error code related to the read attempt. |
|
362 */ |
|
363 nsresult UseDefaultPrefFile(); |
|
364 nsresult UseUserPrefFile(); |
|
365 nsresult ReadAndOwnUserPrefFile(nsIFile *aFile); |
|
366 nsresult ReadAndOwnSharedUserPrefFile(nsIFile *aFile); |
|
367 nsresult SavePrefFileInternal(nsIFile* aFile); |
|
368 nsresult WritePrefFile(nsIFile* aFile); |
|
369 nsresult MakeBackupPrefFile(nsIFile *aFile); |
|
370 |
|
371 private: |
|
372 nsCOMPtr<nsIFile> mCurrentFile; |
|
373 |
|
374 static Preferences* sPreferences; |
|
375 static nsIPrefBranch* sRootBranch; |
|
376 static nsIPrefBranch* sDefaultRootBranch; |
|
377 static bool sShutdown; |
|
378 |
|
379 /** |
|
380 * Init static members. TRUE if it succeeded. Otherwise, FALSE. |
|
381 */ |
|
382 static bool InitStaticMembers(); |
|
383 }; |
|
384 |
|
385 } // namespace mozilla |
|
386 |
|
387 #endif // mozilla_Preferences_h |